Bug Summary

File:build-llvm/tools/clang/include/clang/AST/Attrs.inc
Warning:line 7386, column 5
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 CGOpenMPRuntime.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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-9/lib/clang/9.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-9~svn362543/build-llvm/tools/clang/lib/CodeGen -I /build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen -I /build/llvm-toolchain-snapshot-9~svn362543/tools/clang/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/include -I /build/llvm-toolchain-snapshot-9~svn362543/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/include/clang/9.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-9/lib/clang/9.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++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/lib/CodeGen -fdebug-prefix-map=/build/llvm-toolchain-snapshot-9~svn362543=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2019-06-05-060531-1271-1 -x c++ /build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp -faddrsig

/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp

1//===----- CGOpenMPRuntime.cpp - Interface to OpenMP Runtimes -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This provides a class for OpenMP runtime code generation.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CGCXXABI.h"
14#include "CGCleanup.h"
15#include "CGOpenMPRuntime.h"
16#include "CGRecordLayout.h"
17#include "CodeGenFunction.h"
18#include "clang/CodeGen/ConstantInitBuilder.h"
19#include "clang/AST/Decl.h"
20#include "clang/AST/StmtOpenMP.h"
21#include "clang/Basic/BitmaskEnum.h"
22#include "llvm/ADT/ArrayRef.h"
23#include "llvm/Bitcode/BitcodeReader.h"
24#include "llvm/IR/DerivedTypes.h"
25#include "llvm/IR/GlobalValue.h"
26#include "llvm/IR/Value.h"
27#include "llvm/Support/Format.h"
28#include "llvm/Support/raw_ostream.h"
29#include <cassert>
30
31using namespace clang;
32using namespace CodeGen;
33
34namespace {
35/// Base class for handling code generation inside OpenMP regions.
36class CGOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo {
37public:
38 /// Kinds of OpenMP regions used in codegen.
39 enum CGOpenMPRegionKind {
40 /// Region with outlined function for standalone 'parallel'
41 /// directive.
42 ParallelOutlinedRegion,
43 /// Region with outlined function for standalone 'task' directive.
44 TaskOutlinedRegion,
45 /// Region for constructs that do not require function outlining,
46 /// like 'for', 'sections', 'atomic' etc. directives.
47 InlinedRegion,
48 /// Region with outlined function for standalone 'target' directive.
49 TargetRegion,
50 };
51
52 CGOpenMPRegionInfo(const CapturedStmt &CS,
53 const CGOpenMPRegionKind RegionKind,
54 const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
55 bool HasCancel)
56 : CGCapturedStmtInfo(CS, CR_OpenMP), RegionKind(RegionKind),
57 CodeGen(CodeGen), Kind(Kind), HasCancel(HasCancel) {}
58
59 CGOpenMPRegionInfo(const CGOpenMPRegionKind RegionKind,
60 const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
61 bool HasCancel)
62 : CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
63 Kind(Kind), HasCancel(HasCancel) {}
64
65 /// Get a variable or parameter for storing global thread id
66 /// inside OpenMP construct.
67 virtual const VarDecl *getThreadIDVariable() const = 0;
68
69 /// Emit the captured statement body.
70 void EmitBody(CodeGenFunction &CGF, const Stmt *S) override;
71
72 /// Get an LValue for the current ThreadID variable.
73 /// \return LValue for thread id variable. This LValue always has type int32*.
74 virtual LValue getThreadIDVariableLValue(CodeGenFunction &CGF);
75
76 virtual void emitUntiedSwitch(CodeGenFunction & /*CGF*/) {}
77
78 CGOpenMPRegionKind getRegionKind() const { return RegionKind; }
79
80 OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
81
82 bool hasCancel() const { return HasCancel; }
83
84 static bool classof(const CGCapturedStmtInfo *Info) {
85 return Info->getKind() == CR_OpenMP;
86 }
87
88 ~CGOpenMPRegionInfo() override = default;
89
90protected:
91 CGOpenMPRegionKind RegionKind;
92 RegionCodeGenTy CodeGen;
93 OpenMPDirectiveKind Kind;
94 bool HasCancel;
95};
96
97/// API for captured statement code generation in OpenMP constructs.
98class CGOpenMPOutlinedRegionInfo final : public CGOpenMPRegionInfo {
99public:
100 CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar,
101 const RegionCodeGenTy &CodeGen,
102 OpenMPDirectiveKind Kind, bool HasCancel,
103 StringRef HelperName)
104 : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
105 HasCancel),
106 ThreadIDVar(ThreadIDVar), HelperName(HelperName) {
107 assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.")((ThreadIDVar != nullptr && "No ThreadID in OpenMP region."
) ? static_cast<void> (0) : __assert_fail ("ThreadIDVar != nullptr && \"No ThreadID in OpenMP region.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 107, __PRETTY_FUNCTION__))
;
108 }
109
110 /// Get a variable or parameter for storing global thread id
111 /// inside OpenMP construct.
112 const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
113
114 /// Get the name of the capture helper.
115 StringRef getHelperName() const override { return HelperName; }
116
117 static bool classof(const CGCapturedStmtInfo *Info) {
118 return CGOpenMPRegionInfo::classof(Info) &&
119 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
120 ParallelOutlinedRegion;
121 }
122
123private:
124 /// A variable or parameter storing global thread id for OpenMP
125 /// constructs.
126 const VarDecl *ThreadIDVar;
127 StringRef HelperName;
128};
129
130/// API for captured statement code generation in OpenMP constructs.
131class CGOpenMPTaskOutlinedRegionInfo final : public CGOpenMPRegionInfo {
132public:
133 class UntiedTaskActionTy final : public PrePostActionTy {
134 bool Untied;
135 const VarDecl *PartIDVar;
136 const RegionCodeGenTy UntiedCodeGen;
137 llvm::SwitchInst *UntiedSwitch = nullptr;
138
139 public:
140 UntiedTaskActionTy(bool Tied, const VarDecl *PartIDVar,
141 const RegionCodeGenTy &UntiedCodeGen)
142 : Untied(!Tied), PartIDVar(PartIDVar), UntiedCodeGen(UntiedCodeGen) {}
143 void Enter(CodeGenFunction &CGF) override {
144 if (Untied) {
145 // Emit task switching point.
146 LValue PartIdLVal = CGF.EmitLoadOfPointerLValue(
147 CGF.GetAddrOfLocalVar(PartIDVar),
148 PartIDVar->getType()->castAs<PointerType>());
149 llvm::Value *Res =
150 CGF.EmitLoadOfScalar(PartIdLVal, PartIDVar->getLocation());
151 llvm::BasicBlock *DoneBB = CGF.createBasicBlock(".untied.done.");
152 UntiedSwitch = CGF.Builder.CreateSwitch(Res, DoneBB);
153 CGF.EmitBlock(DoneBB);
154 CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
155 CGF.EmitBlock(CGF.createBasicBlock(".untied.jmp."));
156 UntiedSwitch->addCase(CGF.Builder.getInt32(0),
157 CGF.Builder.GetInsertBlock());
158 emitUntiedSwitch(CGF);
159 }
160 }
161 void emitUntiedSwitch(CodeGenFunction &CGF) const {
162 if (Untied) {
163 LValue PartIdLVal = CGF.EmitLoadOfPointerLValue(
164 CGF.GetAddrOfLocalVar(PartIDVar),
165 PartIDVar->getType()->castAs<PointerType>());
166 CGF.EmitStoreOfScalar(CGF.Builder.getInt32(UntiedSwitch->getNumCases()),
167 PartIdLVal);
168 UntiedCodeGen(CGF);
169 CodeGenFunction::JumpDest CurPoint =
170 CGF.getJumpDestInCurrentScope(".untied.next.");
171 CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
172 CGF.EmitBlock(CGF.createBasicBlock(".untied.jmp."));
173 UntiedSwitch->addCase(CGF.Builder.getInt32(UntiedSwitch->getNumCases()),
174 CGF.Builder.GetInsertBlock());
175 CGF.EmitBranchThroughCleanup(CurPoint);
176 CGF.EmitBlock(CurPoint.getBlock());
177 }
178 }
179 unsigned getNumberOfParts() const { return UntiedSwitch->getNumCases(); }
180 };
181 CGOpenMPTaskOutlinedRegionInfo(const CapturedStmt &CS,
182 const VarDecl *ThreadIDVar,
183 const RegionCodeGenTy &CodeGen,
184 OpenMPDirectiveKind Kind, bool HasCancel,
185 const UntiedTaskActionTy &Action)
186 : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind, HasCancel),
187 ThreadIDVar(ThreadIDVar), Action(Action) {
188 assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.")((ThreadIDVar != nullptr && "No ThreadID in OpenMP region."
) ? static_cast<void> (0) : __assert_fail ("ThreadIDVar != nullptr && \"No ThreadID in OpenMP region.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 188, __PRETTY_FUNCTION__))
;
189 }
190
191 /// Get a variable or parameter for storing global thread id
192 /// inside OpenMP construct.
193 const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
194
195 /// Get an LValue for the current ThreadID variable.
196 LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override;
197
198 /// Get the name of the capture helper.
199 StringRef getHelperName() const override { return ".omp_outlined."; }
200
201 void emitUntiedSwitch(CodeGenFunction &CGF) override {
202 Action.emitUntiedSwitch(CGF);
203 }
204
205 static bool classof(const CGCapturedStmtInfo *Info) {
206 return CGOpenMPRegionInfo::classof(Info) &&
207 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
208 TaskOutlinedRegion;
209 }
210
211private:
212 /// A variable or parameter storing global thread id for OpenMP
213 /// constructs.
214 const VarDecl *ThreadIDVar;
215 /// Action for emitting code for untied tasks.
216 const UntiedTaskActionTy &Action;
217};
218
219/// API for inlined captured statement code generation in OpenMP
220/// constructs.
221class CGOpenMPInlinedRegionInfo : public CGOpenMPRegionInfo {
222public:
223 CGOpenMPInlinedRegionInfo(CodeGenFunction::CGCapturedStmtInfo *OldCSI,
224 const RegionCodeGenTy &CodeGen,
225 OpenMPDirectiveKind Kind, bool HasCancel)
226 : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind, HasCancel),
227 OldCSI(OldCSI),
228 OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
229
230 // Retrieve the value of the context parameter.
231 llvm::Value *getContextValue() const override {
232 if (OuterRegionInfo)
233 return OuterRegionInfo->getContextValue();
234 llvm_unreachable("No context value for inlined OpenMP region")::llvm::llvm_unreachable_internal("No context value for inlined OpenMP region"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 234)
;
235 }
236
237 void setContextValue(llvm::Value *V) override {
238 if (OuterRegionInfo) {
239 OuterRegionInfo->setContextValue(V);
240 return;
241 }
242 llvm_unreachable("No context value for inlined OpenMP region")::llvm::llvm_unreachable_internal("No context value for inlined OpenMP region"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 242)
;
243 }
244
245 /// Lookup the captured field decl for a variable.
246 const FieldDecl *lookup(const VarDecl *VD) const override {
247 if (OuterRegionInfo)
248 return OuterRegionInfo->lookup(VD);
249 // If there is no outer outlined region,no need to lookup in a list of
250 // captured variables, we can use the original one.
251 return nullptr;
252 }
253
254 FieldDecl *getThisFieldDecl() const override {
255 if (OuterRegionInfo)
256 return OuterRegionInfo->getThisFieldDecl();
257 return nullptr;
258 }
259
260 /// Get a variable or parameter for storing global thread id
261 /// inside OpenMP construct.
262 const VarDecl *getThreadIDVariable() const override {
263 if (OuterRegionInfo)
264 return OuterRegionInfo->getThreadIDVariable();
265 return nullptr;
266 }
267
268 /// Get an LValue for the current ThreadID variable.
269 LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override {
270 if (OuterRegionInfo)
271 return OuterRegionInfo->getThreadIDVariableLValue(CGF);
272 llvm_unreachable("No LValue for inlined OpenMP construct")::llvm::llvm_unreachable_internal("No LValue for inlined OpenMP construct"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 272)
;
273 }
274
275 /// Get the name of the capture helper.
276 StringRef getHelperName() const override {
277 if (auto *OuterRegionInfo = getOldCSI())
278 return OuterRegionInfo->getHelperName();
279 llvm_unreachable("No helper name for inlined OpenMP construct")::llvm::llvm_unreachable_internal("No helper name for inlined OpenMP construct"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 279)
;
280 }
281
282 void emitUntiedSwitch(CodeGenFunction &CGF) override {
283 if (OuterRegionInfo)
284 OuterRegionInfo->emitUntiedSwitch(CGF);
285 }
286
287 CodeGenFunction::CGCapturedStmtInfo *getOldCSI() const { return OldCSI; }
288
289 static bool classof(const CGCapturedStmtInfo *Info) {
290 return CGOpenMPRegionInfo::classof(Info) &&
291 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == InlinedRegion;
292 }
293
294 ~CGOpenMPInlinedRegionInfo() override = default;
295
296private:
297 /// CodeGen info about outer OpenMP region.
298 CodeGenFunction::CGCapturedStmtInfo *OldCSI;
299 CGOpenMPRegionInfo *OuterRegionInfo;
300};
301
302/// API for captured statement code generation in OpenMP target
303/// constructs. For this captures, implicit parameters are used instead of the
304/// captured fields. The name of the target region has to be unique in a given
305/// application so it is provided by the client, because only the client has
306/// the information to generate that.
307class CGOpenMPTargetRegionInfo final : public CGOpenMPRegionInfo {
308public:
309 CGOpenMPTargetRegionInfo(const CapturedStmt &CS,
310 const RegionCodeGenTy &CodeGen, StringRef HelperName)
311 : CGOpenMPRegionInfo(CS, TargetRegion, CodeGen, OMPD_target,
312 /*HasCancel=*/false),
313 HelperName(HelperName) {}
314
315 /// This is unused for target regions because each starts executing
316 /// with a single thread.
317 const VarDecl *getThreadIDVariable() const override { return nullptr; }
318
319 /// Get the name of the capture helper.
320 StringRef getHelperName() const override { return HelperName; }
321
322 static bool classof(const CGCapturedStmtInfo *Info) {
323 return CGOpenMPRegionInfo::classof(Info) &&
324 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == TargetRegion;
325 }
326
327private:
328 StringRef HelperName;
329};
330
331static void EmptyCodeGen(CodeGenFunction &, PrePostActionTy &) {
332 llvm_unreachable("No codegen for expressions")::llvm::llvm_unreachable_internal("No codegen for expressions"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 332)
;
333}
334/// API for generation of expressions captured in a innermost OpenMP
335/// region.
336class CGOpenMPInnerExprInfo final : public CGOpenMPInlinedRegionInfo {
337public:
338 CGOpenMPInnerExprInfo(CodeGenFunction &CGF, const CapturedStmt &CS)
339 : CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, EmptyCodeGen,
340 OMPD_unknown,
341 /*HasCancel=*/false),
342 PrivScope(CGF) {
343 // Make sure the globals captured in the provided statement are local by
344 // using the privatization logic. We assume the same variable is not
345 // captured more than once.
346 for (const auto &C : CS.captures()) {
347 if (!C.capturesVariable() && !C.capturesVariableByCopy())
348 continue;
349
350 const VarDecl *VD = C.getCapturedVar();
351 if (VD->isLocalVarDeclOrParm())
352 continue;
353
354 DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(VD),
355 /*RefersToEnclosingVariableOrCapture=*/false,
356 VD->getType().getNonReferenceType(), VK_LValue,
357 C.getLocation());
358 PrivScope.addPrivate(
359 VD, [&CGF, &DRE]() { return CGF.EmitLValue(&DRE).getAddress(); });
360 }
361 (void)PrivScope.Privatize();
362 }
363
364 /// Lookup the captured field decl for a variable.
365 const FieldDecl *lookup(const VarDecl *VD) const override {
366 if (const FieldDecl *FD = CGOpenMPInlinedRegionInfo::lookup(VD))
367 return FD;
368 return nullptr;
369 }
370
371 /// Emit the captured statement body.
372 void EmitBody(CodeGenFunction &CGF, const Stmt *S) override {
373 llvm_unreachable("No body for expressions")::llvm::llvm_unreachable_internal("No body for expressions", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 373)
;
374 }
375
376 /// Get a variable or parameter for storing global thread id
377 /// inside OpenMP construct.
378 const VarDecl *getThreadIDVariable() const override {
379 llvm_unreachable("No thread id for expressions")::llvm::llvm_unreachable_internal("No thread id for expressions"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 379)
;
380 }
381
382 /// Get the name of the capture helper.
383 StringRef getHelperName() const override {
384 llvm_unreachable("No helper name for expressions")::llvm::llvm_unreachable_internal("No helper name for expressions"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 384)
;
385 }
386
387 static bool classof(const CGCapturedStmtInfo *Info) { return false; }
388
389private:
390 /// Private scope to capture global variables.
391 CodeGenFunction::OMPPrivateScope PrivScope;
392};
393
394/// RAII for emitting code of OpenMP constructs.
395class InlinedOpenMPRegionRAII {
396 CodeGenFunction &CGF;
397 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
398 FieldDecl *LambdaThisCaptureField = nullptr;
399 const CodeGen::CGBlockInfo *BlockInfo = nullptr;
400
401public:
402 /// Constructs region for combined constructs.
403 /// \param CodeGen Code generation sequence for combined directives. Includes
404 /// a list of functions used for code generation of implicitly inlined
405 /// regions.
406 InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen,
407 OpenMPDirectiveKind Kind, bool HasCancel)
408 : CGF(CGF) {
409 // Start emission for the construct.
410 CGF.CapturedStmtInfo = new CGOpenMPInlinedRegionInfo(
411 CGF.CapturedStmtInfo, CodeGen, Kind, HasCancel);
412 std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
413 LambdaThisCaptureField = CGF.LambdaThisCaptureField;
414 CGF.LambdaThisCaptureField = nullptr;
415 BlockInfo = CGF.BlockInfo;
416 CGF.BlockInfo = nullptr;
417 }
418
419 ~InlinedOpenMPRegionRAII() {
420 // Restore original CapturedStmtInfo only if we're done with code emission.
421 auto *OldCSI =
422 cast<CGOpenMPInlinedRegionInfo>(CGF.CapturedStmtInfo)->getOldCSI();
423 delete CGF.CapturedStmtInfo;
424 CGF.CapturedStmtInfo = OldCSI;
425 std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
426 CGF.LambdaThisCaptureField = LambdaThisCaptureField;
427 CGF.BlockInfo = BlockInfo;
428 }
429};
430
431/// Values for bit flags used in the ident_t to describe the fields.
432/// All enumeric elements are named and described in accordance with the code
433/// from https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h
434enum OpenMPLocationFlags : unsigned {
435 /// Use trampoline for internal microtask.
436 OMP_IDENT_IMD = 0x01,
437 /// Use c-style ident structure.
438 OMP_IDENT_KMPC = 0x02,
439 /// Atomic reduction option for kmpc_reduce.
440 OMP_ATOMIC_REDUCE = 0x10,
441 /// Explicit 'barrier' directive.
442 OMP_IDENT_BARRIER_EXPL = 0x20,
443 /// Implicit barrier in code.
444 OMP_IDENT_BARRIER_IMPL = 0x40,
445 /// Implicit barrier in 'for' directive.
446 OMP_IDENT_BARRIER_IMPL_FOR = 0x40,
447 /// Implicit barrier in 'sections' directive.
448 OMP_IDENT_BARRIER_IMPL_SECTIONS = 0xC0,
449 /// Implicit barrier in 'single' directive.
450 OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140,
451 /// Call of __kmp_for_static_init for static loop.
452 OMP_IDENT_WORK_LOOP = 0x200,
453 /// Call of __kmp_for_static_init for sections.
454 OMP_IDENT_WORK_SECTIONS = 0x400,
455 /// Call of __kmp_for_static_init for distribute.
456 OMP_IDENT_WORK_DISTRIBUTE = 0x800,
457 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_IDENT_WORK_DISTRIBUTE)LLVM_BITMASK_LARGEST_ENUMERATOR = OMP_IDENT_WORK_DISTRIBUTE
458};
459
460namespace {
461LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()using ::llvm::BitmaskEnumDetail::operator~; using ::llvm::BitmaskEnumDetail
::operator|; using ::llvm::BitmaskEnumDetail::operator&; using
::llvm::BitmaskEnumDetail::operator^; using ::llvm::BitmaskEnumDetail
::operator|=; using ::llvm::BitmaskEnumDetail::operator&=
; using ::llvm::BitmaskEnumDetail::operator^=
;
462/// Values for bit flags for marking which requires clauses have been used.
463enum OpenMPOffloadingRequiresDirFlags : int64_t {
464 /// flag undefined.
465 OMP_REQ_UNDEFINED = 0x000,
466 /// no requires clause present.
467 OMP_REQ_NONE = 0x001,
468 /// reverse_offload clause.
469 OMP_REQ_REVERSE_OFFLOAD = 0x002,
470 /// unified_address clause.
471 OMP_REQ_UNIFIED_ADDRESS = 0x004,
472 /// unified_shared_memory clause.
473 OMP_REQ_UNIFIED_SHARED_MEMORY = 0x008,
474 /// dynamic_allocators clause.
475 OMP_REQ_DYNAMIC_ALLOCATORS = 0x010,
476 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_REQ_DYNAMIC_ALLOCATORS)LLVM_BITMASK_LARGEST_ENUMERATOR = OMP_REQ_DYNAMIC_ALLOCATORS
477};
478} // anonymous namespace
479
480/// Describes ident structure that describes a source location.
481/// All descriptions are taken from
482/// https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h
483/// Original structure:
484/// typedef struct ident {
485/// kmp_int32 reserved_1; /**< might be used in Fortran;
486/// see above */
487/// kmp_int32 flags; /**< also f.flags; KMP_IDENT_xxx flags;
488/// KMP_IDENT_KMPC identifies this union
489/// member */
490/// kmp_int32 reserved_2; /**< not really used in Fortran any more;
491/// see above */
492///#if USE_ITT_BUILD
493/// /* but currently used for storing
494/// region-specific ITT */
495/// /* contextual information. */
496///#endif /* USE_ITT_BUILD */
497/// kmp_int32 reserved_3; /**< source[4] in Fortran, do not use for
498/// C++ */
499/// char const *psource; /**< String describing the source location.
500/// The string is composed of semi-colon separated
501// fields which describe the source file,
502/// the function and a pair of line numbers that
503/// delimit the construct.
504/// */
505/// } ident_t;
506enum IdentFieldIndex {
507 /// might be used in Fortran
508 IdentField_Reserved_1,
509 /// OMP_IDENT_xxx flags; OMP_IDENT_KMPC identifies this union member.
510 IdentField_Flags,
511 /// Not really used in Fortran any more
512 IdentField_Reserved_2,
513 /// Source[4] in Fortran, do not use for C++
514 IdentField_Reserved_3,
515 /// String describing the source location. The string is composed of
516 /// semi-colon separated fields which describe the source file, the function
517 /// and a pair of line numbers that delimit the construct.
518 IdentField_PSource
519};
520
521/// Schedule types for 'omp for' loops (these enumerators are taken from
522/// the enum sched_type in kmp.h).
523enum OpenMPSchedType {
524 /// Lower bound for default (unordered) versions.
525 OMP_sch_lower = 32,
526 OMP_sch_static_chunked = 33,
527 OMP_sch_static = 34,
528 OMP_sch_dynamic_chunked = 35,
529 OMP_sch_guided_chunked = 36,
530 OMP_sch_runtime = 37,
531 OMP_sch_auto = 38,
532 /// static with chunk adjustment (e.g., simd)
533 OMP_sch_static_balanced_chunked = 45,
534 /// Lower bound for 'ordered' versions.
535 OMP_ord_lower = 64,
536 OMP_ord_static_chunked = 65,
537 OMP_ord_static = 66,
538 OMP_ord_dynamic_chunked = 67,
539 OMP_ord_guided_chunked = 68,
540 OMP_ord_runtime = 69,
541 OMP_ord_auto = 70,
542 OMP_sch_default = OMP_sch_static,
543 /// dist_schedule types
544 OMP_dist_sch_static_chunked = 91,
545 OMP_dist_sch_static = 92,
546 /// Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers.
547 /// Set if the monotonic schedule modifier was present.
548 OMP_sch_modifier_monotonic = (1 << 29),
549 /// Set if the nonmonotonic schedule modifier was present.
550 OMP_sch_modifier_nonmonotonic = (1 << 30),
551};
552
553enum OpenMPRTLFunction {
554 /// Call to void __kmpc_fork_call(ident_t *loc, kmp_int32 argc,
555 /// kmpc_micro microtask, ...);
556 OMPRTL__kmpc_fork_call,
557 /// Call to void *__kmpc_threadprivate_cached(ident_t *loc,
558 /// kmp_int32 global_tid, void *data, size_t size, void ***cache);
559 OMPRTL__kmpc_threadprivate_cached,
560 /// Call to void __kmpc_threadprivate_register( ident_t *,
561 /// void *data, kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
562 OMPRTL__kmpc_threadprivate_register,
563 // Call to __kmpc_int32 kmpc_global_thread_num(ident_t *loc);
564 OMPRTL__kmpc_global_thread_num,
565 // Call to void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
566 // kmp_critical_name *crit);
567 OMPRTL__kmpc_critical,
568 // Call to void __kmpc_critical_with_hint(ident_t *loc, kmp_int32
569 // global_tid, kmp_critical_name *crit, uintptr_t hint);
570 OMPRTL__kmpc_critical_with_hint,
571 // Call to void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
572 // kmp_critical_name *crit);
573 OMPRTL__kmpc_end_critical,
574 // Call to kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
575 // global_tid);
576 OMPRTL__kmpc_cancel_barrier,
577 // Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
578 OMPRTL__kmpc_barrier,
579 // Call to void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid);
580 OMPRTL__kmpc_for_static_fini,
581 // Call to void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
582 // global_tid);
583 OMPRTL__kmpc_serialized_parallel,
584 // Call to void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
585 // global_tid);
586 OMPRTL__kmpc_end_serialized_parallel,
587 // Call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
588 // kmp_int32 num_threads);
589 OMPRTL__kmpc_push_num_threads,
590 // Call to void __kmpc_flush(ident_t *loc);
591 OMPRTL__kmpc_flush,
592 // Call to kmp_int32 __kmpc_master(ident_t *, kmp_int32 global_tid);
593 OMPRTL__kmpc_master,
594 // Call to void __kmpc_end_master(ident_t *, kmp_int32 global_tid);
595 OMPRTL__kmpc_end_master,
596 // Call to kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid,
597 // int end_part);
598 OMPRTL__kmpc_omp_taskyield,
599 // Call to kmp_int32 __kmpc_single(ident_t *, kmp_int32 global_tid);
600 OMPRTL__kmpc_single,
601 // Call to void __kmpc_end_single(ident_t *, kmp_int32 global_tid);
602 OMPRTL__kmpc_end_single,
603 // Call to kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
604 // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
605 // kmp_routine_entry_t *task_entry);
606 OMPRTL__kmpc_omp_task_alloc,
607 // Call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t *
608 // new_task);
609 OMPRTL__kmpc_omp_task,
610 // Call to void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid,
611 // size_t cpy_size, void *cpy_data, void(*cpy_func)(void *, void *),
612 // kmp_int32 didit);
613 OMPRTL__kmpc_copyprivate,
614 // Call to kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid,
615 // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void
616 // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck);
617 OMPRTL__kmpc_reduce,
618 // Call to kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32
619 // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data,
620 // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name
621 // *lck);
622 OMPRTL__kmpc_reduce_nowait,
623 // Call to void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid,
624 // kmp_critical_name *lck);
625 OMPRTL__kmpc_end_reduce,
626 // Call to void __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid,
627 // kmp_critical_name *lck);
628 OMPRTL__kmpc_end_reduce_nowait,
629 // Call to void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
630 // kmp_task_t * new_task);
631 OMPRTL__kmpc_omp_task_begin_if0,
632 // Call to void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid,
633 // kmp_task_t * new_task);
634 OMPRTL__kmpc_omp_task_complete_if0,
635 // Call to void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid);
636 OMPRTL__kmpc_ordered,
637 // Call to void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid);
638 OMPRTL__kmpc_end_ordered,
639 // Call to kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
640 // global_tid);
641 OMPRTL__kmpc_omp_taskwait,
642 // Call to void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
643 OMPRTL__kmpc_taskgroup,
644 // Call to void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
645 OMPRTL__kmpc_end_taskgroup,
646 // Call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid,
647 // int proc_bind);
648 OMPRTL__kmpc_push_proc_bind,
649 // Call to kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32
650 // gtid, kmp_task_t * new_task, kmp_int32 ndeps, kmp_depend_info_t
651 // *dep_list, kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
652 OMPRTL__kmpc_omp_task_with_deps,
653 // Call to void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32
654 // gtid, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
655 // ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
656 OMPRTL__kmpc_omp_wait_deps,
657 // Call to kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
658 // global_tid, kmp_int32 cncl_kind);
659 OMPRTL__kmpc_cancellationpoint,
660 // Call to kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
661 // kmp_int32 cncl_kind);
662 OMPRTL__kmpc_cancel,
663 // Call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32 global_tid,
664 // kmp_int32 num_teams, kmp_int32 thread_limit);
665 OMPRTL__kmpc_push_num_teams,
666 // Call to void __kmpc_fork_teams(ident_t *loc, kmp_int32 argc, kmpc_micro
667 // microtask, ...);
668 OMPRTL__kmpc_fork_teams,
669 // Call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
670 // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
671 // sched, kmp_uint64 grainsize, void *task_dup);
672 OMPRTL__kmpc_taskloop,
673 // Call to void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid, kmp_int32
674 // num_dims, struct kmp_dim *dims);
675 OMPRTL__kmpc_doacross_init,
676 // Call to void __kmpc_doacross_fini(ident_t *loc, kmp_int32 gtid);
677 OMPRTL__kmpc_doacross_fini,
678 // Call to void __kmpc_doacross_post(ident_t *loc, kmp_int32 gtid, kmp_int64
679 // *vec);
680 OMPRTL__kmpc_doacross_post,
681 // Call to void __kmpc_doacross_wait(ident_t *loc, kmp_int32 gtid, kmp_int64
682 // *vec);
683 OMPRTL__kmpc_doacross_wait,
684 // Call to void *__kmpc_task_reduction_init(int gtid, int num_data, void
685 // *data);
686 OMPRTL__kmpc_task_reduction_init,
687 // Call to void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
688 // *d);
689 OMPRTL__kmpc_task_reduction_get_th_data,
690 // Call to void *__kmpc_alloc(int gtid, size_t sz, omp_allocator_handle_t al);
691 OMPRTL__kmpc_alloc,
692 // Call to void __kmpc_free(int gtid, void *ptr, omp_allocator_handle_t al);
693 OMPRTL__kmpc_free,
694
695 //
696 // Offloading related calls
697 //
698 // Call to void __kmpc_push_target_tripcount(int64_t device_id, kmp_uint64
699 // size);
700 OMPRTL__kmpc_push_target_tripcount,
701 // Call to int32_t __tgt_target(int64_t device_id, void *host_ptr, int32_t
702 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
703 // *arg_types);
704 OMPRTL__tgt_target,
705 // Call to int32_t __tgt_target_nowait(int64_t device_id, void *host_ptr,
706 // int32_t arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
707 // *arg_types);
708 OMPRTL__tgt_target_nowait,
709 // Call to int32_t __tgt_target_teams(int64_t device_id, void *host_ptr,
710 // int32_t arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
711 // *arg_types, int32_t num_teams, int32_t thread_limit);
712 OMPRTL__tgt_target_teams,
713 // Call to int32_t __tgt_target_teams_nowait(int64_t device_id, void
714 // *host_ptr, int32_t arg_num, void** args_base, void **args, size_t
715 // *arg_sizes, int64_t *arg_types, int32_t num_teams, int32_t thread_limit);
716 OMPRTL__tgt_target_teams_nowait,
717 // Call to void __tgt_register_requires(int64_t flags);
718 OMPRTL__tgt_register_requires,
719 // Call to void __tgt_register_lib(__tgt_bin_desc *desc);
720 OMPRTL__tgt_register_lib,
721 // Call to void __tgt_unregister_lib(__tgt_bin_desc *desc);
722 OMPRTL__tgt_unregister_lib,
723 // Call to void __tgt_target_data_begin(int64_t device_id, int32_t arg_num,
724 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
725 OMPRTL__tgt_target_data_begin,
726 // Call to void __tgt_target_data_begin_nowait(int64_t device_id, int32_t
727 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
728 // *arg_types);
729 OMPRTL__tgt_target_data_begin_nowait,
730 // Call to void __tgt_target_data_end(int64_t device_id, int32_t arg_num,
731 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
732 OMPRTL__tgt_target_data_end,
733 // Call to void __tgt_target_data_end_nowait(int64_t device_id, int32_t
734 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
735 // *arg_types);
736 OMPRTL__tgt_target_data_end_nowait,
737 // Call to void __tgt_target_data_update(int64_t device_id, int32_t arg_num,
738 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
739 OMPRTL__tgt_target_data_update,
740 // Call to void __tgt_target_data_update_nowait(int64_t device_id, int32_t
741 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
742 // *arg_types);
743 OMPRTL__tgt_target_data_update_nowait,
744};
745
746/// A basic class for pre|post-action for advanced codegen sequence for OpenMP
747/// region.
748class CleanupTy final : public EHScopeStack::Cleanup {
749 PrePostActionTy *Action;
750
751public:
752 explicit CleanupTy(PrePostActionTy *Action) : Action(Action) {}
753 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
754 if (!CGF.HaveInsertPoint())
755 return;
756 Action->Exit(CGF);
757 }
758};
759
760} // anonymous namespace
761
762void RegionCodeGenTy::operator()(CodeGenFunction &CGF) const {
763 CodeGenFunction::RunCleanupsScope Scope(CGF);
764 if (PrePostAction) {
765 CGF.EHStack.pushCleanup<CleanupTy>(NormalAndEHCleanup, PrePostAction);
766 Callback(CodeGen, CGF, *PrePostAction);
767 } else {
768 PrePostActionTy Action;
769 Callback(CodeGen, CGF, Action);
770 }
771}
772
773/// Check if the combiner is a call to UDR combiner and if it is so return the
774/// UDR decl used for reduction.
775static const OMPDeclareReductionDecl *
776getReductionInit(const Expr *ReductionOp) {
777 if (const auto *CE = dyn_cast<CallExpr>(ReductionOp))
778 if (const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
779 if (const auto *DRE =
780 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
781 if (const auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))
782 return DRD;
783 return nullptr;
784}
785
786static void emitInitWithReductionInitializer(CodeGenFunction &CGF,
787 const OMPDeclareReductionDecl *DRD,
788 const Expr *InitOp,
789 Address Private, Address Original,
790 QualType Ty) {
791 if (DRD->getInitializer()) {
792 std::pair<llvm::Function *, llvm::Function *> Reduction =
793 CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
794 const auto *CE = cast<CallExpr>(InitOp);
795 const auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());
796 const Expr *LHS = CE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
797 const Expr *RHS = CE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
798 const auto *LHSDRE =
799 cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());
800 const auto *RHSDRE =
801 cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());
802 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
803 PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),
804 [=]() { return Private; });
805 PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),
806 [=]() { return Original; });
807 (void)PrivateScope.Privatize();
808 RValue Func = RValue::get(Reduction.second);
809 CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
810 CGF.EmitIgnoredExpr(InitOp);
811 } else {
812 llvm::Constant *Init = CGF.CGM.EmitNullConstant(Ty);
813 std::string Name = CGF.CGM.getOpenMPRuntime().getName({"init"});
814 auto *GV = new llvm::GlobalVariable(
815 CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
816 llvm::GlobalValue::PrivateLinkage, Init, Name);
817 LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty);
818 RValue InitRVal;
819 switch (CGF.getEvaluationKind(Ty)) {
820 case TEK_Scalar:
821 InitRVal = CGF.EmitLoadOfLValue(LV, DRD->getLocation());
822 break;
823 case TEK_Complex:
824 InitRVal =
825 RValue::getComplex(CGF.EmitLoadOfComplex(LV, DRD->getLocation()));
826 break;
827 case TEK_Aggregate:
828 InitRVal = RValue::getAggregate(LV.getAddress());
829 break;
830 }
831 OpaqueValueExpr OVE(DRD->getLocation(), Ty, VK_RValue);
832 CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal);
833 CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),
834 /*IsInitializer=*/false);
835 }
836}
837
838/// Emit initialization of arrays of complex types.
839/// \param DestAddr Address of the array.
840/// \param Type Type of array.
841/// \param Init Initial expression of array.
842/// \param SrcAddr Address of the original array.
843static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
844 QualType Type, bool EmitDeclareReductionInit,
845 const Expr *Init,
846 const OMPDeclareReductionDecl *DRD,
847 Address SrcAddr = Address::invalid()) {
848 // Perform element-by-element initialization.
849 QualType ElementTy;
850
851 // Drill down to the base element type on both arrays.
852 const ArrayType *ArrayTy = Type->getAsArrayTypeUnsafe();
853 llvm::Value *NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, DestAddr);
854 DestAddr =
855 CGF.Builder.CreateElementBitCast(DestAddr, DestAddr.getElementType());
856 if (DRD)
857 SrcAddr =
858 CGF.Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
859
860 llvm::Value *SrcBegin = nullptr;
861 if (DRD)
862 SrcBegin = SrcAddr.getPointer();
863 llvm::Value *DestBegin = DestAddr.getPointer();
864 // Cast from pointer to array type to pointer to single element.
865 llvm::Value *DestEnd = CGF.Builder.CreateGEP(DestBegin, NumElements);
866 // The basic structure here is a while-do loop.
867 llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.arrayinit.body");
868 llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.arrayinit.done");
869 llvm::Value *IsEmpty =
870 CGF.Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arrayinit.isempty");
871 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
872
873 // Enter the loop body, making that address the current address.
874 llvm::BasicBlock *EntryBB = CGF.Builder.GetInsertBlock();
875 CGF.EmitBlock(BodyBB);
876
877 CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
878
879 llvm::PHINode *SrcElementPHI = nullptr;
880 Address SrcElementCurrent = Address::invalid();
881 if (DRD) {
882 SrcElementPHI = CGF.Builder.CreatePHI(SrcBegin->getType(), 2,
883 "omp.arraycpy.srcElementPast");
884 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
885 SrcElementCurrent =
886 Address(SrcElementPHI,
887 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
888 }
889 llvm::PHINode *DestElementPHI = CGF.Builder.CreatePHI(
890 DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
891 DestElementPHI->addIncoming(DestBegin, EntryBB);
892 Address DestElementCurrent =
893 Address(DestElementPHI,
894 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
895
896 // Emit copy.
897 {
898 CodeGenFunction::RunCleanupsScope InitScope(CGF);
899 if (EmitDeclareReductionInit) {
900 emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,
901 SrcElementCurrent, ElementTy);
902 } else
903 CGF.EmitAnyExprToMem(Init, DestElementCurrent, ElementTy.getQualifiers(),
904 /*IsInitializer=*/false);
905 }
906
907 if (DRD) {
908 // Shift the address forward by one element.
909 llvm::Value *SrcElementNext = CGF.Builder.CreateConstGEP1_32(
910 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
911 SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock());
912 }
913
914 // Shift the address forward by one element.
915 llvm::Value *DestElementNext = CGF.Builder.CreateConstGEP1_32(
916 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
917 // Check whether we've reached the end.
918 llvm::Value *Done =
919 CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
920 CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
921 DestElementPHI->addIncoming(DestElementNext, CGF.Builder.GetInsertBlock());
922
923 // Done.
924 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
925}
926
927LValue ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, const Expr *E) {
928 return CGF.EmitOMPSharedLValue(E);
929}
930
931LValue ReductionCodeGen::emitSharedLValueUB(CodeGenFunction &CGF,
932 const Expr *E) {
933 if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(E))
934 return CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false);
935 return LValue();
936}
937
938void ReductionCodeGen::emitAggregateInitialization(
939 CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal,
940 const OMPDeclareReductionDecl *DRD) {
941 // Emit VarDecl with copy init for arrays.
942 // Get the address of the original variable captured in current
943 // captured region.
944 const auto *PrivateVD =
945 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
946 bool EmitDeclareReductionInit =
947 DRD && (DRD->getInitializer() || !PrivateVD->hasInit());
948 EmitOMPAggregateInit(CGF, PrivateAddr, PrivateVD->getType(),
949 EmitDeclareReductionInit,
950 EmitDeclareReductionInit ? ClausesData[N].ReductionOp
951 : PrivateVD->getInit(),
952 DRD, SharedLVal.getAddress());
953}
954
955ReductionCodeGen::ReductionCodeGen(ArrayRef<const Expr *> Shareds,
956 ArrayRef<const Expr *> Privates,
957 ArrayRef<const Expr *> ReductionOps) {
958 ClausesData.reserve(Shareds.size());
959 SharedAddresses.reserve(Shareds.size());
960 Sizes.reserve(Shareds.size());
961 BaseDecls.reserve(Shareds.size());
962 auto IPriv = Privates.begin();
963 auto IRed = ReductionOps.begin();
964 for (const Expr *Ref : Shareds) {
965 ClausesData.emplace_back(Ref, *IPriv, *IRed);
966 std::advance(IPriv, 1);
967 std::advance(IRed, 1);
968 }
969}
970
971void ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, unsigned N) {
972 assert(SharedAddresses.size() == N &&((SharedAddresses.size() == N && "Number of generated lvalues must be exactly N."
) ? static_cast<void> (0) : __assert_fail ("SharedAddresses.size() == N && \"Number of generated lvalues must be exactly N.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 973, __PRETTY_FUNCTION__))
973 "Number of generated lvalues must be exactly N.")((SharedAddresses.size() == N && "Number of generated lvalues must be exactly N."
) ? static_cast<void> (0) : __assert_fail ("SharedAddresses.size() == N && \"Number of generated lvalues must be exactly N.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 973, __PRETTY_FUNCTION__))
;
974 LValue First = emitSharedLValue(CGF, ClausesData[N].Ref);
975 LValue Second = emitSharedLValueUB(CGF, ClausesData[N].Ref);
976 SharedAddresses.emplace_back(First, Second);
977}
978
979void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N) {
980 const auto *PrivateVD =
981 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
982 QualType PrivateType = PrivateVD->getType();
983 bool AsArraySection = isa<OMPArraySectionExpr>(ClausesData[N].Ref);
984 if (!PrivateType->isVariablyModifiedType()) {
985 Sizes.emplace_back(
986 CGF.getTypeSize(
987 SharedAddresses[N].first.getType().getNonReferenceType()),
988 nullptr);
989 return;
990 }
991 llvm::Value *Size;
992 llvm::Value *SizeInChars;
993 auto *ElemType =
994 cast<llvm::PointerType>(SharedAddresses[N].first.getPointer()->getType())
995 ->getElementType();
996 auto *ElemSizeOf = llvm::ConstantExpr::getSizeOf(ElemType);
997 if (AsArraySection) {
998 Size = CGF.Builder.CreatePtrDiff(SharedAddresses[N].second.getPointer(),
999 SharedAddresses[N].first.getPointer());
1000 Size = CGF.Builder.CreateNUWAdd(
1001 Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1));
1002 SizeInChars = CGF.Builder.CreateNUWMul(Size, ElemSizeOf);
1003 } else {
1004 SizeInChars = CGF.getTypeSize(
1005 SharedAddresses[N].first.getType().getNonReferenceType());
1006 Size = CGF.Builder.CreateExactUDiv(SizeInChars, ElemSizeOf);
1007 }
1008 Sizes.emplace_back(SizeInChars, Size);
1009 CodeGenFunction::OpaqueValueMapping OpaqueMap(
1010 CGF,
1011 cast<OpaqueValueExpr>(
1012 CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),
1013 RValue::get(Size));
1014 CGF.EmitVariablyModifiedType(PrivateType);
1015}
1016
1017void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N,
1018 llvm::Value *Size) {
1019 const auto *PrivateVD =
1020 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1021 QualType PrivateType = PrivateVD->getType();
1022 if (!PrivateType->isVariablyModifiedType()) {
1023 assert(!Size && !Sizes[N].second &&((!Size && !Sizes[N].second && "Size should be nullptr for non-variably modified reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("!Size && !Sizes[N].second && \"Size should be nullptr for non-variably modified reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1025, __PRETTY_FUNCTION__))
1024 "Size should be nullptr for non-variably modified reduction "((!Size && !Sizes[N].second && "Size should be nullptr for non-variably modified reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("!Size && !Sizes[N].second && \"Size should be nullptr for non-variably modified reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1025, __PRETTY_FUNCTION__))
1025 "items.")((!Size && !Sizes[N].second && "Size should be nullptr for non-variably modified reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("!Size && !Sizes[N].second && \"Size should be nullptr for non-variably modified reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1025, __PRETTY_FUNCTION__))
;
1026 return;
1027 }
1028 CodeGenFunction::OpaqueValueMapping OpaqueMap(
1029 CGF,
1030 cast<OpaqueValueExpr>(
1031 CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),
1032 RValue::get(Size));
1033 CGF.EmitVariablyModifiedType(PrivateType);
1034}
1035
1036void ReductionCodeGen::emitInitialization(
1037 CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal,
1038 llvm::function_ref<bool(CodeGenFunction &)> DefaultInit) {
1039 assert(SharedAddresses.size() > N && "No variable was generated")((SharedAddresses.size() > N && "No variable was generated"
) ? static_cast<void> (0) : __assert_fail ("SharedAddresses.size() > N && \"No variable was generated\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1039, __PRETTY_FUNCTION__))
;
1040 const auto *PrivateVD =
1041 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1042 const OMPDeclareReductionDecl *DRD =
1043 getReductionInit(ClausesData[N].ReductionOp);
1044 QualType PrivateType = PrivateVD->getType();
1045 PrivateAddr = CGF.Builder.CreateElementBitCast(
1046 PrivateAddr, CGF.ConvertTypeForMem(PrivateType));
1047 QualType SharedType = SharedAddresses[N].first.getType();
1048 SharedLVal = CGF.MakeAddrLValue(
1049 CGF.Builder.CreateElementBitCast(SharedLVal.getAddress(),
1050 CGF.ConvertTypeForMem(SharedType)),
1051 SharedType, SharedAddresses[N].first.getBaseInfo(),
1052 CGF.CGM.getTBAAInfoForSubobject(SharedAddresses[N].first, SharedType));
1053 if (CGF.getContext().getAsArrayType(PrivateVD->getType())) {
1054 emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD);
1055 } else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
1056 emitInitWithReductionInitializer(CGF, DRD, ClausesData[N].ReductionOp,
1057 PrivateAddr, SharedLVal.getAddress(),
1058 SharedLVal.getType());
1059 } else if (!DefaultInit(CGF) && PrivateVD->hasInit() &&
1060 !CGF.isTrivialInitializer(PrivateVD->getInit())) {
1061 CGF.EmitAnyExprToMem(PrivateVD->getInit(), PrivateAddr,
1062 PrivateVD->getType().getQualifiers(),
1063 /*IsInitializer=*/false);
1064 }
1065}
1066
1067bool ReductionCodeGen::needCleanups(unsigned N) {
1068 const auto *PrivateVD =
1069 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1070 QualType PrivateType = PrivateVD->getType();
1071 QualType::DestructionKind DTorKind = PrivateType.isDestructedType();
1072 return DTorKind != QualType::DK_none;
1073}
1074
1075void ReductionCodeGen::emitCleanups(CodeGenFunction &CGF, unsigned N,
1076 Address PrivateAddr) {
1077 const auto *PrivateVD =
1078 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1079 QualType PrivateType = PrivateVD->getType();
1080 QualType::DestructionKind DTorKind = PrivateType.isDestructedType();
1081 if (needCleanups(N)) {
1082 PrivateAddr = CGF.Builder.CreateElementBitCast(
1083 PrivateAddr, CGF.ConvertTypeForMem(PrivateType));
1084 CGF.pushDestroy(DTorKind, PrivateAddr, PrivateType);
1085 }
1086}
1087
1088static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
1089 LValue BaseLV) {
1090 BaseTy = BaseTy.getNonReferenceType();
1091 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
1092 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
1093 if (const auto *PtrTy = BaseTy->getAs<PointerType>()) {
1094 BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);
1095 } else {
1096 LValue RefLVal = CGF.MakeAddrLValue(BaseLV.getAddress(), BaseTy);
1097 BaseLV = CGF.EmitLoadOfReferenceLValue(RefLVal);
1098 }
1099 BaseTy = BaseTy->getPointeeType();
1100 }
1101 return CGF.MakeAddrLValue(
1102 CGF.Builder.CreateElementBitCast(BaseLV.getAddress(),
1103 CGF.ConvertTypeForMem(ElTy)),
1104 BaseLV.getType(), BaseLV.getBaseInfo(),
1105 CGF.CGM.getTBAAInfoForSubobject(BaseLV, BaseLV.getType()));
1106}
1107
1108static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
1109 llvm::Type *BaseLVType, CharUnits BaseLVAlignment,
1110 llvm::Value *Addr) {
1111 Address Tmp = Address::invalid();
1112 Address TopTmp = Address::invalid();
1113 Address MostTopTmp = Address::invalid();
1114 BaseTy = BaseTy.getNonReferenceType();
1115 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
1116 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
1117 Tmp = CGF.CreateMemTemp(BaseTy);
1118 if (TopTmp.isValid())
1119 CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp);
1120 else
1121 MostTopTmp = Tmp;
1122 TopTmp = Tmp;
1123 BaseTy = BaseTy->getPointeeType();
1124 }
1125 llvm::Type *Ty = BaseLVType;
1126 if (Tmp.isValid())
1127 Ty = Tmp.getElementType();
1128 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty);
1129 if (Tmp.isValid()) {
1130 CGF.Builder.CreateStore(Addr, Tmp);
1131 return MostTopTmp;
1132 }
1133 return Address(Addr, BaseLVAlignment);
1134}
1135
1136static const VarDecl *getBaseDecl(const Expr *Ref, const DeclRefExpr *&DE) {
1137 const VarDecl *OrigVD = nullptr;
1138 if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(Ref)) {
1139 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
1140 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
1141 Base = TempOASE->getBase()->IgnoreParenImpCasts();
1142 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
1143 Base = TempASE->getBase()->IgnoreParenImpCasts();
1144 DE = cast<DeclRefExpr>(Base);
1145 OrigVD = cast<VarDecl>(DE->getDecl());
1146 } else if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Ref)) {
1147 const Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
1148 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
1149 Base = TempASE->getBase()->IgnoreParenImpCasts();
1150 DE = cast<DeclRefExpr>(Base);
1151 OrigVD = cast<VarDecl>(DE->getDecl());
1152 }
1153 return OrigVD;
1154}
1155
1156Address ReductionCodeGen::adjustPrivateAddress(CodeGenFunction &CGF, unsigned N,
1157 Address PrivateAddr) {
1158 const DeclRefExpr *DE;
1159 if (const VarDecl *OrigVD = ::getBaseDecl(ClausesData[N].Ref, DE)) {
1160 BaseDecls.emplace_back(OrigVD);
1161 LValue OriginalBaseLValue = CGF.EmitLValue(DE);
1162 LValue BaseLValue =
1163 loadToBegin(CGF, OrigVD->getType(), SharedAddresses[N].first.getType(),
1164 OriginalBaseLValue);
1165 llvm::Value *Adjustment = CGF.Builder.CreatePtrDiff(
1166 BaseLValue.getPointer(), SharedAddresses[N].first.getPointer());
1167 llvm::Value *PrivatePointer =
1168 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1169 PrivateAddr.getPointer(),
1170 SharedAddresses[N].first.getAddress().getType());
1171 llvm::Value *Ptr = CGF.Builder.CreateGEP(PrivatePointer, Adjustment);
1172 return castToBase(CGF, OrigVD->getType(),
1173 SharedAddresses[N].first.getType(),
1174 OriginalBaseLValue.getAddress().getType(),
1175 OriginalBaseLValue.getAlignment(), Ptr);
1176 }
1177 BaseDecls.emplace_back(
1178 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Ref)->getDecl()));
1179 return PrivateAddr;
1180}
1181
1182bool ReductionCodeGen::usesReductionInitializer(unsigned N) const {
1183 const OMPDeclareReductionDecl *DRD =
1184 getReductionInit(ClausesData[N].ReductionOp);
1185 return DRD && DRD->getInitializer();
1186}
1187
1188LValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) {
1189 return CGF.EmitLoadOfPointerLValue(
1190 CGF.GetAddrOfLocalVar(getThreadIDVariable()),
1191 getThreadIDVariable()->getType()->castAs<PointerType>());
1192}
1193
1194void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt * /*S*/) {
1195 if (!CGF.HaveInsertPoint())
1196 return;
1197 // 1.2.2 OpenMP Language Terminology
1198 // Structured block - An executable statement with a single entry at the
1199 // top and a single exit at the bottom.
1200 // The point of exit cannot be a branch out of the structured block.
1201 // longjmp() and throw() must not violate the entry/exit criteria.
1202 CGF.EHStack.pushTerminate();
1203 CodeGen(CGF);
1204 CGF.EHStack.popTerminate();
1205}
1206
1207LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
1208 CodeGenFunction &CGF) {
1209 return CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(getThreadIDVariable()),
1210 getThreadIDVariable()->getType(),
1211 AlignmentSource::Decl);
1212}
1213
1214static FieldDecl *addFieldToRecordDecl(ASTContext &C, DeclContext *DC,
1215 QualType FieldTy) {
1216 auto *Field = FieldDecl::Create(
1217 C, DC, SourceLocation(), SourceLocation(), /*Id=*/nullptr, FieldTy,
1218 C.getTrivialTypeSourceInfo(FieldTy, SourceLocation()),
1219 /*BW=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit);
1220 Field->setAccess(AS_public);
1221 DC->addDecl(Field);
1222 return Field;
1223}
1224
1225CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator,
1226 StringRef Separator)
1227 : CGM(CGM), FirstSeparator(FirstSeparator), Separator(Separator),
1228 OffloadEntriesInfoManager(CGM) {
1229 ASTContext &C = CGM.getContext();
1230 RecordDecl *RD = C.buildImplicitRecord("ident_t");
1231 QualType KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
1232 RD->startDefinition();
1233 // reserved_1
1234 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1235 // flags
1236 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1237 // reserved_2
1238 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1239 // reserved_3
1240 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1241 // psource
1242 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
1243 RD->completeDefinition();
1244 IdentQTy = C.getRecordType(RD);
1245 IdentTy = CGM.getTypes().ConvertRecordDeclType(RD);
1246 KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8);
1247
1248 loadOffloadInfoMetadata();
1249}
1250
1251void CGOpenMPRuntime::clear() {
1252 InternalVars.clear();
1253 // Clean non-target variable declarations possibly used only in debug info.
1254 for (const auto &Data : EmittedNonTargetVariables) {
1255 if (!Data.getValue().pointsToAliveValue())
1256 continue;
1257 auto *GV = dyn_cast<llvm::GlobalVariable>(Data.getValue());
1258 if (!GV)
1259 continue;
1260 if (!GV->isDeclaration() || GV->getNumUses() > 0)
1261 continue;
1262 GV->eraseFromParent();
1263 }
1264}
1265
1266std::string CGOpenMPRuntime::getName(ArrayRef<StringRef> Parts) const {
1267 SmallString<128> Buffer;
1268 llvm::raw_svector_ostream OS(Buffer);
1269 StringRef Sep = FirstSeparator;
1270 for (StringRef Part : Parts) {
1271 OS << Sep << Part;
1272 Sep = Separator;
1273 }
1274 return OS.str();
1275}
1276
1277static llvm::Function *
1278emitCombinerOrInitializer(CodeGenModule &CGM, QualType Ty,
1279 const Expr *CombinerInitializer, const VarDecl *In,
1280 const VarDecl *Out, bool IsCombiner) {
1281 // void .omp_combiner.(Ty *in, Ty *out);
1282 ASTContext &C = CGM.getContext();
1283 QualType PtrTy = C.getPointerType(Ty).withRestrict();
1284 FunctionArgList Args;
1285 ImplicitParamDecl OmpOutParm(C, /*DC=*/nullptr, Out->getLocation(),
1286 /*Id=*/nullptr, PtrTy, ImplicitParamDecl::Other);
1287 ImplicitParamDecl OmpInParm(C, /*DC=*/nullptr, In->getLocation(),
1288 /*Id=*/nullptr, PtrTy, ImplicitParamDecl::Other);
1289 Args.push_back(&OmpOutParm);
1290 Args.push_back(&OmpInParm);
1291 const CGFunctionInfo &FnInfo =
1292 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
1293 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
1294 std::string Name = CGM.getOpenMPRuntime().getName(
1295 {IsCombiner ? "omp_combiner" : "omp_initializer", ""});
1296 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
1297 Name, &CGM.getModule());
1298 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
1299 if (CGM.getLangOpts().Optimize) {
1300 Fn->removeFnAttr(llvm::Attribute::NoInline);
1301 Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
1302 Fn->addFnAttr(llvm::Attribute::AlwaysInline);
1303 }
1304 CodeGenFunction CGF(CGM);
1305 // Map "T omp_in;" variable to "*omp_in_parm" value in all expressions.
1306 // Map "T omp_out;" variable to "*omp_out_parm" value in all expressions.
1307 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, In->getLocation(),
1308 Out->getLocation());
1309 CodeGenFunction::OMPPrivateScope Scope(CGF);
1310 Address AddrIn = CGF.GetAddrOfLocalVar(&OmpInParm);
1311 Scope.addPrivate(In, [&CGF, AddrIn, PtrTy]() {
1312 return CGF.EmitLoadOfPointerLValue(AddrIn, PtrTy->castAs<PointerType>())
1313 .getAddress();
1314 });
1315 Address AddrOut = CGF.GetAddrOfLocalVar(&OmpOutParm);
1316 Scope.addPrivate(Out, [&CGF, AddrOut, PtrTy]() {
1317 return CGF.EmitLoadOfPointerLValue(AddrOut, PtrTy->castAs<PointerType>())
1318 .getAddress();
1319 });
1320 (void)Scope.Privatize();
1321 if (!IsCombiner && Out->hasInit() &&
1322 !CGF.isTrivialInitializer(Out->getInit())) {
1323 CGF.EmitAnyExprToMem(Out->getInit(), CGF.GetAddrOfLocalVar(Out),
1324 Out->getType().getQualifiers(),
1325 /*IsInitializer=*/true);
1326 }
1327 if (CombinerInitializer)
1328 CGF.EmitIgnoredExpr(CombinerInitializer);
1329 Scope.ForceCleanup();
1330 CGF.FinishFunction();
1331 return Fn;
1332}
1333
1334void CGOpenMPRuntime::emitUserDefinedReduction(
1335 CodeGenFunction *CGF, const OMPDeclareReductionDecl *D) {
1336 if (UDRMap.count(D) > 0)
1337 return;
1338 llvm::Function *Combiner = emitCombinerOrInitializer(
1339 CGM, D->getType(), D->getCombiner(),
1340 cast<VarDecl>(cast<DeclRefExpr>(D->getCombinerIn())->getDecl()),
1341 cast<VarDecl>(cast<DeclRefExpr>(D->getCombinerOut())->getDecl()),
1342 /*IsCombiner=*/true);
1343 llvm::Function *Initializer = nullptr;
1344 if (const Expr *Init = D->getInitializer()) {
1345 Initializer = emitCombinerOrInitializer(
1346 CGM, D->getType(),
1347 D->getInitializerKind() == OMPDeclareReductionDecl::CallInit ? Init
1348 : nullptr,
1349 cast<VarDecl>(cast<DeclRefExpr>(D->getInitOrig())->getDecl()),
1350 cast<VarDecl>(cast<DeclRefExpr>(D->getInitPriv())->getDecl()),
1351 /*IsCombiner=*/false);
1352 }
1353 UDRMap.try_emplace(D, Combiner, Initializer);
1354 if (CGF) {
1355 auto &Decls = FunctionUDRMap.FindAndConstruct(CGF->CurFn);
1356 Decls.second.push_back(D);
1357 }
1358}
1359
1360std::pair<llvm::Function *, llvm::Function *>
1361CGOpenMPRuntime::getUserDefinedReduction(const OMPDeclareReductionDecl *D) {
1362 auto I = UDRMap.find(D);
1363 if (I != UDRMap.end())
1364 return I->second;
1365 emitUserDefinedReduction(/*CGF=*/nullptr, D);
1366 return UDRMap.lookup(D);
1367}
1368
1369static llvm::Function *emitParallelOrTeamsOutlinedFunction(
1370 CodeGenModule &CGM, const OMPExecutableDirective &D, const CapturedStmt *CS,
1371 const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind,
1372 const StringRef OutlinedHelperName, const RegionCodeGenTy &CodeGen) {
1373 assert(ThreadIDVar->getType()->isPointerType() &&((ThreadIDVar->getType()->isPointerType() && "thread id variable must be of type kmp_int32 *"
) ? static_cast<void> (0) : __assert_fail ("ThreadIDVar->getType()->isPointerType() && \"thread id variable must be of type kmp_int32 *\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1374, __PRETTY_FUNCTION__))
1374 "thread id variable must be of type kmp_int32 *")((ThreadIDVar->getType()->isPointerType() && "thread id variable must be of type kmp_int32 *"
) ? static_cast<void> (0) : __assert_fail ("ThreadIDVar->getType()->isPointerType() && \"thread id variable must be of type kmp_int32 *\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1374, __PRETTY_FUNCTION__))
;
1375 CodeGenFunction CGF(CGM, true);
1376 bool HasCancel = false;
1377 if (const auto *OPD = dyn_cast<OMPParallelDirective>(&D))
1378 HasCancel = OPD->hasCancel();
1379 else if (const auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&D))
1380 HasCancel = OPSD->hasCancel();
1381 else if (const auto *OPFD = dyn_cast<OMPParallelForDirective>(&D))
1382 HasCancel = OPFD->hasCancel();
1383 else if (const auto *OPFD = dyn_cast<OMPTargetParallelForDirective>(&D))
1384 HasCancel = OPFD->hasCancel();
1385 else if (const auto *OPFD = dyn_cast<OMPDistributeParallelForDirective>(&D))
1386 HasCancel = OPFD->hasCancel();
1387 else if (const auto *OPFD =
1388 dyn_cast<OMPTeamsDistributeParallelForDirective>(&D))
1389 HasCancel = OPFD->hasCancel();
1390 else if (const auto *OPFD =
1391 dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&D))
1392 HasCancel = OPFD->hasCancel();
1393 CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
1394 HasCancel, OutlinedHelperName);
1395 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
1396 return CGF.GenerateOpenMPCapturedStmtFunction(*CS);
1397}
1398
1399llvm::Function *CGOpenMPRuntime::emitParallelOutlinedFunction(
1400 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1401 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
1402 const CapturedStmt *CS = D.getCapturedStmt(OMPD_parallel);
1403 return emitParallelOrTeamsOutlinedFunction(
1404 CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
1405}
1406
1407llvm::Function *CGOpenMPRuntime::emitTeamsOutlinedFunction(
1408 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1409 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
1410 const CapturedStmt *CS = D.getCapturedStmt(OMPD_teams);
1411 return emitParallelOrTeamsOutlinedFunction(
1412 CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
1413}
1414
1415llvm::Function *CGOpenMPRuntime::emitTaskOutlinedFunction(
1416 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1417 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
1418 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
1419 bool Tied, unsigned &NumberOfParts) {
1420 auto &&UntiedCodeGen = [this, &D, TaskTVar](CodeGenFunction &CGF,
1421 PrePostActionTy &) {
1422 llvm::Value *ThreadID = getThreadID(CGF, D.getBeginLoc());
1423 llvm::Value *UpLoc = emitUpdateLocation(CGF, D.getBeginLoc());
1424 llvm::Value *TaskArgs[] = {
1425 UpLoc, ThreadID,
1426 CGF.EmitLoadOfPointerLValue(CGF.GetAddrOfLocalVar(TaskTVar),
1427 TaskTVar->getType()->castAs<PointerType>())
1428 .getPointer()};
1429 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task), TaskArgs);
1430 };
1431 CGOpenMPTaskOutlinedRegionInfo::UntiedTaskActionTy Action(Tied, PartIDVar,
1432 UntiedCodeGen);
1433 CodeGen.setAction(Action);
1434 assert(!ThreadIDVar->getType()->isPointerType() &&((!ThreadIDVar->getType()->isPointerType() && "thread id variable must be of type kmp_int32 for tasks"
) ? static_cast<void> (0) : __assert_fail ("!ThreadIDVar->getType()->isPointerType() && \"thread id variable must be of type kmp_int32 for tasks\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1435, __PRETTY_FUNCTION__))
1435 "thread id variable must be of type kmp_int32 for tasks")((!ThreadIDVar->getType()->isPointerType() && "thread id variable must be of type kmp_int32 for tasks"
) ? static_cast<void> (0) : __assert_fail ("!ThreadIDVar->getType()->isPointerType() && \"thread id variable must be of type kmp_int32 for tasks\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1435, __PRETTY_FUNCTION__))
;
1436 const OpenMPDirectiveKind Region =
1437 isOpenMPTaskLoopDirective(D.getDirectiveKind()) ? OMPD_taskloop
1438 : OMPD_task;
1439 const CapturedStmt *CS = D.getCapturedStmt(Region);
1440 const auto *TD = dyn_cast<OMPTaskDirective>(&D);
1441 CodeGenFunction CGF(CGM, true);
1442 CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
1443 InnermostKind,
1444 TD ? TD->hasCancel() : false, Action);
1445 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
1446 llvm::Function *Res = CGF.GenerateCapturedStmtFunction(*CS);
1447 if (!Tied)
1448 NumberOfParts = Action.getNumberOfParts();
1449 return Res;
1450}
1451
1452static void buildStructValue(ConstantStructBuilder &Fields, CodeGenModule &CGM,
1453 const RecordDecl *RD, const CGRecordLayout &RL,
1454 ArrayRef<llvm::Constant *> Data) {
1455 llvm::StructType *StructTy = RL.getLLVMType();
1456 unsigned PrevIdx = 0;
1457 ConstantInitBuilder CIBuilder(CGM);
1458 auto DI = Data.begin();
1459 for (const FieldDecl *FD : RD->fields()) {
1460 unsigned Idx = RL.getLLVMFieldNo(FD);
1461 // Fill the alignment.
1462 for (unsigned I = PrevIdx; I < Idx; ++I)
1463 Fields.add(llvm::Constant::getNullValue(StructTy->getElementType(I)));
1464 PrevIdx = Idx + 1;
1465 Fields.add(*DI);
1466 ++DI;
1467 }
1468}
1469
1470template <class... As>
1471static llvm::GlobalVariable *
1472createGlobalStruct(CodeGenModule &CGM, QualType Ty, bool IsConstant,
1473 ArrayRef<llvm::Constant *> Data, const Twine &Name,
1474 As &&... Args) {
1475 const auto *RD = cast<RecordDecl>(Ty->getAsTagDecl());
1476 const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(RD);
1477 ConstantInitBuilder CIBuilder(CGM);
1478 ConstantStructBuilder Fields = CIBuilder.beginStruct(RL.getLLVMType());
1479 buildStructValue(Fields, CGM, RD, RL, Data);
1480 return Fields.finishAndCreateGlobal(
1481 Name, CGM.getContext().getAlignOfGlobalVarInChars(Ty), IsConstant,
1482 std::forward<As>(Args)...);
1483}
1484
1485template <typename T>
1486static void
1487createConstantGlobalStructAndAddToParent(CodeGenModule &CGM, QualType Ty,
1488 ArrayRef<llvm::Constant *> Data,
1489 T &Parent) {
1490 const auto *RD = cast<RecordDecl>(Ty->getAsTagDecl());
1491 const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(RD);
1492 ConstantStructBuilder Fields = Parent.beginStruct(RL.getLLVMType());
1493 buildStructValue(Fields, CGM, RD, RL, Data);
1494 Fields.finishAndAddTo(Parent);
1495}
1496
1497Address CGOpenMPRuntime::getOrCreateDefaultLocation(unsigned Flags) {
1498 CharUnits Align = CGM.getContext().getTypeAlignInChars(IdentQTy);
1499 unsigned Reserved2Flags = getDefaultLocationReserved2Flags();
1500 FlagsTy FlagsKey(Flags, Reserved2Flags);
1501 llvm::Value *Entry = OpenMPDefaultLocMap.lookup(FlagsKey);
1502 if (!Entry) {
1503 if (!DefaultOpenMPPSource) {
1504 // Initialize default location for psource field of ident_t structure of
1505 // all ident_t objects. Format is ";file;function;line;column;;".
1506 // Taken from
1507 // https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp_str.cpp
1508 DefaultOpenMPPSource =
1509 CGM.GetAddrOfConstantCString(";unknown;unknown;0;0;;").getPointer();
1510 DefaultOpenMPPSource =
1511 llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy);
1512 }
1513
1514 llvm::Constant *Data[] = {
1515 llvm::ConstantInt::getNullValue(CGM.Int32Ty),
1516 llvm::ConstantInt::get(CGM.Int32Ty, Flags),
1517 llvm::ConstantInt::get(CGM.Int32Ty, Reserved2Flags),
1518 llvm::ConstantInt::getNullValue(CGM.Int32Ty), DefaultOpenMPPSource};
1519 llvm::GlobalValue *DefaultOpenMPLocation =
1520 createGlobalStruct(CGM, IdentQTy, isDefaultLocationConstant(), Data, "",
1521 llvm::GlobalValue::PrivateLinkage);
1522 DefaultOpenMPLocation->setUnnamedAddr(
1523 llvm::GlobalValue::UnnamedAddr::Global);
1524
1525 OpenMPDefaultLocMap[FlagsKey] = Entry = DefaultOpenMPLocation;
1526 }
1527 return Address(Entry, Align);
1528}
1529
1530void CGOpenMPRuntime::setLocThreadIdInsertPt(CodeGenFunction &CGF,
1531 bool AtCurrentPoint) {
1532 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1533 assert(!Elem.second.ServiceInsertPt && "Insert point is set already.")((!Elem.second.ServiceInsertPt && "Insert point is set already."
) ? static_cast<void> (0) : __assert_fail ("!Elem.second.ServiceInsertPt && \"Insert point is set already.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1533, __PRETTY_FUNCTION__))
;
1534
1535 llvm::Value *Undef = llvm::UndefValue::get(CGF.Int32Ty);
1536 if (AtCurrentPoint) {
1537 Elem.second.ServiceInsertPt = new llvm::BitCastInst(
1538 Undef, CGF.Int32Ty, "svcpt", CGF.Builder.GetInsertBlock());
1539 } else {
1540 Elem.second.ServiceInsertPt =
1541 new llvm::BitCastInst(Undef, CGF.Int32Ty, "svcpt");
1542 Elem.second.ServiceInsertPt->insertAfter(CGF.AllocaInsertPt);
1543 }
1544}
1545
1546void CGOpenMPRuntime::clearLocThreadIdInsertPt(CodeGenFunction &CGF) {
1547 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1548 if (Elem.second.ServiceInsertPt) {
1549 llvm::Instruction *Ptr = Elem.second.ServiceInsertPt;
1550 Elem.second.ServiceInsertPt = nullptr;
1551 Ptr->eraseFromParent();
1552 }
1553}
1554
1555llvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF,
1556 SourceLocation Loc,
1557 unsigned Flags) {
1558 Flags |= OMP_IDENT_KMPC;
1559 // If no debug info is generated - return global default location.
1560 if (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo ||
1561 Loc.isInvalid())
1562 return getOrCreateDefaultLocation(Flags).getPointer();
1563
1564 assert(CGF.CurFn && "No function in current CodeGenFunction.")((CGF.CurFn && "No function in current CodeGenFunction."
) ? static_cast<void> (0) : __assert_fail ("CGF.CurFn && \"No function in current CodeGenFunction.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1564, __PRETTY_FUNCTION__))
;
1565
1566 CharUnits Align = CGM.getContext().getTypeAlignInChars(IdentQTy);
1567 Address LocValue = Address::invalid();
1568 auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
1569 if (I != OpenMPLocThreadIDMap.end())
1570 LocValue = Address(I->second.DebugLoc, Align);
1571
1572 // OpenMPLocThreadIDMap may have null DebugLoc and non-null ThreadID, if
1573 // GetOpenMPThreadID was called before this routine.
1574 if (!LocValue.isValid()) {
1575 // Generate "ident_t .kmpc_loc.addr;"
1576 Address AI = CGF.CreateMemTemp(IdentQTy, ".kmpc_loc.addr");
1577 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1578 Elem.second.DebugLoc = AI.getPointer();
1579 LocValue = AI;
1580
1581 if (!Elem.second.ServiceInsertPt)
1582 setLocThreadIdInsertPt(CGF);
1583 CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
1584 CGF.Builder.SetInsertPoint(Elem.second.ServiceInsertPt);
1585 CGF.Builder.CreateMemCpy(LocValue, getOrCreateDefaultLocation(Flags),
1586 CGF.getTypeSize(IdentQTy));
1587 }
1588
1589 // char **psource = &.kmpc_loc_<flags>.addr.psource;
1590 LValue Base = CGF.MakeAddrLValue(LocValue, IdentQTy);
1591 auto Fields = cast<RecordDecl>(IdentQTy->getAsTagDecl())->field_begin();
1592 LValue PSource =
1593 CGF.EmitLValueForField(Base, *std::next(Fields, IdentField_PSource));
1594
1595 llvm::Value *OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.getRawEncoding());
1596 if (OMPDebugLoc == nullptr) {
1597 SmallString<128> Buffer2;
1598 llvm::raw_svector_ostream OS2(Buffer2);
1599 // Build debug location
1600 PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
1601 OS2 << ";" << PLoc.getFilename() << ";";
1602 if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl))
1603 OS2 << FD->getQualifiedNameAsString();
1604 OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
1605 OMPDebugLoc = CGF.Builder.CreateGlobalStringPtr(OS2.str());
1606 OpenMPDebugLocMap[Loc.getRawEncoding()] = OMPDebugLoc;
1607 }
1608 // *psource = ";<File>;<Function>;<Line>;<Column>;;";
1609 CGF.EmitStoreOfScalar(OMPDebugLoc, PSource);
1610
1611 // Our callers always pass this to a runtime function, so for
1612 // convenience, go ahead and return a naked pointer.
1613 return LocValue.getPointer();
1614}
1615
1616llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF,
1617 SourceLocation Loc) {
1618 assert(CGF.CurFn && "No function in current CodeGenFunction.")((CGF.CurFn && "No function in current CodeGenFunction."
) ? static_cast<void> (0) : __assert_fail ("CGF.CurFn && \"No function in current CodeGenFunction.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1618, __PRETTY_FUNCTION__))
;
1619
1620 llvm::Value *ThreadID = nullptr;
1621 // Check whether we've already cached a load of the thread id in this
1622 // function.
1623 auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
1624 if (I != OpenMPLocThreadIDMap.end()) {
1625 ThreadID = I->second.ThreadID;
1626 if (ThreadID != nullptr)
1627 return ThreadID;
1628 }
1629 // If exceptions are enabled, do not use parameter to avoid possible crash.
1630 if (!CGF.EHStack.requiresLandingPad() || !CGF.getLangOpts().Exceptions ||
1631 !CGF.getLangOpts().CXXExceptions ||
1632 CGF.Builder.GetInsertBlock() == CGF.AllocaInsertPt->getParent()) {
1633 if (auto *OMPRegionInfo =
1634 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
1635 if (OMPRegionInfo->getThreadIDVariable()) {
1636 // Check if this an outlined function with thread id passed as argument.
1637 LValue LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF);
1638 ThreadID = CGF.EmitLoadOfScalar(LVal, Loc);
1639 // If value loaded in entry block, cache it and use it everywhere in
1640 // function.
1641 if (CGF.Builder.GetInsertBlock() == CGF.AllocaInsertPt->getParent()) {
1642 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1643 Elem.second.ThreadID = ThreadID;
1644 }
1645 return ThreadID;
1646 }
1647 }
1648 }
1649
1650 // This is not an outlined function region - need to call __kmpc_int32
1651 // kmpc_global_thread_num(ident_t *loc).
1652 // Generate thread id value and cache this value for use across the
1653 // function.
1654 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1655 if (!Elem.second.ServiceInsertPt)
1656 setLocThreadIdInsertPt(CGF);
1657 CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
1658 CGF.Builder.SetInsertPoint(Elem.second.ServiceInsertPt);
1659 llvm::CallInst *Call = CGF.Builder.CreateCall(
1660 createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
1661 emitUpdateLocation(CGF, Loc));
1662 Call->setCallingConv(CGF.getRuntimeCC());
1663 Elem.second.ThreadID = Call;
1664 return Call;
1665}
1666
1667void CGOpenMPRuntime::functionFinished(CodeGenFunction &CGF) {
1668 assert(CGF.CurFn && "No function in current CodeGenFunction.")((CGF.CurFn && "No function in current CodeGenFunction."
) ? static_cast<void> (0) : __assert_fail ("CGF.CurFn && \"No function in current CodeGenFunction.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1668, __PRETTY_FUNCTION__))
;
1669 if (OpenMPLocThreadIDMap.count(CGF.CurFn)) {
1670 clearLocThreadIdInsertPt(CGF);
1671 OpenMPLocThreadIDMap.erase(CGF.CurFn);
1672 }
1673 if (FunctionUDRMap.count(CGF.CurFn) > 0) {
1674 for(auto *D : FunctionUDRMap[CGF.CurFn])
1675 UDRMap.erase(D);
1676 FunctionUDRMap.erase(CGF.CurFn);
1677 }
1678}
1679
1680llvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() {
1681 return IdentTy->getPointerTo();
1682}
1683
1684llvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() {
1685 if (!Kmpc_MicroTy) {
1686 // Build void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid,...)
1687 llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.Int32Ty),
1688 llvm::PointerType::getUnqual(CGM.Int32Ty)};
1689 Kmpc_MicroTy = llvm::FunctionType::get(CGM.VoidTy, MicroParams, true);
1690 }
1691 return llvm::PointerType::getUnqual(Kmpc_MicroTy);
1692}
1693
1694llvm::FunctionCallee CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
1695 llvm::FunctionCallee RTLFn = nullptr;
1696 switch (static_cast<OpenMPRTLFunction>(Function)) {
1697 case OMPRTL__kmpc_fork_call: {
1698 // Build void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro
1699 // microtask, ...);
1700 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1701 getKmpc_MicroPointerTy()};
1702 auto *FnTy =
1703 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
1704 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_call");
1705 if (auto *F = dyn_cast<llvm::Function>(RTLFn.getCallee())) {
1706 if (!F->hasMetadata(llvm::LLVMContext::MD_callback)) {
1707 llvm::LLVMContext &Ctx = F->getContext();
1708 llvm::MDBuilder MDB(Ctx);
1709 // Annotate the callback behavior of the __kmpc_fork_call:
1710 // - The callback callee is argument number 2 (microtask).
1711 // - The first two arguments of the callback callee are unknown (-1).
1712 // - All variadic arguments to the __kmpc_fork_call are passed to the
1713 // callback callee.
1714 F->addMetadata(
1715 llvm::LLVMContext::MD_callback,
1716 *llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding(
1717 2, {-1, -1},
1718 /* VarArgsArePassed */ true)}));
1719 }
1720 }
1721 break;
1722 }
1723 case OMPRTL__kmpc_global_thread_num: {
1724 // Build kmp_int32 __kmpc_global_thread_num(ident_t *loc);
1725 llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
1726 auto *FnTy =
1727 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
1728 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_global_thread_num");
1729 break;
1730 }
1731 case OMPRTL__kmpc_threadprivate_cached: {
1732 // Build void *__kmpc_threadprivate_cached(ident_t *loc,
1733 // kmp_int32 global_tid, void *data, size_t size, void ***cache);
1734 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1735 CGM.VoidPtrTy, CGM.SizeTy,
1736 CGM.VoidPtrTy->getPointerTo()->getPointerTo()};
1737 auto *FnTy =
1738 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg*/ false);
1739 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_cached");
1740 break;
1741 }
1742 case OMPRTL__kmpc_critical: {
1743 // Build void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
1744 // kmp_critical_name *crit);
1745 llvm::Type *TypeParams[] = {
1746 getIdentTyPointerTy(), CGM.Int32Ty,
1747 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1748 auto *FnTy =
1749 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1750 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical");
1751 break;
1752 }
1753 case OMPRTL__kmpc_critical_with_hint: {
1754 // Build void __kmpc_critical_with_hint(ident_t *loc, kmp_int32 global_tid,
1755 // kmp_critical_name *crit, uintptr_t hint);
1756 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1757 llvm::PointerType::getUnqual(KmpCriticalNameTy),
1758 CGM.IntPtrTy};
1759 auto *FnTy =
1760 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1761 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical_with_hint");
1762 break;
1763 }
1764 case OMPRTL__kmpc_threadprivate_register: {
1765 // Build void __kmpc_threadprivate_register(ident_t *, void *data,
1766 // kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
1767 // typedef void *(*kmpc_ctor)(void *);
1768 auto *KmpcCtorTy =
1769 llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
1770 /*isVarArg*/ false)->getPointerTo();
1771 // typedef void *(*kmpc_cctor)(void *, void *);
1772 llvm::Type *KmpcCopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
1773 auto *KmpcCopyCtorTy =
1774 llvm::FunctionType::get(CGM.VoidPtrTy, KmpcCopyCtorTyArgs,
1775 /*isVarArg*/ false)
1776 ->getPointerTo();
1777 // typedef void (*kmpc_dtor)(void *);
1778 auto *KmpcDtorTy =
1779 llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy, /*isVarArg*/ false)
1780 ->getPointerTo();
1781 llvm::Type *FnTyArgs[] = {getIdentTyPointerTy(), CGM.VoidPtrTy, KmpcCtorTy,
1782 KmpcCopyCtorTy, KmpcDtorTy};
1783 auto *FnTy = llvm::FunctionType::get(CGM.VoidTy, FnTyArgs,
1784 /*isVarArg*/ false);
1785 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_register");
1786 break;
1787 }
1788 case OMPRTL__kmpc_end_critical: {
1789 // Build void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
1790 // kmp_critical_name *crit);
1791 llvm::Type *TypeParams[] = {
1792 getIdentTyPointerTy(), CGM.Int32Ty,
1793 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1794 auto *FnTy =
1795 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1796 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_critical");
1797 break;
1798 }
1799 case OMPRTL__kmpc_cancel_barrier: {
1800 // Build kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
1801 // global_tid);
1802 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1803 auto *FnTy =
1804 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
1805 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_cancel_barrier");
1806 break;
1807 }
1808 case OMPRTL__kmpc_barrier: {
1809 // Build void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
1810 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1811 auto *FnTy =
1812 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1813 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier");
1814 break;
1815 }
1816 case OMPRTL__kmpc_for_static_fini: {
1817 // Build void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid);
1818 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1819 auto *FnTy =
1820 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1821 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_for_static_fini");
1822 break;
1823 }
1824 case OMPRTL__kmpc_push_num_threads: {
1825 // Build void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
1826 // kmp_int32 num_threads)
1827 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1828 CGM.Int32Ty};
1829 auto *FnTy =
1830 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1831 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_num_threads");
1832 break;
1833 }
1834 case OMPRTL__kmpc_serialized_parallel: {
1835 // Build void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
1836 // global_tid);
1837 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1838 auto *FnTy =
1839 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1840 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_serialized_parallel");
1841 break;
1842 }
1843 case OMPRTL__kmpc_end_serialized_parallel: {
1844 // Build void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
1845 // global_tid);
1846 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1847 auto *FnTy =
1848 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1849 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_serialized_parallel");
1850 break;
1851 }
1852 case OMPRTL__kmpc_flush: {
1853 // Build void __kmpc_flush(ident_t *loc);
1854 llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
1855 auto *FnTy =
1856 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1857 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_flush");
1858 break;
1859 }
1860 case OMPRTL__kmpc_master: {
1861 // Build kmp_int32 __kmpc_master(ident_t *loc, kmp_int32 global_tid);
1862 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1863 auto *FnTy =
1864 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1865 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_master");
1866 break;
1867 }
1868 case OMPRTL__kmpc_end_master: {
1869 // Build void __kmpc_end_master(ident_t *loc, kmp_int32 global_tid);
1870 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1871 auto *FnTy =
1872 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1873 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_master");
1874 break;
1875 }
1876 case OMPRTL__kmpc_omp_taskyield: {
1877 // Build kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid,
1878 // int end_part);
1879 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
1880 auto *FnTy =
1881 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1882 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_taskyield");
1883 break;
1884 }
1885 case OMPRTL__kmpc_single: {
1886 // Build kmp_int32 __kmpc_single(ident_t *loc, kmp_int32 global_tid);
1887 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1888 auto *FnTy =
1889 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1890 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_single");
1891 break;
1892 }
1893 case OMPRTL__kmpc_end_single: {
1894 // Build void __kmpc_end_single(ident_t *loc, kmp_int32 global_tid);
1895 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
1896 auto *FnTy =
1897 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1898 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_single");
1899 break;
1900 }
1901 case OMPRTL__kmpc_omp_task_alloc: {
1902 // Build kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
1903 // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
1904 // kmp_routine_entry_t *task_entry);
1905 assert(KmpRoutineEntryPtrTy != nullptr &&((KmpRoutineEntryPtrTy != nullptr && "Type kmp_routine_entry_t must be created."
) ? static_cast<void> (0) : __assert_fail ("KmpRoutineEntryPtrTy != nullptr && \"Type kmp_routine_entry_t must be created.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1906, __PRETTY_FUNCTION__))
1906 "Type kmp_routine_entry_t must be created.")((KmpRoutineEntryPtrTy != nullptr && "Type kmp_routine_entry_t must be created."
) ? static_cast<void> (0) : __assert_fail ("KmpRoutineEntryPtrTy != nullptr && \"Type kmp_routine_entry_t must be created.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 1906, __PRETTY_FUNCTION__))
;
1907 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty,
1908 CGM.SizeTy, CGM.SizeTy, KmpRoutineEntryPtrTy};
1909 // Return void * and then cast to particular kmp_task_t type.
1910 auto *FnTy =
1911 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
1912 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_alloc");
1913 break;
1914 }
1915 case OMPRTL__kmpc_omp_task: {
1916 // Build kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
1917 // *new_task);
1918 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1919 CGM.VoidPtrTy};
1920 auto *FnTy =
1921 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1922 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task");
1923 break;
1924 }
1925 case OMPRTL__kmpc_copyprivate: {
1926 // Build void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid,
1927 // size_t cpy_size, void *cpy_data, void(*cpy_func)(void *, void *),
1928 // kmp_int32 didit);
1929 llvm::Type *CpyTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
1930 auto *CpyFnTy =
1931 llvm::FunctionType::get(CGM.VoidTy, CpyTypeParams, /*isVarArg=*/false);
1932 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.SizeTy,
1933 CGM.VoidPtrTy, CpyFnTy->getPointerTo(),
1934 CGM.Int32Ty};
1935 auto *FnTy =
1936 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1937 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_copyprivate");
1938 break;
1939 }
1940 case OMPRTL__kmpc_reduce: {
1941 // Build kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid,
1942 // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void
1943 // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck);
1944 llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
1945 auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams,
1946 /*isVarArg=*/false);
1947 llvm::Type *TypeParams[] = {
1948 getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy,
1949 CGM.VoidPtrTy, ReduceFnTy->getPointerTo(),
1950 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1951 auto *FnTy =
1952 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1953 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce");
1954 break;
1955 }
1956 case OMPRTL__kmpc_reduce_nowait: {
1957 // Build kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32
1958 // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data,
1959 // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name
1960 // *lck);
1961 llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
1962 auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams,
1963 /*isVarArg=*/false);
1964 llvm::Type *TypeParams[] = {
1965 getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy,
1966 CGM.VoidPtrTy, ReduceFnTy->getPointerTo(),
1967 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1968 auto *FnTy =
1969 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1970 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce_nowait");
1971 break;
1972 }
1973 case OMPRTL__kmpc_end_reduce: {
1974 // Build void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid,
1975 // kmp_critical_name *lck);
1976 llvm::Type *TypeParams[] = {
1977 getIdentTyPointerTy(), CGM.Int32Ty,
1978 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1979 auto *FnTy =
1980 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1981 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce");
1982 break;
1983 }
1984 case OMPRTL__kmpc_end_reduce_nowait: {
1985 // Build __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid,
1986 // kmp_critical_name *lck);
1987 llvm::Type *TypeParams[] = {
1988 getIdentTyPointerTy(), CGM.Int32Ty,
1989 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
1990 auto *FnTy =
1991 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1992 RTLFn =
1993 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce_nowait");
1994 break;
1995 }
1996 case OMPRTL__kmpc_omp_task_begin_if0: {
1997 // Build void __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
1998 // *new_task);
1999 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2000 CGM.VoidPtrTy};
2001 auto *FnTy =
2002 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2003 RTLFn =
2004 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_begin_if0");
2005 break;
2006 }
2007 case OMPRTL__kmpc_omp_task_complete_if0: {
2008 // Build void __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
2009 // *new_task);
2010 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2011 CGM.VoidPtrTy};
2012 auto *FnTy =
2013 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2014 RTLFn = CGM.CreateRuntimeFunction(FnTy,
2015 /*Name=*/"__kmpc_omp_task_complete_if0");
2016 break;
2017 }
2018 case OMPRTL__kmpc_ordered: {
2019 // Build void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid);
2020 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
2021 auto *FnTy =
2022 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2023 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_ordered");
2024 break;
2025 }
2026 case OMPRTL__kmpc_end_ordered: {
2027 // Build void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid);
2028 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
2029 auto *FnTy =
2030 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2031 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_ordered");
2032 break;
2033 }
2034 case OMPRTL__kmpc_omp_taskwait: {
2035 // Build kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32 global_tid);
2036 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
2037 auto *FnTy =
2038 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2039 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_omp_taskwait");
2040 break;
2041 }
2042 case OMPRTL__kmpc_taskgroup: {
2043 // Build void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
2044 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
2045 auto *FnTy =
2046 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2047 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_taskgroup");
2048 break;
2049 }
2050 case OMPRTL__kmpc_end_taskgroup: {
2051 // Build void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
2052 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
2053 auto *FnTy =
2054 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2055 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_taskgroup");
2056 break;
2057 }
2058 case OMPRTL__kmpc_push_proc_bind: {
2059 // Build void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid,
2060 // int proc_bind)
2061 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
2062 auto *FnTy =
2063 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2064 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_proc_bind");
2065 break;
2066 }
2067 case OMPRTL__kmpc_omp_task_with_deps: {
2068 // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid,
2069 // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
2070 // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
2071 llvm::Type *TypeParams[] = {
2072 getIdentTyPointerTy(), CGM.Int32Ty, CGM.VoidPtrTy, CGM.Int32Ty,
2073 CGM.VoidPtrTy, CGM.Int32Ty, CGM.VoidPtrTy};
2074 auto *FnTy =
2075 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2076 RTLFn =
2077 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_with_deps");
2078 break;
2079 }
2080 case OMPRTL__kmpc_omp_wait_deps: {
2081 // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
2082 // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias,
2083 // kmp_depend_info_t *noalias_dep_list);
2084 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2085 CGM.Int32Ty, CGM.VoidPtrTy,
2086 CGM.Int32Ty, CGM.VoidPtrTy};
2087 auto *FnTy =
2088 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2089 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_wait_deps");
2090 break;
2091 }
2092 case OMPRTL__kmpc_cancellationpoint: {
2093 // Build kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
2094 // global_tid, kmp_int32 cncl_kind)
2095 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
2096 auto *FnTy =
2097 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2098 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancellationpoint");
2099 break;
2100 }
2101 case OMPRTL__kmpc_cancel: {
2102 // Build kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
2103 // kmp_int32 cncl_kind)
2104 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
2105 auto *FnTy =
2106 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2107 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancel");
2108 break;
2109 }
2110 case OMPRTL__kmpc_push_num_teams: {
2111 // Build void kmpc_push_num_teams (ident_t loc, kmp_int32 global_tid,
2112 // kmp_int32 num_teams, kmp_int32 num_threads)
2113 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty,
2114 CGM.Int32Ty};
2115 auto *FnTy =
2116 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2117 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_num_teams");
2118 break;
2119 }
2120 case OMPRTL__kmpc_fork_teams: {
2121 // Build void __kmpc_fork_teams(ident_t *loc, kmp_int32 argc, kmpc_micro
2122 // microtask, ...);
2123 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2124 getKmpc_MicroPointerTy()};
2125 auto *FnTy =
2126 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
2127 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_teams");
2128 if (auto *F = dyn_cast<llvm::Function>(RTLFn.getCallee())) {
2129 if (!F->hasMetadata(llvm::LLVMContext::MD_callback)) {
2130 llvm::LLVMContext &Ctx = F->getContext();
2131 llvm::MDBuilder MDB(Ctx);
2132 // Annotate the callback behavior of the __kmpc_fork_teams:
2133 // - The callback callee is argument number 2 (microtask).
2134 // - The first two arguments of the callback callee are unknown (-1).
2135 // - All variadic arguments to the __kmpc_fork_teams are passed to the
2136 // callback callee.
2137 F->addMetadata(
2138 llvm::LLVMContext::MD_callback,
2139 *llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding(
2140 2, {-1, -1},
2141 /* VarArgsArePassed */ true)}));
2142 }
2143 }
2144 break;
2145 }
2146 case OMPRTL__kmpc_taskloop: {
2147 // Build void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
2148 // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
2149 // sched, kmp_uint64 grainsize, void *task_dup);
2150 llvm::Type *TypeParams[] = {getIdentTyPointerTy(),
2151 CGM.IntTy,
2152 CGM.VoidPtrTy,
2153 CGM.IntTy,
2154 CGM.Int64Ty->getPointerTo(),
2155 CGM.Int64Ty->getPointerTo(),
2156 CGM.Int64Ty,
2157 CGM.IntTy,
2158 CGM.IntTy,
2159 CGM.Int64Ty,
2160 CGM.VoidPtrTy};
2161 auto *FnTy =
2162 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2163 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_taskloop");
2164 break;
2165 }
2166 case OMPRTL__kmpc_doacross_init: {
2167 // Build void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid, kmp_int32
2168 // num_dims, struct kmp_dim *dims);
2169 llvm::Type *TypeParams[] = {getIdentTyPointerTy(),
2170 CGM.Int32Ty,
2171 CGM.Int32Ty,
2172 CGM.VoidPtrTy};
2173 auto *FnTy =
2174 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2175 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_init");
2176 break;
2177 }
2178 case OMPRTL__kmpc_doacross_fini: {
2179 // Build void __kmpc_doacross_fini(ident_t *loc, kmp_int32 gtid);
2180 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
2181 auto *FnTy =
2182 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2183 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_fini");
2184 break;
2185 }
2186 case OMPRTL__kmpc_doacross_post: {
2187 // Build void __kmpc_doacross_post(ident_t *loc, kmp_int32 gtid, kmp_int64
2188 // *vec);
2189 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2190 CGM.Int64Ty->getPointerTo()};
2191 auto *FnTy =
2192 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2193 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_post");
2194 break;
2195 }
2196 case OMPRTL__kmpc_doacross_wait: {
2197 // Build void __kmpc_doacross_wait(ident_t *loc, kmp_int32 gtid, kmp_int64
2198 // *vec);
2199 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2200 CGM.Int64Ty->getPointerTo()};
2201 auto *FnTy =
2202 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2203 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_wait");
2204 break;
2205 }
2206 case OMPRTL__kmpc_task_reduction_init: {
2207 // Build void *__kmpc_task_reduction_init(int gtid, int num_data, void
2208 // *data);
2209 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.IntTy, CGM.VoidPtrTy};
2210 auto *FnTy =
2211 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
2212 RTLFn =
2213 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_task_reduction_init");
2214 break;
2215 }
2216 case OMPRTL__kmpc_task_reduction_get_th_data: {
2217 // Build void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
2218 // *d);
2219 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.VoidPtrTy, CGM.VoidPtrTy};
2220 auto *FnTy =
2221 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
2222 RTLFn = CGM.CreateRuntimeFunction(
2223 FnTy, /*Name=*/"__kmpc_task_reduction_get_th_data");
2224 break;
2225 }
2226 case OMPRTL__kmpc_alloc: {
2227 // Build to void *__kmpc_alloc(int gtid, size_t sz, omp_allocator_handle_t
2228 // al); omp_allocator_handle_t type is void *.
2229 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.SizeTy, CGM.VoidPtrTy};
2230 auto *FnTy =
2231 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
2232 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_alloc");
2233 break;
2234 }
2235 case OMPRTL__kmpc_free: {
2236 // Build to void __kmpc_free(int gtid, void *ptr, omp_allocator_handle_t
2237 // al); omp_allocator_handle_t type is void *.
2238 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.VoidPtrTy, CGM.VoidPtrTy};
2239 auto *FnTy =
2240 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2241 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_free");
2242 break;
2243 }
2244 case OMPRTL__kmpc_push_target_tripcount: {
2245 // Build void __kmpc_push_target_tripcount(int64_t device_id, kmp_uint64
2246 // size);
2247 llvm::Type *TypeParams[] = {CGM.Int64Ty, CGM.Int64Ty};
2248 llvm::FunctionType *FnTy =
2249 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2250 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_target_tripcount");
2251 break;
2252 }
2253 case OMPRTL__tgt_target: {
2254 // Build int32_t __tgt_target(int64_t device_id, void *host_ptr, int32_t
2255 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
2256 // *arg_types);
2257 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2258 CGM.VoidPtrTy,
2259 CGM.Int32Ty,
2260 CGM.VoidPtrPtrTy,
2261 CGM.VoidPtrPtrTy,
2262 CGM.SizeTy->getPointerTo(),
2263 CGM.Int64Ty->getPointerTo()};
2264 auto *FnTy =
2265 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2266 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target");
2267 break;
2268 }
2269 case OMPRTL__tgt_target_nowait: {
2270 // Build int32_t __tgt_target_nowait(int64_t device_id, void *host_ptr,
2271 // int32_t arg_num, void** args_base, void **args, size_t *arg_sizes,
2272 // int64_t *arg_types);
2273 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2274 CGM.VoidPtrTy,
2275 CGM.Int32Ty,
2276 CGM.VoidPtrPtrTy,
2277 CGM.VoidPtrPtrTy,
2278 CGM.SizeTy->getPointerTo(),
2279 CGM.Int64Ty->getPointerTo()};
2280 auto *FnTy =
2281 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2282 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_nowait");
2283 break;
2284 }
2285 case OMPRTL__tgt_target_teams: {
2286 // Build int32_t __tgt_target_teams(int64_t device_id, void *host_ptr,
2287 // int32_t arg_num, void** args_base, void **args, size_t *arg_sizes,
2288 // int64_t *arg_types, int32_t num_teams, int32_t thread_limit);
2289 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2290 CGM.VoidPtrTy,
2291 CGM.Int32Ty,
2292 CGM.VoidPtrPtrTy,
2293 CGM.VoidPtrPtrTy,
2294 CGM.SizeTy->getPointerTo(),
2295 CGM.Int64Ty->getPointerTo(),
2296 CGM.Int32Ty,
2297 CGM.Int32Ty};
2298 auto *FnTy =
2299 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2300 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_teams");
2301 break;
2302 }
2303 case OMPRTL__tgt_target_teams_nowait: {
2304 // Build int32_t __tgt_target_teams_nowait(int64_t device_id, void
2305 // *host_ptr, int32_t arg_num, void** args_base, void **args, size_t
2306 // *arg_sizes, int64_t *arg_types, int32_t num_teams, int32_t thread_limit);
2307 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2308 CGM.VoidPtrTy,
2309 CGM.Int32Ty,
2310 CGM.VoidPtrPtrTy,
2311 CGM.VoidPtrPtrTy,
2312 CGM.SizeTy->getPointerTo(),
2313 CGM.Int64Ty->getPointerTo(),
2314 CGM.Int32Ty,
2315 CGM.Int32Ty};
2316 auto *FnTy =
2317 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2318 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_teams_nowait");
2319 break;
2320 }
2321 case OMPRTL__tgt_register_requires: {
2322 // Build void __tgt_register_requires(int64_t flags);
2323 llvm::Type *TypeParams[] = {CGM.Int64Ty};
2324 auto *FnTy =
2325 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2326 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_register_requires");
2327 break;
2328 }
2329 case OMPRTL__tgt_register_lib: {
2330 // Build void __tgt_register_lib(__tgt_bin_desc *desc);
2331 QualType ParamTy =
2332 CGM.getContext().getPointerType(getTgtBinaryDescriptorQTy());
2333 llvm::Type *TypeParams[] = {CGM.getTypes().ConvertTypeForMem(ParamTy)};
2334 auto *FnTy =
2335 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2336 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_register_lib");
2337 break;
2338 }
2339 case OMPRTL__tgt_unregister_lib: {
2340 // Build void __tgt_unregister_lib(__tgt_bin_desc *desc);
2341 QualType ParamTy =
2342 CGM.getContext().getPointerType(getTgtBinaryDescriptorQTy());
2343 llvm::Type *TypeParams[] = {CGM.getTypes().ConvertTypeForMem(ParamTy)};
2344 auto *FnTy =
2345 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2346 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_unregister_lib");
2347 break;
2348 }
2349 case OMPRTL__tgt_target_data_begin: {
2350 // Build void __tgt_target_data_begin(int64_t device_id, int32_t arg_num,
2351 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
2352 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2353 CGM.Int32Ty,
2354 CGM.VoidPtrPtrTy,
2355 CGM.VoidPtrPtrTy,
2356 CGM.SizeTy->getPointerTo(),
2357 CGM.Int64Ty->getPointerTo()};
2358 auto *FnTy =
2359 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2360 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_begin");
2361 break;
2362 }
2363 case OMPRTL__tgt_target_data_begin_nowait: {
2364 // Build void __tgt_target_data_begin_nowait(int64_t device_id, int32_t
2365 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
2366 // *arg_types);
2367 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2368 CGM.Int32Ty,
2369 CGM.VoidPtrPtrTy,
2370 CGM.VoidPtrPtrTy,
2371 CGM.SizeTy->getPointerTo(),
2372 CGM.Int64Ty->getPointerTo()};
2373 auto *FnTy =
2374 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2375 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_begin_nowait");
2376 break;
2377 }
2378 case OMPRTL__tgt_target_data_end: {
2379 // Build void __tgt_target_data_end(int64_t device_id, int32_t arg_num,
2380 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
2381 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2382 CGM.Int32Ty,
2383 CGM.VoidPtrPtrTy,
2384 CGM.VoidPtrPtrTy,
2385 CGM.SizeTy->getPointerTo(),
2386 CGM.Int64Ty->getPointerTo()};
2387 auto *FnTy =
2388 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2389 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_end");
2390 break;
2391 }
2392 case OMPRTL__tgt_target_data_end_nowait: {
2393 // Build void __tgt_target_data_end_nowait(int64_t device_id, int32_t
2394 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
2395 // *arg_types);
2396 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2397 CGM.Int32Ty,
2398 CGM.VoidPtrPtrTy,
2399 CGM.VoidPtrPtrTy,
2400 CGM.SizeTy->getPointerTo(),
2401 CGM.Int64Ty->getPointerTo()};
2402 auto *FnTy =
2403 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2404 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_end_nowait");
2405 break;
2406 }
2407 case OMPRTL__tgt_target_data_update: {
2408 // Build void __tgt_target_data_update(int64_t device_id, int32_t arg_num,
2409 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
2410 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2411 CGM.Int32Ty,
2412 CGM.VoidPtrPtrTy,
2413 CGM.VoidPtrPtrTy,
2414 CGM.SizeTy->getPointerTo(),
2415 CGM.Int64Ty->getPointerTo()};
2416 auto *FnTy =
2417 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2418 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_update");
2419 break;
2420 }
2421 case OMPRTL__tgt_target_data_update_nowait: {
2422 // Build void __tgt_target_data_update_nowait(int64_t device_id, int32_t
2423 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
2424 // *arg_types);
2425 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2426 CGM.Int32Ty,
2427 CGM.VoidPtrPtrTy,
2428 CGM.VoidPtrPtrTy,
2429 CGM.SizeTy->getPointerTo(),
2430 CGM.Int64Ty->getPointerTo()};
2431 auto *FnTy =
2432 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2433 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_update_nowait");
2434 break;
2435 }
2436 }
2437 assert(RTLFn && "Unable to find OpenMP runtime function")((RTLFn && "Unable to find OpenMP runtime function") ?
static_cast<void> (0) : __assert_fail ("RTLFn && \"Unable to find OpenMP runtime function\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2437, __PRETTY_FUNCTION__))
;
2438 return RTLFn;
2439}
2440
2441llvm::FunctionCallee
2442CGOpenMPRuntime::createForStaticInitFunction(unsigned IVSize, bool IVSigned) {
2443 assert((IVSize == 32 || IVSize == 64) &&(((IVSize == 32 || IVSize == 64) && "IV size is not compatible with the omp runtime"
) ? static_cast<void> (0) : __assert_fail ("(IVSize == 32 || IVSize == 64) && \"IV size is not compatible with the omp runtime\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2444, __PRETTY_FUNCTION__))
2444 "IV size is not compatible with the omp runtime")(((IVSize == 32 || IVSize == 64) && "IV size is not compatible with the omp runtime"
) ? static_cast<void> (0) : __assert_fail ("(IVSize == 32 || IVSize == 64) && \"IV size is not compatible with the omp runtime\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2444, __PRETTY_FUNCTION__))
;
2445 StringRef Name = IVSize == 32 ? (IVSigned ? "__kmpc_for_static_init_4"
2446 : "__kmpc_for_static_init_4u")
2447 : (IVSigned ? "__kmpc_for_static_init_8"
2448 : "__kmpc_for_static_init_8u");
2449 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
2450 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
2451 llvm::Type *TypeParams[] = {
2452 getIdentTyPointerTy(), // loc
2453 CGM.Int32Ty, // tid
2454 CGM.Int32Ty, // schedtype
2455 llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
2456 PtrTy, // p_lower
2457 PtrTy, // p_upper
2458 PtrTy, // p_stride
2459 ITy, // incr
2460 ITy // chunk
2461 };
2462 auto *FnTy =
2463 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2464 return CGM.CreateRuntimeFunction(FnTy, Name);
2465}
2466
2467llvm::FunctionCallee
2468CGOpenMPRuntime::createDispatchInitFunction(unsigned IVSize, bool IVSigned) {
2469 assert((IVSize == 32 || IVSize == 64) &&(((IVSize == 32 || IVSize == 64) && "IV size is not compatible with the omp runtime"
) ? static_cast<void> (0) : __assert_fail ("(IVSize == 32 || IVSize == 64) && \"IV size is not compatible with the omp runtime\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2470, __PRETTY_FUNCTION__))
2470 "IV size is not compatible with the omp runtime")(((IVSize == 32 || IVSize == 64) && "IV size is not compatible with the omp runtime"
) ? static_cast<void> (0) : __assert_fail ("(IVSize == 32 || IVSize == 64) && \"IV size is not compatible with the omp runtime\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2470, __PRETTY_FUNCTION__))
;
2471 StringRef Name =
2472 IVSize == 32
2473 ? (IVSigned ? "__kmpc_dispatch_init_4" : "__kmpc_dispatch_init_4u")
2474 : (IVSigned ? "__kmpc_dispatch_init_8" : "__kmpc_dispatch_init_8u");
2475 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
2476 llvm::Type *TypeParams[] = { getIdentTyPointerTy(), // loc
2477 CGM.Int32Ty, // tid
2478 CGM.Int32Ty, // schedtype
2479 ITy, // lower
2480 ITy, // upper
2481 ITy, // stride
2482 ITy // chunk
2483 };
2484 auto *FnTy =
2485 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2486 return CGM.CreateRuntimeFunction(FnTy, Name);
2487}
2488
2489llvm::FunctionCallee
2490CGOpenMPRuntime::createDispatchFiniFunction(unsigned IVSize, bool IVSigned) {
2491 assert((IVSize == 32 || IVSize == 64) &&(((IVSize == 32 || IVSize == 64) && "IV size is not compatible with the omp runtime"
) ? static_cast<void> (0) : __assert_fail ("(IVSize == 32 || IVSize == 64) && \"IV size is not compatible with the omp runtime\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2492, __PRETTY_FUNCTION__))
2492 "IV size is not compatible with the omp runtime")(((IVSize == 32 || IVSize == 64) && "IV size is not compatible with the omp runtime"
) ? static_cast<void> (0) : __assert_fail ("(IVSize == 32 || IVSize == 64) && \"IV size is not compatible with the omp runtime\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2492, __PRETTY_FUNCTION__))
;
2493 StringRef Name =
2494 IVSize == 32
2495 ? (IVSigned ? "__kmpc_dispatch_fini_4" : "__kmpc_dispatch_fini_4u")
2496 : (IVSigned ? "__kmpc_dispatch_fini_8" : "__kmpc_dispatch_fini_8u");
2497 llvm::Type *TypeParams[] = {
2498 getIdentTyPointerTy(), // loc
2499 CGM.Int32Ty, // tid
2500 };
2501 auto *FnTy =
2502 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2503 return CGM.CreateRuntimeFunction(FnTy, Name);
2504}
2505
2506llvm::FunctionCallee
2507CGOpenMPRuntime::createDispatchNextFunction(unsigned IVSize, bool IVSigned) {
2508 assert((IVSize == 32 || IVSize == 64) &&(((IVSize == 32 || IVSize == 64) && "IV size is not compatible with the omp runtime"
) ? static_cast<void> (0) : __assert_fail ("(IVSize == 32 || IVSize == 64) && \"IV size is not compatible with the omp runtime\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2509, __PRETTY_FUNCTION__))
2509 "IV size is not compatible with the omp runtime")(((IVSize == 32 || IVSize == 64) && "IV size is not compatible with the omp runtime"
) ? static_cast<void> (0) : __assert_fail ("(IVSize == 32 || IVSize == 64) && \"IV size is not compatible with the omp runtime\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2509, __PRETTY_FUNCTION__))
;
2510 StringRef Name =
2511 IVSize == 32
2512 ? (IVSigned ? "__kmpc_dispatch_next_4" : "__kmpc_dispatch_next_4u")
2513 : (IVSigned ? "__kmpc_dispatch_next_8" : "__kmpc_dispatch_next_8u");
2514 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
2515 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
2516 llvm::Type *TypeParams[] = {
2517 getIdentTyPointerTy(), // loc
2518 CGM.Int32Ty, // tid
2519 llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
2520 PtrTy, // p_lower
2521 PtrTy, // p_upper
2522 PtrTy // p_stride
2523 };
2524 auto *FnTy =
2525 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2526 return CGM.CreateRuntimeFunction(FnTy, Name);
2527}
2528
2529Address CGOpenMPRuntime::getAddrOfDeclareTargetLink(const VarDecl *VD) {
2530 if (CGM.getLangOpts().OpenMPSimd)
2531 return Address::invalid();
2532 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
2533 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2534 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
2535 SmallString<64> PtrName;
2536 {
2537 llvm::raw_svector_ostream OS(PtrName);
2538 OS << CGM.getMangledName(GlobalDecl(VD)) << "_decl_tgt_link_ptr";
2539 }
2540 llvm::Value *Ptr = CGM.getModule().getNamedValue(PtrName);
2541 if (!Ptr) {
2542 QualType PtrTy = CGM.getContext().getPointerType(VD->getType());
2543 Ptr = getOrCreateInternalVariable(CGM.getTypes().ConvertTypeForMem(PtrTy),
2544 PtrName);
2545 if (!CGM.getLangOpts().OpenMPIsDevice) {
2546 auto *GV = cast<llvm::GlobalVariable>(Ptr);
2547 GV->setLinkage(llvm::GlobalValue::ExternalLinkage);
2548 GV->setInitializer(CGM.GetAddrOfGlobal(VD));
2549 }
2550 CGM.addUsedGlobal(cast<llvm::GlobalValue>(Ptr));
2551 registerTargetGlobalVariable(VD, cast<llvm::Constant>(Ptr));
2552 }
2553 return Address(Ptr, CGM.getContext().getDeclAlign(VD));
2554 }
2555 return Address::invalid();
2556}
2557
2558llvm::Constant *
2559CGOpenMPRuntime::getOrCreateThreadPrivateCache(const VarDecl *VD) {
2560 assert(!CGM.getLangOpts().OpenMPUseTLS ||((!CGM.getLangOpts().OpenMPUseTLS || !CGM.getContext().getTargetInfo
().isTLSSupported()) ? static_cast<void> (0) : __assert_fail
("!CGM.getLangOpts().OpenMPUseTLS || !CGM.getContext().getTargetInfo().isTLSSupported()"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2561, __PRETTY_FUNCTION__))
2561 !CGM.getContext().getTargetInfo().isTLSSupported())((!CGM.getLangOpts().OpenMPUseTLS || !CGM.getContext().getTargetInfo
().isTLSSupported()) ? static_cast<void> (0) : __assert_fail
("!CGM.getLangOpts().OpenMPUseTLS || !CGM.getContext().getTargetInfo().isTLSSupported()"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2561, __PRETTY_FUNCTION__))
;
2562 // Lookup the entry, lazily creating it if necessary.
2563 std::string Suffix = getName({"cache", ""});
2564 return getOrCreateInternalVariable(
2565 CGM.Int8PtrPtrTy, Twine(CGM.getMangledName(VD)).concat(Suffix));
2566}
2567
2568Address CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
2569 const VarDecl *VD,
2570 Address VDAddr,
2571 SourceLocation Loc) {
2572 if (CGM.getLangOpts().OpenMPUseTLS &&
2573 CGM.getContext().getTargetInfo().isTLSSupported())
2574 return VDAddr;
2575
2576 llvm::Type *VarTy = VDAddr.getElementType();
2577 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
2578 CGF.Builder.CreatePointerCast(VDAddr.getPointer(),
2579 CGM.Int8PtrTy),
2580 CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)),
2581 getOrCreateThreadPrivateCache(VD)};
2582 return Address(CGF.EmitRuntimeCall(
2583 createRuntimeFunction(OMPRTL__kmpc_threadprivate_cached), Args),
2584 VDAddr.getAlignment());
2585}
2586
2587void CGOpenMPRuntime::emitThreadPrivateVarInit(
2588 CodeGenFunction &CGF, Address VDAddr, llvm::Value *Ctor,
2589 llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc) {
2590 // Call kmp_int32 __kmpc_global_thread_num(&loc) to init OpenMP runtime
2591 // library.
2592 llvm::Value *OMPLoc = emitUpdateLocation(CGF, Loc);
2593 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
2594 OMPLoc);
2595 // Call __kmpc_threadprivate_register(&loc, &var, ctor, cctor/*NULL*/, dtor)
2596 // to register constructor/destructor for variable.
2597 llvm::Value *Args[] = {
2598 OMPLoc, CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.VoidPtrTy),
2599 Ctor, CopyCtor, Dtor};
2600 CGF.EmitRuntimeCall(
2601 createRuntimeFunction(OMPRTL__kmpc_threadprivate_register), Args);
2602}
2603
2604llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
2605 const VarDecl *VD, Address VDAddr, SourceLocation Loc,
2606 bool PerformInit, CodeGenFunction *CGF) {
2607 if (CGM.getLangOpts().OpenMPUseTLS &&
2608 CGM.getContext().getTargetInfo().isTLSSupported())
2609 return nullptr;
2610
2611 VD = VD->getDefinition(CGM.getContext());
2612 if (VD && ThreadPrivateWithDefinition.insert(CGM.getMangledName(VD)).second) {
2613 QualType ASTTy = VD->getType();
2614
2615 llvm::Value *Ctor = nullptr, *CopyCtor = nullptr, *Dtor = nullptr;
2616 const Expr *Init = VD->getAnyInitializer();
2617 if (CGM.getLangOpts().CPlusPlus && PerformInit) {
2618 // Generate function that re-emits the declaration's initializer into the
2619 // threadprivate copy of the variable VD
2620 CodeGenFunction CtorCGF(CGM);
2621 FunctionArgList Args;
2622 ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
2623 /*Id=*/nullptr, CGM.getContext().VoidPtrTy,
2624 ImplicitParamDecl::Other);
2625 Args.push_back(&Dst);
2626
2627 const auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
2628 CGM.getContext().VoidPtrTy, Args);
2629 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
2630 std::string Name = getName({"__kmpc_global_ctor_", ""});
2631 llvm::Function *Fn =
2632 CGM.CreateGlobalInitOrDestructFunction(FTy, Name, FI, Loc);
2633 CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidPtrTy, Fn, FI,
2634 Args, Loc, Loc);
2635 llvm::Value *ArgVal = CtorCGF.EmitLoadOfScalar(
2636 CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
2637 CGM.getContext().VoidPtrTy, Dst.getLocation());
2638 Address Arg = Address(ArgVal, VDAddr.getAlignment());
2639 Arg = CtorCGF.Builder.CreateElementBitCast(
2640 Arg, CtorCGF.ConvertTypeForMem(ASTTy));
2641 CtorCGF.EmitAnyExprToMem(Init, Arg, Init->getType().getQualifiers(),
2642 /*IsInitializer=*/true);
2643 ArgVal = CtorCGF.EmitLoadOfScalar(
2644 CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
2645 CGM.getContext().VoidPtrTy, Dst.getLocation());
2646 CtorCGF.Builder.CreateStore(ArgVal, CtorCGF.ReturnValue);
2647 CtorCGF.FinishFunction();
2648 Ctor = Fn;
2649 }
2650 if (VD->getType().isDestructedType() != QualType::DK_none) {
2651 // Generate function that emits destructor call for the threadprivate copy
2652 // of the variable VD
2653 CodeGenFunction DtorCGF(CGM);
2654 FunctionArgList Args;
2655 ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
2656 /*Id=*/nullptr, CGM.getContext().VoidPtrTy,
2657 ImplicitParamDecl::Other);
2658 Args.push_back(&Dst);
2659
2660 const auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
2661 CGM.getContext().VoidTy, Args);
2662 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
2663 std::string Name = getName({"__kmpc_global_dtor_", ""});
2664 llvm::Function *Fn =
2665 CGM.CreateGlobalInitOrDestructFunction(FTy, Name, FI, Loc);
2666 auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
2667 DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI, Args,
2668 Loc, Loc);
2669 // Create a scope with an artificial location for the body of this function.
2670 auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
2671 llvm::Value *ArgVal = DtorCGF.EmitLoadOfScalar(
2672 DtorCGF.GetAddrOfLocalVar(&Dst),
2673 /*Volatile=*/false, CGM.getContext().VoidPtrTy, Dst.getLocation());
2674 DtorCGF.emitDestroy(Address(ArgVal, VDAddr.getAlignment()), ASTTy,
2675 DtorCGF.getDestroyer(ASTTy.isDestructedType()),
2676 DtorCGF.needsEHCleanup(ASTTy.isDestructedType()));
2677 DtorCGF.FinishFunction();
2678 Dtor = Fn;
2679 }
2680 // Do not emit init function if it is not required.
2681 if (!Ctor && !Dtor)
2682 return nullptr;
2683
2684 llvm::Type *CopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
2685 auto *CopyCtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CopyCtorTyArgs,
2686 /*isVarArg=*/false)
2687 ->getPointerTo();
2688 // Copying constructor for the threadprivate variable.
2689 // Must be NULL - reserved by runtime, but currently it requires that this
2690 // parameter is always NULL. Otherwise it fires assertion.
2691 CopyCtor = llvm::Constant::getNullValue(CopyCtorTy);
2692 if (Ctor == nullptr) {
2693 auto *CtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
2694 /*isVarArg=*/false)
2695 ->getPointerTo();
2696 Ctor = llvm::Constant::getNullValue(CtorTy);
2697 }
2698 if (Dtor == nullptr) {
2699 auto *DtorTy = llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy,
2700 /*isVarArg=*/false)
2701 ->getPointerTo();
2702 Dtor = llvm::Constant::getNullValue(DtorTy);
2703 }
2704 if (!CGF) {
2705 auto *InitFunctionTy =
2706 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg*/ false);
2707 std::string Name = getName({"__omp_threadprivate_init_", ""});
2708 llvm::Function *InitFunction = CGM.CreateGlobalInitOrDestructFunction(
2709 InitFunctionTy, Name, CGM.getTypes().arrangeNullaryFunction());
2710 CodeGenFunction InitCGF(CGM);
2711 FunctionArgList ArgList;
2712 InitCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, InitFunction,
2713 CGM.getTypes().arrangeNullaryFunction(), ArgList,
2714 Loc, Loc);
2715 emitThreadPrivateVarInit(InitCGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
2716 InitCGF.FinishFunction();
2717 return InitFunction;
2718 }
2719 emitThreadPrivateVarInit(*CGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
2720 }
2721 return nullptr;
2722}
2723
2724/// Obtain information that uniquely identifies a target entry. This
2725/// consists of the file and device IDs as well as line number associated with
2726/// the relevant entry source location.
2727static void getTargetEntryUniqueInfo(ASTContext &C, SourceLocation Loc,
2728 unsigned &DeviceID, unsigned &FileID,
2729 unsigned &LineNum) {
2730 SourceManager &SM = C.getSourceManager();
2731
2732 // The loc should be always valid and have a file ID (the user cannot use
2733 // #pragma directives in macros)
2734
2735 assert(Loc.isValid() && "Source location is expected to be always valid.")((Loc.isValid() && "Source location is expected to be always valid."
) ? static_cast<void> (0) : __assert_fail ("Loc.isValid() && \"Source location is expected to be always valid.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2735, __PRETTY_FUNCTION__))
;
2736
2737 PresumedLoc PLoc = SM.getPresumedLoc(Loc);
2738 assert(PLoc.isValid() && "Source location is expected to be always valid.")((PLoc.isValid() && "Source location is expected to be always valid."
) ? static_cast<void> (0) : __assert_fail ("PLoc.isValid() && \"Source location is expected to be always valid.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 2738, __PRETTY_FUNCTION__))
;
2739
2740 llvm::sys::fs::UniqueID ID;
2741 if (auto EC = llvm::sys::fs::getUniqueID(PLoc.getFilename(), ID))
2742 SM.getDiagnostics().Report(diag::err_cannot_open_file)
2743 << PLoc.getFilename() << EC.message();
2744
2745 DeviceID = ID.getDevice();
2746 FileID = ID.getFile();
2747 LineNum = PLoc.getLine();
2748}
2749
2750bool CGOpenMPRuntime::emitDeclareTargetVarDefinition(const VarDecl *VD,
2751 llvm::GlobalVariable *Addr,
2752 bool PerformInit) {
2753 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
2754 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2755 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link)
2756 return CGM.getLangOpts().OpenMPIsDevice;
2757 VD = VD->getDefinition(CGM.getContext());
2758 if (VD && !DeclareTargetWithDefinition.insert(CGM.getMangledName(VD)).second)
2759 return CGM.getLangOpts().OpenMPIsDevice;
2760
2761 QualType ASTTy = VD->getType();
2762
2763 SourceLocation Loc = VD->getCanonicalDecl()->getBeginLoc();
2764 // Produce the unique prefix to identify the new target regions. We use
2765 // the source location of the variable declaration which we know to not
2766 // conflict with any target region.
2767 unsigned DeviceID;
2768 unsigned FileID;
2769 unsigned Line;
2770 getTargetEntryUniqueInfo(CGM.getContext(), Loc, DeviceID, FileID, Line);
2771 SmallString<128> Buffer, Out;
2772 {
2773 llvm::raw_svector_ostream OS(Buffer);
2774 OS << "__omp_offloading_" << llvm::format("_%x", DeviceID)
2775 << llvm::format("_%x_", FileID) << VD->getName() << "_l" << Line;
2776 }
2777
2778 const Expr *Init = VD->getAnyInitializer();
2779 if (CGM.getLangOpts().CPlusPlus && PerformInit) {
2780 llvm::Constant *Ctor;
2781 llvm::Constant *ID;
2782 if (CGM.getLangOpts().OpenMPIsDevice) {
2783 // Generate function that re-emits the declaration's initializer into
2784 // the threadprivate copy of the variable VD
2785 CodeGenFunction CtorCGF(CGM);
2786
2787 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
2788 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
2789 llvm::Function *Fn = CGM.CreateGlobalInitOrDestructFunction(
2790 FTy, Twine(Buffer, "_ctor"), FI, Loc);
2791 auto NL = ApplyDebugLocation::CreateEmpty(CtorCGF);
2792 CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI,
2793 FunctionArgList(), Loc, Loc);
2794 auto AL = ApplyDebugLocation::CreateArtificial(CtorCGF);
2795 CtorCGF.EmitAnyExprToMem(Init,
2796 Address(Addr, CGM.getContext().getDeclAlign(VD)),
2797 Init->getType().getQualifiers(),
2798 /*IsInitializer=*/true);
2799 CtorCGF.FinishFunction();
2800 Ctor = Fn;
2801 ID = llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
2802 CGM.addUsedGlobal(cast<llvm::GlobalValue>(Ctor));
2803 } else {
2804 Ctor = new llvm::GlobalVariable(
2805 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
2806 llvm::GlobalValue::PrivateLinkage,
2807 llvm::Constant::getNullValue(CGM.Int8Ty), Twine(Buffer, "_ctor"));
2808 ID = Ctor;
2809 }
2810
2811 // Register the information for the entry associated with the constructor.
2812 Out.clear();
2813 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
2814 DeviceID, FileID, Twine(Buffer, "_ctor").toStringRef(Out), Line, Ctor,
2815 ID, OffloadEntriesInfoManagerTy::OMPTargetRegionEntryCtor);
2816 }
2817 if (VD->getType().isDestructedType() != QualType::DK_none) {
2818 llvm::Constant *Dtor;
2819 llvm::Constant *ID;
2820 if (CGM.getLangOpts().OpenMPIsDevice) {
2821 // Generate function that emits destructor call for the threadprivate
2822 // copy of the variable VD
2823 CodeGenFunction DtorCGF(CGM);
2824
2825 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
2826 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
2827 llvm::Function *Fn = CGM.CreateGlobalInitOrDestructFunction(
2828 FTy, Twine(Buffer, "_dtor"), FI, Loc);
2829 auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
2830 DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI,
2831 FunctionArgList(), Loc, Loc);
2832 // Create a scope with an artificial location for the body of this
2833 // function.
2834 auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
2835 DtorCGF.emitDestroy(Address(Addr, CGM.getContext().getDeclAlign(VD)),
2836 ASTTy, DtorCGF.getDestroyer(ASTTy.isDestructedType()),
2837 DtorCGF.needsEHCleanup(ASTTy.isDestructedType()));
2838 DtorCGF.FinishFunction();
2839 Dtor = Fn;
2840 ID = llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
2841 CGM.addUsedGlobal(cast<llvm::GlobalValue>(Dtor));
2842 } else {
2843 Dtor = new llvm::GlobalVariable(
2844 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
2845 llvm::GlobalValue::PrivateLinkage,
2846 llvm::Constant::getNullValue(CGM.Int8Ty), Twine(Buffer, "_dtor"));
2847 ID = Dtor;
2848 }
2849 // Register the information for the entry associated with the destructor.
2850 Out.clear();
2851 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
2852 DeviceID, FileID, Twine(Buffer, "_dtor").toStringRef(Out), Line, Dtor,
2853 ID, OffloadEntriesInfoManagerTy::OMPTargetRegionEntryDtor);
2854 }
2855 return CGM.getLangOpts().OpenMPIsDevice;
2856}
2857
2858Address CGOpenMPRuntime::getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF,
2859 QualType VarType,
2860 StringRef Name) {
2861 std::string Suffix = getName({"artificial", ""});
2862 std::string CacheSuffix = getName({"cache", ""});
2863 llvm::Type *VarLVType = CGF.ConvertTypeForMem(VarType);
2864 llvm::Value *GAddr =
2865 getOrCreateInternalVariable(VarLVType, Twine(Name).concat(Suffix));
2866 llvm::Value *Args[] = {
2867 emitUpdateLocation(CGF, SourceLocation()),
2868 getThreadID(CGF, SourceLocation()),
2869 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(GAddr, CGM.VoidPtrTy),
2870 CGF.Builder.CreateIntCast(CGF.getTypeSize(VarType), CGM.SizeTy,
2871 /*IsSigned=*/false),
2872 getOrCreateInternalVariable(
2873 CGM.VoidPtrPtrTy, Twine(Name).concat(Suffix).concat(CacheSuffix))};
2874 return Address(
2875 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2876 CGF.EmitRuntimeCall(
2877 createRuntimeFunction(OMPRTL__kmpc_threadprivate_cached), Args),
2878 VarLVType->getPointerTo(/*AddrSpace=*/0)),
2879 CGM.getPointerAlign());
2880}
2881
2882void CGOpenMPRuntime::emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
2883 const RegionCodeGenTy &ThenGen,
2884 const RegionCodeGenTy &ElseGen) {
2885 CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
2886
2887 // If the condition constant folds and can be elided, try to avoid emitting
2888 // the condition and the dead arm of the if/else.
2889 bool CondConstant;
2890 if (CGF.ConstantFoldsToSimpleInteger(Cond, CondConstant)) {
2891 if (CondConstant)
2892 ThenGen(CGF);
2893 else
2894 ElseGen(CGF);
2895 return;
2896 }
2897
2898 // Otherwise, the condition did not fold, or we couldn't elide it. Just
2899 // emit the conditional branch.
2900 llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("omp_if.then");
2901 llvm::BasicBlock *ElseBlock = CGF.createBasicBlock("omp_if.else");
2902 llvm::BasicBlock *ContBlock = CGF.createBasicBlock("omp_if.end");
2903 CGF.EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, /*TrueCount=*/0);
2904
2905 // Emit the 'then' code.
2906 CGF.EmitBlock(ThenBlock);
2907 ThenGen(CGF);
2908 CGF.EmitBranch(ContBlock);
2909 // Emit the 'else' code if present.
2910 // There is no need to emit line number for unconditional branch.
2911 (void)ApplyDebugLocation::CreateEmpty(CGF);
2912 CGF.EmitBlock(ElseBlock);
2913 ElseGen(CGF);
2914 // There is no need to emit line number for unconditional branch.
2915 (void)ApplyDebugLocation::CreateEmpty(CGF);
2916 CGF.EmitBranch(ContBlock);
2917 // Emit the continuation block for code after the if.
2918 CGF.EmitBlock(ContBlock, /*IsFinished=*/true);
2919}
2920
2921void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
2922 llvm::Function *OutlinedFn,
2923 ArrayRef<llvm::Value *> CapturedVars,
2924 const Expr *IfCond) {
2925 if (!CGF.HaveInsertPoint())
2926 return;
2927 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
2928 auto &&ThenGen = [OutlinedFn, CapturedVars, RTLoc](CodeGenFunction &CGF,
2929 PrePostActionTy &) {
2930 // Build call __kmpc_fork_call(loc, n, microtask, var1, .., varn);
2931 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
2932 llvm::Value *Args[] = {
2933 RTLoc,
2934 CGF.Builder.getInt32(CapturedVars.size()), // Number of captured vars
2935 CGF.Builder.CreateBitCast(OutlinedFn, RT.getKmpc_MicroPointerTy())};
2936 llvm::SmallVector<llvm::Value *, 16> RealArgs;
2937 RealArgs.append(std::begin(Args), std::end(Args));
2938 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
2939
2940 llvm::FunctionCallee RTLFn =
2941 RT.createRuntimeFunction(OMPRTL__kmpc_fork_call);
2942 CGF.EmitRuntimeCall(RTLFn, RealArgs);
2943 };
2944 auto &&ElseGen = [OutlinedFn, CapturedVars, RTLoc, Loc](CodeGenFunction &CGF,
2945 PrePostActionTy &) {
2946 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
2947 llvm::Value *ThreadID = RT.getThreadID(CGF, Loc);
2948 // Build calls:
2949 // __kmpc_serialized_parallel(&Loc, GTid);
2950 llvm::Value *Args[] = {RTLoc, ThreadID};
2951 CGF.EmitRuntimeCall(
2952 RT.createRuntimeFunction(OMPRTL__kmpc_serialized_parallel), Args);
2953
2954 // OutlinedFn(&GTid, &zero, CapturedStruct);
2955 Address ZeroAddr = CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty,
2956 /*Name*/ ".zero.addr");
2957 CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32(/*C*/ 0));
2958 llvm::SmallVector<llvm::Value *, 16> OutlinedFnArgs;
2959 // ThreadId for serialized parallels is 0.
2960 OutlinedFnArgs.push_back(ZeroAddr.getPointer());
2961 OutlinedFnArgs.push_back(ZeroAddr.getPointer());
2962 OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
2963 RT.emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs);
2964
2965 // __kmpc_end_serialized_parallel(&Loc, GTid);
2966 llvm::Value *EndArgs[] = {RT.emitUpdateLocation(CGF, Loc), ThreadID};
2967 CGF.EmitRuntimeCall(
2968 RT.createRuntimeFunction(OMPRTL__kmpc_end_serialized_parallel),
2969 EndArgs);
2970 };
2971 if (IfCond) {
2972 emitOMPIfClause(CGF, IfCond, ThenGen, ElseGen);
2973 } else {
2974 RegionCodeGenTy ThenRCG(ThenGen);
2975 ThenRCG(CGF);
2976 }
2977}
2978
2979// If we're inside an (outlined) parallel region, use the region info's
2980// thread-ID variable (it is passed in a first argument of the outlined function
2981// as "kmp_int32 *gtid"). Otherwise, if we're not inside parallel region, but in
2982// regular serial code region, get thread ID by calling kmp_int32
2983// kmpc_global_thread_num(ident_t *loc), stash this thread ID in a temporary and
2984// return the address of that temp.
2985Address CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF,
2986 SourceLocation Loc) {
2987 if (auto *OMPRegionInfo =
2988 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
2989 if (OMPRegionInfo->getThreadIDVariable())
2990 return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
2991
2992 llvm::Value *ThreadID = getThreadID(CGF, Loc);
2993 QualType Int32Ty =
2994 CGF.getContext().getIntTypeForBitwidth(/*DestWidth*/ 32, /*Signed*/ true);
2995 Address ThreadIDTemp = CGF.CreateMemTemp(Int32Ty, /*Name*/ ".threadid_temp.");
2996 CGF.EmitStoreOfScalar(ThreadID,
2997 CGF.MakeAddrLValue(ThreadIDTemp, Int32Ty));
2998
2999 return ThreadIDTemp;
3000}
3001
3002llvm::Constant *CGOpenMPRuntime::getOrCreateInternalVariable(
3003 llvm::Type *Ty, const llvm::Twine &Name, unsigned AddressSpace) {
3004 SmallString<256> Buffer;
3005 llvm::raw_svector_ostream Out(Buffer);
3006 Out << Name;
3007 StringRef RuntimeName = Out.str();
3008 auto &Elem = *InternalVars.try_emplace(RuntimeName, nullptr).first;
3009 if (Elem.second) {
3010 assert(Elem.second->getType()->getPointerElementType() == Ty &&((Elem.second->getType()->getPointerElementType() == Ty
&& "OMP internal variable has different type than requested"
) ? static_cast<void> (0) : __assert_fail ("Elem.second->getType()->getPointerElementType() == Ty && \"OMP internal variable has different type than requested\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3011, __PRETTY_FUNCTION__))
3011 "OMP internal variable has different type than requested")((Elem.second->getType()->getPointerElementType() == Ty
&& "OMP internal variable has different type than requested"
) ? static_cast<void> (0) : __assert_fail ("Elem.second->getType()->getPointerElementType() == Ty && \"OMP internal variable has different type than requested\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3011, __PRETTY_FUNCTION__))
;
3012 return &*Elem.second;
3013 }
3014
3015 return Elem.second = new llvm::GlobalVariable(
3016 CGM.getModule(), Ty, /*IsConstant*/ false,
3017 llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
3018 Elem.first(), /*InsertBefore=*/nullptr,
3019 llvm::GlobalValue::NotThreadLocal, AddressSpace);
3020}
3021
3022llvm::Value *CGOpenMPRuntime::getCriticalRegionLock(StringRef CriticalName) {
3023 std::string Prefix = Twine("gomp_critical_user_", CriticalName).str();
3024 std::string Name = getName({Prefix, "var"});
3025 return getOrCreateInternalVariable(KmpCriticalNameTy, Name);
3026}
3027
3028namespace {
3029/// Common pre(post)-action for different OpenMP constructs.
3030class CommonActionTy final : public PrePostActionTy {
3031 llvm::FunctionCallee EnterCallee;
3032 ArrayRef<llvm::Value *> EnterArgs;
3033 llvm::FunctionCallee ExitCallee;
3034 ArrayRef<llvm::Value *> ExitArgs;
3035 bool Conditional;
3036 llvm::BasicBlock *ContBlock = nullptr;
3037
3038public:
3039 CommonActionTy(llvm::FunctionCallee EnterCallee,
3040 ArrayRef<llvm::Value *> EnterArgs,
3041 llvm::FunctionCallee ExitCallee,
3042 ArrayRef<llvm::Value *> ExitArgs, bool Conditional = false)
3043 : EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
3044 ExitArgs(ExitArgs), Conditional(Conditional) {}
3045 void Enter(CodeGenFunction &CGF) override {
3046 llvm::Value *EnterRes = CGF.EmitRuntimeCall(EnterCallee, EnterArgs);
3047 if (Conditional) {
3048 llvm::Value *CallBool = CGF.Builder.CreateIsNotNull(EnterRes);
3049 auto *ThenBlock = CGF.createBasicBlock("omp_if.then");
3050 ContBlock = CGF.createBasicBlock("omp_if.end");
3051 // Generate the branch (If-stmt)
3052 CGF.Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
3053 CGF.EmitBlock(ThenBlock);
3054 }
3055 }
3056 void Done(CodeGenFunction &CGF) {
3057 // Emit the rest of blocks/branches
3058 CGF.EmitBranch(ContBlock);
3059 CGF.EmitBlock(ContBlock, true);
3060 }
3061 void Exit(CodeGenFunction &CGF) override {
3062 CGF.EmitRuntimeCall(ExitCallee, ExitArgs);
3063 }
3064};
3065} // anonymous namespace
3066
3067void CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF,
3068 StringRef CriticalName,
3069 const RegionCodeGenTy &CriticalOpGen,
3070 SourceLocation Loc, const Expr *Hint) {
3071 // __kmpc_critical[_with_hint](ident_t *, gtid, Lock[, hint]);
3072 // CriticalOpGen();
3073 // __kmpc_end_critical(ident_t *, gtid, Lock);
3074 // Prepare arguments and build a call to __kmpc_critical
3075 if (!CGF.HaveInsertPoint())
3076 return;
3077 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
3078 getCriticalRegionLock(CriticalName)};
3079 llvm::SmallVector<llvm::Value *, 4> EnterArgs(std::begin(Args),
3080 std::end(Args));
3081 if (Hint) {
3082 EnterArgs.push_back(CGF.Builder.CreateIntCast(
3083 CGF.EmitScalarExpr(Hint), CGM.IntPtrTy, /*isSigned=*/false));
3084 }
3085 CommonActionTy Action(
3086 createRuntimeFunction(Hint ? OMPRTL__kmpc_critical_with_hint
3087 : OMPRTL__kmpc_critical),
3088 EnterArgs, createRuntimeFunction(OMPRTL__kmpc_end_critical), Args);
3089 CriticalOpGen.setAction(Action);
3090 emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen);
3091}
3092
3093void CGOpenMPRuntime::emitMasterRegion(CodeGenFunction &CGF,
3094 const RegionCodeGenTy &MasterOpGen,
3095 SourceLocation Loc) {
3096 if (!CGF.HaveInsertPoint())
3097 return;
3098 // if(__kmpc_master(ident_t *, gtid)) {
3099 // MasterOpGen();
3100 // __kmpc_end_master(ident_t *, gtid);
3101 // }
3102 // Prepare arguments and build a call to __kmpc_master
3103 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
3104 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_master), Args,
3105 createRuntimeFunction(OMPRTL__kmpc_end_master), Args,
3106 /*Conditional=*/true);
3107 MasterOpGen.setAction(Action);
3108 emitInlinedDirective(CGF, OMPD_master, MasterOpGen);
3109 Action.Done(CGF);
3110}
3111
3112void CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
3113 SourceLocation Loc) {
3114 if (!CGF.HaveInsertPoint())
3115 return;
3116 // Build call __kmpc_omp_taskyield(loc, thread_id, 0);
3117 llvm::Value *Args[] = {
3118 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
3119 llvm::ConstantInt::get(CGM.IntTy, /*V=*/0, /*isSigned=*/true)};
3120 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskyield), Args);
3121 if (auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
3122 Region->emitUntiedSwitch(CGF);
3123}
3124
3125void CGOpenMPRuntime::emitTaskgroupRegion(CodeGenFunction &CGF,
3126 const RegionCodeGenTy &TaskgroupOpGen,
3127 SourceLocation Loc) {
3128 if (!CGF.HaveInsertPoint())
3129 return;
3130 // __kmpc_taskgroup(ident_t *, gtid);
3131 // TaskgroupOpGen();
3132 // __kmpc_end_taskgroup(ident_t *, gtid);
3133 // Prepare arguments and build a call to __kmpc_taskgroup
3134 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
3135 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_taskgroup), Args,
3136 createRuntimeFunction(OMPRTL__kmpc_end_taskgroup),
3137 Args);
3138 TaskgroupOpGen.setAction(Action);
3139 emitInlinedDirective(CGF, OMPD_taskgroup, TaskgroupOpGen);
3140}
3141
3142/// Given an array of pointers to variables, project the address of a
3143/// given variable.
3144static Address emitAddrOfVarFromArray(CodeGenFunction &CGF, Address Array,
3145 unsigned Index, const VarDecl *Var) {
3146 // Pull out the pointer to the variable.
3147 Address PtrAddr = CGF.Builder.CreateConstArrayGEP(Array, Index);
3148 llvm::Value *Ptr = CGF.Builder.CreateLoad(PtrAddr);
3149
3150 Address Addr = Address(Ptr, CGF.getContext().getDeclAlign(Var));
3151 Addr = CGF.Builder.CreateElementBitCast(
3152 Addr, CGF.ConvertTypeForMem(Var->getType()));
3153 return Addr;
3154}
3155
3156static llvm::Value *emitCopyprivateCopyFunction(
3157 CodeGenModule &CGM, llvm::Type *ArgsType,
3158 ArrayRef<const Expr *> CopyprivateVars, ArrayRef<const Expr *> DestExprs,
3159 ArrayRef<const Expr *> SrcExprs, ArrayRef<const Expr *> AssignmentOps,
3160 SourceLocation Loc) {
3161 ASTContext &C = CGM.getContext();
3162 // void copy_func(void *LHSArg, void *RHSArg);
3163 FunctionArgList Args;
3164 ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
3165 ImplicitParamDecl::Other);
3166 ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
3167 ImplicitParamDecl::Other);
3168 Args.push_back(&LHSArg);
3169 Args.push_back(&RHSArg);
3170 const auto &CGFI =
3171 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
3172 std::string Name =
3173 CGM.getOpenMPRuntime().getName({"omp", "copyprivate", "copy_func"});
3174 auto *Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(CGFI),
3175 llvm::GlobalValue::InternalLinkage, Name,
3176 &CGM.getModule());
3177 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
3178 Fn->setDoesNotRecurse();
3179 CodeGenFunction CGF(CGM);
3180 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
3181 // Dest = (void*[n])(LHSArg);
3182 // Src = (void*[n])(RHSArg);
3183 Address LHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3184 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&LHSArg)),
3185 ArgsType), CGF.getPointerAlign());
3186 Address RHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3187 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&RHSArg)),
3188 ArgsType), CGF.getPointerAlign());
3189 // *(Type0*)Dst[0] = *(Type0*)Src[0];
3190 // *(Type1*)Dst[1] = *(Type1*)Src[1];
3191 // ...
3192 // *(Typen*)Dst[n] = *(Typen*)Src[n];
3193 for (unsigned I = 0, E = AssignmentOps.size(); I < E; ++I) {
3194 const auto *DestVar =
3195 cast<VarDecl>(cast<DeclRefExpr>(DestExprs[I])->getDecl());
3196 Address DestAddr = emitAddrOfVarFromArray(CGF, LHS, I, DestVar);
3197
3198 const auto *SrcVar =
3199 cast<VarDecl>(cast<DeclRefExpr>(SrcExprs[I])->getDecl());
3200 Address SrcAddr = emitAddrOfVarFromArray(CGF, RHS, I, SrcVar);
3201
3202 const auto *VD = cast<DeclRefExpr>(CopyprivateVars[I])->getDecl();
3203 QualType Type = VD->getType();
3204 CGF.EmitOMPCopy(Type, DestAddr, SrcAddr, DestVar, SrcVar, AssignmentOps[I]);
3205 }
3206 CGF.FinishFunction();
3207 return Fn;
3208}
3209
3210void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF,
3211 const RegionCodeGenTy &SingleOpGen,
3212 SourceLocation Loc,
3213 ArrayRef<const Expr *> CopyprivateVars,
3214 ArrayRef<const Expr *> SrcExprs,
3215 ArrayRef<const Expr *> DstExprs,
3216 ArrayRef<const Expr *> AssignmentOps) {
3217 if (!CGF.HaveInsertPoint())
3218 return;
3219 assert(CopyprivateVars.size() == SrcExprs.size() &&((CopyprivateVars.size() == SrcExprs.size() && CopyprivateVars
.size() == DstExprs.size() && CopyprivateVars.size() ==
AssignmentOps.size()) ? static_cast<void> (0) : __assert_fail
("CopyprivateVars.size() == SrcExprs.size() && CopyprivateVars.size() == DstExprs.size() && CopyprivateVars.size() == AssignmentOps.size()"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3221, __PRETTY_FUNCTION__))
3220 CopyprivateVars.size() == DstExprs.size() &&((CopyprivateVars.size() == SrcExprs.size() && CopyprivateVars
.size() == DstExprs.size() && CopyprivateVars.size() ==
AssignmentOps.size()) ? static_cast<void> (0) : __assert_fail
("CopyprivateVars.size() == SrcExprs.size() && CopyprivateVars.size() == DstExprs.size() && CopyprivateVars.size() == AssignmentOps.size()"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3221, __PRETTY_FUNCTION__))
3221 CopyprivateVars.size() == AssignmentOps.size())((CopyprivateVars.size() == SrcExprs.size() && CopyprivateVars
.size() == DstExprs.size() && CopyprivateVars.size() ==
AssignmentOps.size()) ? static_cast<void> (0) : __assert_fail
("CopyprivateVars.size() == SrcExprs.size() && CopyprivateVars.size() == DstExprs.size() && CopyprivateVars.size() == AssignmentOps.size()"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3221, __PRETTY_FUNCTION__))
;
3222 ASTContext &C = CGM.getContext();
3223 // int32 did_it = 0;
3224 // if(__kmpc_single(ident_t *, gtid)) {
3225 // SingleOpGen();
3226 // __kmpc_end_single(ident_t *, gtid);
3227 // did_it = 1;
3228 // }
3229 // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
3230 // <copy_func>, did_it);
3231
3232 Address DidIt = Address::invalid();
3233 if (!CopyprivateVars.empty()) {
3234 // int32 did_it = 0;
3235 QualType KmpInt32Ty =
3236 C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
3237 DidIt = CGF.CreateMemTemp(KmpInt32Ty, ".omp.copyprivate.did_it");
3238 CGF.Builder.CreateStore(CGF.Builder.getInt32(0), DidIt);
3239 }
3240 // Prepare arguments and build a call to __kmpc_single
3241 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
3242 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_single), Args,
3243 createRuntimeFunction(OMPRTL__kmpc_end_single), Args,
3244 /*Conditional=*/true);
3245 SingleOpGen.setAction(Action);
3246 emitInlinedDirective(CGF, OMPD_single, SingleOpGen);
3247 if (DidIt.isValid()) {
3248 // did_it = 1;
3249 CGF.Builder.CreateStore(CGF.Builder.getInt32(1), DidIt);
3250 }
3251 Action.Done(CGF);
3252 // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
3253 // <copy_func>, did_it);
3254 if (DidIt.isValid()) {
3255 llvm::APInt ArraySize(/*unsigned int numBits=*/32, CopyprivateVars.size());
3256 QualType CopyprivateArrayTy =
3257 C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
3258 /*IndexTypeQuals=*/0);
3259 // Create a list of all private variables for copyprivate.
3260 Address CopyprivateList =
3261 CGF.CreateMemTemp(CopyprivateArrayTy, ".omp.copyprivate.cpr_list");
3262 for (unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) {
3263 Address Elem = CGF.Builder.CreateConstArrayGEP(CopyprivateList, I);
3264 CGF.Builder.CreateStore(
3265 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3266 CGF.EmitLValue(CopyprivateVars[I]).getPointer(), CGF.VoidPtrTy),
3267 Elem);
3268 }
3269 // Build function that copies private values from single region to all other
3270 // threads in the corresponding parallel region.
3271 llvm::Value *CpyFn = emitCopyprivateCopyFunction(
3272 CGM, CGF.ConvertTypeForMem(CopyprivateArrayTy)->getPointerTo(),
3273 CopyprivateVars, SrcExprs, DstExprs, AssignmentOps, Loc);
3274 llvm::Value *BufSize = CGF.getTypeSize(CopyprivateArrayTy);
3275 Address CL =
3276 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(CopyprivateList,
3277 CGF.VoidPtrTy);
3278 llvm::Value *DidItVal = CGF.Builder.CreateLoad(DidIt);
3279 llvm::Value *Args[] = {
3280 emitUpdateLocation(CGF, Loc), // ident_t *<loc>
3281 getThreadID(CGF, Loc), // i32 <gtid>
3282 BufSize, // size_t <buf_size>
3283 CL.getPointer(), // void *<copyprivate list>
3284 CpyFn, // void (*) (void *, void *) <copy_func>
3285 DidItVal // i32 did_it
3286 };
3287 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_copyprivate), Args);
3288 }
3289}
3290
3291void CGOpenMPRuntime::emitOrderedRegion(CodeGenFunction &CGF,
3292 const RegionCodeGenTy &OrderedOpGen,
3293 SourceLocation Loc, bool IsThreads) {
3294 if (!CGF.HaveInsertPoint())
3295 return;
3296 // __kmpc_ordered(ident_t *, gtid);
3297 // OrderedOpGen();
3298 // __kmpc_end_ordered(ident_t *, gtid);
3299 // Prepare arguments and build a call to __kmpc_ordered
3300 if (IsThreads) {
3301 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
3302 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_ordered), Args,
3303 createRuntimeFunction(OMPRTL__kmpc_end_ordered),
3304 Args);
3305 OrderedOpGen.setAction(Action);
3306 emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
3307 return;
3308 }
3309 emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
3310}
3311
3312unsigned CGOpenMPRuntime::getDefaultFlagsForBarriers(OpenMPDirectiveKind Kind) {
3313 unsigned Flags;
3314 if (Kind == OMPD_for)
3315 Flags = OMP_IDENT_BARRIER_IMPL_FOR;
3316 else if (Kind == OMPD_sections)
3317 Flags = OMP_IDENT_BARRIER_IMPL_SECTIONS;
3318 else if (Kind == OMPD_single)
3319 Flags = OMP_IDENT_BARRIER_IMPL_SINGLE;
3320 else if (Kind == OMPD_barrier)
3321 Flags = OMP_IDENT_BARRIER_EXPL;
3322 else
3323 Flags = OMP_IDENT_BARRIER_IMPL;
3324 return Flags;
3325}
3326
3327void CGOpenMPRuntime::getDefaultScheduleAndChunk(
3328 CodeGenFunction &CGF, const OMPLoopDirective &S,
3329 OpenMPScheduleClauseKind &ScheduleKind, const Expr *&ChunkExpr) const {
3330 // Check if the loop directive is actually a doacross loop directive. In this
3331 // case choose static, 1 schedule.
3332 if (llvm::any_of(
3333 S.getClausesOfKind<OMPOrderedClause>(),
3334 [](const OMPOrderedClause *C) { return C->getNumForLoops(); })) {
3335 ScheduleKind = OMPC_SCHEDULE_static;
3336 // Chunk size is 1 in this case.
3337 llvm::APInt ChunkSize(32, 1);
3338 ChunkExpr = IntegerLiteral::Create(
3339 CGF.getContext(), ChunkSize,
3340 CGF.getContext().getIntTypeForBitwidth(32, /*Signed=*/0),
3341 SourceLocation());
3342 }
3343}
3344
3345void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
3346 OpenMPDirectiveKind Kind, bool EmitChecks,
3347 bool ForceSimpleCall) {
3348 if (!CGF.HaveInsertPoint())
3349 return;
3350 // Build call __kmpc_cancel_barrier(loc, thread_id);
3351 // Build call __kmpc_barrier(loc, thread_id);
3352 unsigned Flags = getDefaultFlagsForBarriers(Kind);
3353 // Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc,
3354 // thread_id);
3355 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
3356 getThreadID(CGF, Loc)};
3357 if (auto *OMPRegionInfo =
3358 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
3359 if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
3360 llvm::Value *Result = CGF.EmitRuntimeCall(
3361 createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args);
3362 if (EmitChecks) {
3363 // if (__kmpc_cancel_barrier()) {
3364 // exit from construct;
3365 // }
3366 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
3367 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
3368 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
3369 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
3370 CGF.EmitBlock(ExitBB);
3371 // exit from construct;
3372 CodeGenFunction::JumpDest CancelDestination =
3373 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
3374 CGF.EmitBranchThroughCleanup(CancelDestination);
3375 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
3376 }
3377 return;
3378 }
3379 }
3380 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_barrier), Args);
3381}
3382
3383/// Map the OpenMP loop schedule to the runtime enumeration.
3384static OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind,
3385 bool Chunked, bool Ordered) {
3386 switch (ScheduleKind) {
3387 case OMPC_SCHEDULE_static:
3388 return Chunked ? (Ordered ? OMP_ord_static_chunked : OMP_sch_static_chunked)
3389 : (Ordered ? OMP_ord_static : OMP_sch_static);
3390 case OMPC_SCHEDULE_dynamic:
3391 return Ordered ? OMP_ord_dynamic_chunked : OMP_sch_dynamic_chunked;
3392 case OMPC_SCHEDULE_guided:
3393 return Ordered ? OMP_ord_guided_chunked : OMP_sch_guided_chunked;
3394 case OMPC_SCHEDULE_runtime:
3395 return Ordered ? OMP_ord_runtime : OMP_sch_runtime;
3396 case OMPC_SCHEDULE_auto:
3397 return Ordered ? OMP_ord_auto : OMP_sch_auto;
3398 case OMPC_SCHEDULE_unknown:
3399 assert(!Chunked && "chunk was specified but schedule kind not known")((!Chunked && "chunk was specified but schedule kind not known"
) ? static_cast<void> (0) : __assert_fail ("!Chunked && \"chunk was specified but schedule kind not known\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3399, __PRETTY_FUNCTION__))
;
3400 return Ordered ? OMP_ord_static : OMP_sch_static;
3401 }
3402 llvm_unreachable("Unexpected runtime schedule")::llvm::llvm_unreachable_internal("Unexpected runtime schedule"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3402)
;
3403}
3404
3405/// Map the OpenMP distribute schedule to the runtime enumeration.
3406static OpenMPSchedType
3407getRuntimeSchedule(OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) {
3408 // only static is allowed for dist_schedule
3409 return Chunked ? OMP_dist_sch_static_chunked : OMP_dist_sch_static;
3410}
3411
3412bool CGOpenMPRuntime::isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind,
3413 bool Chunked) const {
3414 OpenMPSchedType Schedule =
3415 getRuntimeSchedule(ScheduleKind, Chunked, /*Ordered=*/false);
3416 return Schedule == OMP_sch_static;
3417}
3418
3419bool CGOpenMPRuntime::isStaticNonchunked(
3420 OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) const {
3421 OpenMPSchedType Schedule = getRuntimeSchedule(ScheduleKind, Chunked);
3422 return Schedule == OMP_dist_sch_static;
3423}
3424
3425bool CGOpenMPRuntime::isStaticChunked(OpenMPScheduleClauseKind ScheduleKind,
3426 bool Chunked) const {
3427 OpenMPSchedType Schedule =
3428 getRuntimeSchedule(ScheduleKind, Chunked, /*Ordered=*/false);
3429 return Schedule == OMP_sch_static_chunked;
3430}
3431
3432bool CGOpenMPRuntime::isStaticChunked(
3433 OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) const {
3434 OpenMPSchedType Schedule = getRuntimeSchedule(ScheduleKind, Chunked);
3435 return Schedule == OMP_dist_sch_static_chunked;
3436}
3437
3438bool CGOpenMPRuntime::isDynamic(OpenMPScheduleClauseKind ScheduleKind) const {
3439 OpenMPSchedType Schedule =
3440 getRuntimeSchedule(ScheduleKind, /*Chunked=*/false, /*Ordered=*/false);
3441 assert(Schedule != OMP_sch_static_chunked && "cannot be chunked here")((Schedule != OMP_sch_static_chunked && "cannot be chunked here"
) ? static_cast<void> (0) : __assert_fail ("Schedule != OMP_sch_static_chunked && \"cannot be chunked here\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3441, __PRETTY_FUNCTION__))
;
3442 return Schedule != OMP_sch_static;
3443}
3444
3445static int addMonoNonMonoModifier(OpenMPSchedType Schedule,
3446 OpenMPScheduleClauseModifier M1,
3447 OpenMPScheduleClauseModifier M2) {
3448 int Modifier = 0;
3449 switch (M1) {
3450 case OMPC_SCHEDULE_MODIFIER_monotonic:
3451 Modifier = OMP_sch_modifier_monotonic;
3452 break;
3453 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
3454 Modifier = OMP_sch_modifier_nonmonotonic;
3455 break;
3456 case OMPC_SCHEDULE_MODIFIER_simd:
3457 if (Schedule == OMP_sch_static_chunked)
3458 Schedule = OMP_sch_static_balanced_chunked;
3459 break;
3460 case OMPC_SCHEDULE_MODIFIER_last:
3461 case OMPC_SCHEDULE_MODIFIER_unknown:
3462 break;
3463 }
3464 switch (M2) {
3465 case OMPC_SCHEDULE_MODIFIER_monotonic:
3466 Modifier = OMP_sch_modifier_monotonic;
3467 break;
3468 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
3469 Modifier = OMP_sch_modifier_nonmonotonic;
3470 break;
3471 case OMPC_SCHEDULE_MODIFIER_simd:
3472 if (Schedule == OMP_sch_static_chunked)
3473 Schedule = OMP_sch_static_balanced_chunked;
3474 break;
3475 case OMPC_SCHEDULE_MODIFIER_last:
3476 case OMPC_SCHEDULE_MODIFIER_unknown:
3477 break;
3478 }
3479 return Schedule | Modifier;
3480}
3481
3482void CGOpenMPRuntime::emitForDispatchInit(
3483 CodeGenFunction &CGF, SourceLocation Loc,
3484 const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned,
3485 bool Ordered, const DispatchRTInput &DispatchValues) {
3486 if (!CGF.HaveInsertPoint())
3487 return;
3488 OpenMPSchedType Schedule = getRuntimeSchedule(
3489 ScheduleKind.Schedule, DispatchValues.Chunk != nullptr, Ordered);
3490 assert(Ordered ||((Ordered || (Schedule != OMP_sch_static && Schedule !=
OMP_sch_static_chunked && Schedule != OMP_ord_static
&& Schedule != OMP_ord_static_chunked && Schedule
!= OMP_sch_static_balanced_chunked)) ? static_cast<void>
(0) : __assert_fail ("Ordered || (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked && Schedule != OMP_ord_static && Schedule != OMP_ord_static_chunked && Schedule != OMP_sch_static_balanced_chunked)"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3493, __PRETTY_FUNCTION__))
3491 (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked &&((Ordered || (Schedule != OMP_sch_static && Schedule !=
OMP_sch_static_chunked && Schedule != OMP_ord_static
&& Schedule != OMP_ord_static_chunked && Schedule
!= OMP_sch_static_balanced_chunked)) ? static_cast<void>
(0) : __assert_fail ("Ordered || (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked && Schedule != OMP_ord_static && Schedule != OMP_ord_static_chunked && Schedule != OMP_sch_static_balanced_chunked)"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3493, __PRETTY_FUNCTION__))
3492 Schedule != OMP_ord_static && Schedule != OMP_ord_static_chunked &&((Ordered || (Schedule != OMP_sch_static && Schedule !=
OMP_sch_static_chunked && Schedule != OMP_ord_static
&& Schedule != OMP_ord_static_chunked && Schedule
!= OMP_sch_static_balanced_chunked)) ? static_cast<void>
(0) : __assert_fail ("Ordered || (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked && Schedule != OMP_ord_static && Schedule != OMP_ord_static_chunked && Schedule != OMP_sch_static_balanced_chunked)"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3493, __PRETTY_FUNCTION__))
3493 Schedule != OMP_sch_static_balanced_chunked))((Ordered || (Schedule != OMP_sch_static && Schedule !=
OMP_sch_static_chunked && Schedule != OMP_ord_static
&& Schedule != OMP_ord_static_chunked && Schedule
!= OMP_sch_static_balanced_chunked)) ? static_cast<void>
(0) : __assert_fail ("Ordered || (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked && Schedule != OMP_ord_static && Schedule != OMP_ord_static_chunked && Schedule != OMP_sch_static_balanced_chunked)"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3493, __PRETTY_FUNCTION__))
;
3494 // Call __kmpc_dispatch_init(
3495 // ident_t *loc, kmp_int32 tid, kmp_int32 schedule,
3496 // kmp_int[32|64] lower, kmp_int[32|64] upper,
3497 // kmp_int[32|64] stride, kmp_int[32|64] chunk);
3498
3499 // If the Chunk was not specified in the clause - use default value 1.
3500 llvm::Value *Chunk = DispatchValues.Chunk ? DispatchValues.Chunk
3501 : CGF.Builder.getIntN(IVSize, 1);
3502 llvm::Value *Args[] = {
3503 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
3504 CGF.Builder.getInt32(addMonoNonMonoModifier(
3505 Schedule, ScheduleKind.M1, ScheduleKind.M2)), // Schedule type
3506 DispatchValues.LB, // Lower
3507 DispatchValues.UB, // Upper
3508 CGF.Builder.getIntN(IVSize, 1), // Stride
3509 Chunk // Chunk
3510 };
3511 CGF.EmitRuntimeCall(createDispatchInitFunction(IVSize, IVSigned), Args);
3512}
3513
3514static void emitForStaticInitCall(
3515 CodeGenFunction &CGF, llvm::Value *UpdateLocation, llvm::Value *ThreadId,
3516 llvm::FunctionCallee ForStaticInitFunction, OpenMPSchedType Schedule,
3517 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
3518 const CGOpenMPRuntime::StaticRTInput &Values) {
3519 if (!CGF.HaveInsertPoint())
3520 return;
3521
3522 assert(!Values.Ordered)((!Values.Ordered) ? static_cast<void> (0) : __assert_fail
("!Values.Ordered", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3522, __PRETTY_FUNCTION__))
;
3523 assert(Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked ||((Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked
|| Schedule == OMP_sch_static_balanced_chunked || Schedule ==
OMP_ord_static || Schedule == OMP_ord_static_chunked || Schedule
== OMP_dist_sch_static || Schedule == OMP_dist_sch_static_chunked
) ? static_cast<void> (0) : __assert_fail ("Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked || Schedule == OMP_ord_static || Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static || Schedule == OMP_dist_sch_static_chunked"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3527, __PRETTY_FUNCTION__))
3524 Schedule == OMP_sch_static_balanced_chunked ||((Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked
|| Schedule == OMP_sch_static_balanced_chunked || Schedule ==
OMP_ord_static || Schedule == OMP_ord_static_chunked || Schedule
== OMP_dist_sch_static || Schedule == OMP_dist_sch_static_chunked
) ? static_cast<void> (0) : __assert_fail ("Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked || Schedule == OMP_ord_static || Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static || Schedule == OMP_dist_sch_static_chunked"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3527, __PRETTY_FUNCTION__))
3525 Schedule == OMP_ord_static || Schedule == OMP_ord_static_chunked ||((Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked
|| Schedule == OMP_sch_static_balanced_chunked || Schedule ==
OMP_ord_static || Schedule == OMP_ord_static_chunked || Schedule
== OMP_dist_sch_static || Schedule == OMP_dist_sch_static_chunked
) ? static_cast<void> (0) : __assert_fail ("Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked || Schedule == OMP_ord_static || Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static || Schedule == OMP_dist_sch_static_chunked"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3527, __PRETTY_FUNCTION__))
3526 Schedule == OMP_dist_sch_static ||((Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked
|| Schedule == OMP_sch_static_balanced_chunked || Schedule ==
OMP_ord_static || Schedule == OMP_ord_static_chunked || Schedule
== OMP_dist_sch_static || Schedule == OMP_dist_sch_static_chunked
) ? static_cast<void> (0) : __assert_fail ("Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked || Schedule == OMP_ord_static || Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static || Schedule == OMP_dist_sch_static_chunked"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3527, __PRETTY_FUNCTION__))
3527 Schedule == OMP_dist_sch_static_chunked)((Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked
|| Schedule == OMP_sch_static_balanced_chunked || Schedule ==
OMP_ord_static || Schedule == OMP_ord_static_chunked || Schedule
== OMP_dist_sch_static || Schedule == OMP_dist_sch_static_chunked
) ? static_cast<void> (0) : __assert_fail ("Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked || Schedule == OMP_ord_static || Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static || Schedule == OMP_dist_sch_static_chunked"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3527, __PRETTY_FUNCTION__))
;
3528
3529 // Call __kmpc_for_static_init(
3530 // ident_t *loc, kmp_int32 tid, kmp_int32 schedtype,
3531 // kmp_int32 *p_lastiter, kmp_int[32|64] *p_lower,
3532 // kmp_int[32|64] *p_upper, kmp_int[32|64] *p_stride,
3533 // kmp_int[32|64] incr, kmp_int[32|64] chunk);
3534 llvm::Value *Chunk = Values.Chunk;
3535 if (Chunk == nullptr) {
3536 assert((Schedule == OMP_sch_static || Schedule == OMP_ord_static ||(((Schedule == OMP_sch_static || Schedule == OMP_ord_static ||
Schedule == OMP_dist_sch_static) && "expected static non-chunked schedule"
) ? static_cast<void> (0) : __assert_fail ("(Schedule == OMP_sch_static || Schedule == OMP_ord_static || Schedule == OMP_dist_sch_static) && \"expected static non-chunked schedule\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3538, __PRETTY_FUNCTION__))
3537 Schedule == OMP_dist_sch_static) &&(((Schedule == OMP_sch_static || Schedule == OMP_ord_static ||
Schedule == OMP_dist_sch_static) && "expected static non-chunked schedule"
) ? static_cast<void> (0) : __assert_fail ("(Schedule == OMP_sch_static || Schedule == OMP_ord_static || Schedule == OMP_dist_sch_static) && \"expected static non-chunked schedule\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3538, __PRETTY_FUNCTION__))
3538 "expected static non-chunked schedule")(((Schedule == OMP_sch_static || Schedule == OMP_ord_static ||
Schedule == OMP_dist_sch_static) && "expected static non-chunked schedule"
) ? static_cast<void> (0) : __assert_fail ("(Schedule == OMP_sch_static || Schedule == OMP_ord_static || Schedule == OMP_dist_sch_static) && \"expected static non-chunked schedule\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3538, __PRETTY_FUNCTION__))
;
3539 // If the Chunk was not specified in the clause - use default value 1.
3540 Chunk = CGF.Builder.getIntN(Values.IVSize, 1);
3541 } else {
3542 assert((Schedule == OMP_sch_static_chunked ||(((Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked
|| Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static_chunked
) && "expected static chunked schedule") ? static_cast
<void> (0) : __assert_fail ("(Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked || Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static_chunked) && \"expected static chunked schedule\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3546, __PRETTY_FUNCTION__))
3543 Schedule == OMP_sch_static_balanced_chunked ||(((Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked
|| Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static_chunked
) && "expected static chunked schedule") ? static_cast
<void> (0) : __assert_fail ("(Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked || Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static_chunked) && \"expected static chunked schedule\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3546, __PRETTY_FUNCTION__))
3544 Schedule == OMP_ord_static_chunked ||(((Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked
|| Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static_chunked
) && "expected static chunked schedule") ? static_cast
<void> (0) : __assert_fail ("(Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked || Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static_chunked) && \"expected static chunked schedule\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3546, __PRETTY_FUNCTION__))
3545 Schedule == OMP_dist_sch_static_chunked) &&(((Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked
|| Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static_chunked
) && "expected static chunked schedule") ? static_cast
<void> (0) : __assert_fail ("(Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked || Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static_chunked) && \"expected static chunked schedule\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3546, __PRETTY_FUNCTION__))
3546 "expected static chunked schedule")(((Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked
|| Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static_chunked
) && "expected static chunked schedule") ? static_cast
<void> (0) : __assert_fail ("(Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static_balanced_chunked || Schedule == OMP_ord_static_chunked || Schedule == OMP_dist_sch_static_chunked) && \"expected static chunked schedule\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3546, __PRETTY_FUNCTION__))
;
3547 }
3548 llvm::Value *Args[] = {
3549 UpdateLocation,
3550 ThreadId,
3551 CGF.Builder.getInt32(addMonoNonMonoModifier(Schedule, M1,
3552 M2)), // Schedule type
3553 Values.IL.getPointer(), // &isLastIter
3554 Values.LB.getPointer(), // &LB
3555 Values.UB.getPointer(), // &UB
3556 Values.ST.getPointer(), // &Stride
3557 CGF.Builder.getIntN(Values.IVSize, 1), // Incr
3558 Chunk // Chunk
3559 };
3560 CGF.EmitRuntimeCall(ForStaticInitFunction, Args);
3561}
3562
3563void CGOpenMPRuntime::emitForStaticInit(CodeGenFunction &CGF,
3564 SourceLocation Loc,
3565 OpenMPDirectiveKind DKind,
3566 const OpenMPScheduleTy &ScheduleKind,
3567 const StaticRTInput &Values) {
3568 OpenMPSchedType ScheduleNum = getRuntimeSchedule(
3569 ScheduleKind.Schedule, Values.Chunk != nullptr, Values.Ordered);
3570 assert(isOpenMPWorksharingDirective(DKind) &&((isOpenMPWorksharingDirective(DKind) && "Expected loop-based or sections-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPWorksharingDirective(DKind) && \"Expected loop-based or sections-based directive.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3571, __PRETTY_FUNCTION__))
3571 "Expected loop-based or sections-based directive.")((isOpenMPWorksharingDirective(DKind) && "Expected loop-based or sections-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPWorksharingDirective(DKind) && \"Expected loop-based or sections-based directive.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3571, __PRETTY_FUNCTION__))
;
3572 llvm::Value *UpdatedLocation = emitUpdateLocation(CGF, Loc,
3573 isOpenMPLoopDirective(DKind)
3574 ? OMP_IDENT_WORK_LOOP
3575 : OMP_IDENT_WORK_SECTIONS);
3576 llvm::Value *ThreadId = getThreadID(CGF, Loc);
3577 llvm::FunctionCallee StaticInitFunction =
3578 createForStaticInitFunction(Values.IVSize, Values.IVSigned);
3579 emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
3580 ScheduleNum, ScheduleKind.M1, ScheduleKind.M2, Values);
3581}
3582
3583void CGOpenMPRuntime::emitDistributeStaticInit(
3584 CodeGenFunction &CGF, SourceLocation Loc,
3585 OpenMPDistScheduleClauseKind SchedKind,
3586 const CGOpenMPRuntime::StaticRTInput &Values) {
3587 OpenMPSchedType ScheduleNum =
3588 getRuntimeSchedule(SchedKind, Values.Chunk != nullptr);
3589 llvm::Value *UpdatedLocation =
3590 emitUpdateLocation(CGF, Loc, OMP_IDENT_WORK_DISTRIBUTE);
3591 llvm::Value *ThreadId = getThreadID(CGF, Loc);
3592 llvm::FunctionCallee StaticInitFunction =
3593 createForStaticInitFunction(Values.IVSize, Values.IVSigned);
3594 emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
3595 ScheduleNum, OMPC_SCHEDULE_MODIFIER_unknown,
3596 OMPC_SCHEDULE_MODIFIER_unknown, Values);
3597}
3598
3599void CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF,
3600 SourceLocation Loc,
3601 OpenMPDirectiveKind DKind) {
3602 if (!CGF.HaveInsertPoint())
3603 return;
3604 // Call __kmpc_for_static_fini(ident_t *loc, kmp_int32 tid);
3605 llvm::Value *Args[] = {
3606 emitUpdateLocation(CGF, Loc,
3607 isOpenMPDistributeDirective(DKind)
3608 ? OMP_IDENT_WORK_DISTRIBUTE
3609 : isOpenMPLoopDirective(DKind)
3610 ? OMP_IDENT_WORK_LOOP
3611 : OMP_IDENT_WORK_SECTIONS),
3612 getThreadID(CGF, Loc)};
3613 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_for_static_fini),
3614 Args);
3615}
3616
3617void CGOpenMPRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF,
3618 SourceLocation Loc,
3619 unsigned IVSize,
3620 bool IVSigned) {
3621 if (!CGF.HaveInsertPoint())
3622 return;
3623 // Call __kmpc_for_dynamic_fini_(4|8)[u](ident_t *loc, kmp_int32 tid);
3624 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
3625 CGF.EmitRuntimeCall(createDispatchFiniFunction(IVSize, IVSigned), Args);
3626}
3627
3628llvm::Value *CGOpenMPRuntime::emitForNext(CodeGenFunction &CGF,
3629 SourceLocation Loc, unsigned IVSize,
3630 bool IVSigned, Address IL,
3631 Address LB, Address UB,
3632 Address ST) {
3633 // Call __kmpc_dispatch_next(
3634 // ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
3635 // kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
3636 // kmp_int[32|64] *p_stride);
3637 llvm::Value *Args[] = {
3638 emitUpdateLocation(CGF, Loc),
3639 getThreadID(CGF, Loc),
3640 IL.getPointer(), // &isLastIter
3641 LB.getPointer(), // &Lower
3642 UB.getPointer(), // &Upper
3643 ST.getPointer() // &Stride
3644 };
3645 llvm::Value *Call =
3646 CGF.EmitRuntimeCall(createDispatchNextFunction(IVSize, IVSigned), Args);
3647 return CGF.EmitScalarConversion(
3648 Call, CGF.getContext().getIntTypeForBitwidth(32, /*Signed=*/1),
3649 CGF.getContext().BoolTy, Loc);
3650}
3651
3652void CGOpenMPRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
3653 llvm::Value *NumThreads,
3654 SourceLocation Loc) {
3655 if (!CGF.HaveInsertPoint())
3656 return;
3657 // Build call __kmpc_push_num_threads(&loc, global_tid, num_threads)
3658 llvm::Value *Args[] = {
3659 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
3660 CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty, /*isSigned*/ true)};
3661 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_num_threads),
3662 Args);
3663}
3664
3665void CGOpenMPRuntime::emitProcBindClause(CodeGenFunction &CGF,
3666 OpenMPProcBindClauseKind ProcBind,
3667 SourceLocation Loc) {
3668 if (!CGF.HaveInsertPoint())
3669 return;
3670 // Constants for proc bind value accepted by the runtime.
3671 enum ProcBindTy {
3672 ProcBindFalse = 0,
3673 ProcBindTrue,
3674 ProcBindMaster,
3675 ProcBindClose,
3676 ProcBindSpread,
3677 ProcBindIntel,
3678 ProcBindDefault
3679 } RuntimeProcBind;
3680 switch (ProcBind) {
3681 case OMPC_PROC_BIND_master:
3682 RuntimeProcBind = ProcBindMaster;
3683 break;
3684 case OMPC_PROC_BIND_close:
3685 RuntimeProcBind = ProcBindClose;
3686 break;
3687 case OMPC_PROC_BIND_spread:
3688 RuntimeProcBind = ProcBindSpread;
3689 break;
3690 case OMPC_PROC_BIND_unknown:
3691 llvm_unreachable("Unsupported proc_bind value.")::llvm::llvm_unreachable_internal("Unsupported proc_bind value."
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3691)
;
3692 }
3693 // Build call __kmpc_push_proc_bind(&loc, global_tid, proc_bind)
3694 llvm::Value *Args[] = {
3695 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
3696 llvm::ConstantInt::get(CGM.IntTy, RuntimeProcBind, /*isSigned=*/true)};
3697 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_proc_bind), Args);
3698}
3699
3700void CGOpenMPRuntime::emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *>,
3701 SourceLocation Loc) {
3702 if (!CGF.HaveInsertPoint())
3703 return;
3704 // Build call void __kmpc_flush(ident_t *loc)
3705 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_flush),
3706 emitUpdateLocation(CGF, Loc));
3707}
3708
3709namespace {
3710/// Indexes of fields for type kmp_task_t.
3711enum KmpTaskTFields {
3712 /// List of shared variables.
3713 KmpTaskTShareds,
3714 /// Task routine.
3715 KmpTaskTRoutine,
3716 /// Partition id for the untied tasks.
3717 KmpTaskTPartId,
3718 /// Function with call of destructors for private variables.
3719 Data1,
3720 /// Task priority.
3721 Data2,
3722 /// (Taskloops only) Lower bound.
3723 KmpTaskTLowerBound,
3724 /// (Taskloops only) Upper bound.
3725 KmpTaskTUpperBound,
3726 /// (Taskloops only) Stride.
3727 KmpTaskTStride,
3728 /// (Taskloops only) Is last iteration flag.
3729 KmpTaskTLastIter,
3730 /// (Taskloops only) Reduction data.
3731 KmpTaskTReductions,
3732};
3733} // anonymous namespace
3734
3735bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::empty() const {
3736 return OffloadEntriesTargetRegion.empty() &&
3737 OffloadEntriesDeviceGlobalVar.empty();
3738}
3739
3740/// Initialize target region entry.
3741void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3742 initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
3743 StringRef ParentName, unsigned LineNum,
3744 unsigned Order) {
3745 assert(CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "((CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "
"only required for the device " "code generation.") ? static_cast
<void> (0) : __assert_fail ("CGM.getLangOpts().OpenMPIsDevice && \"Initialization of entries is \" \"only required for the device \" \"code generation.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3747, __PRETTY_FUNCTION__))
3746 "only required for the device "((CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "
"only required for the device " "code generation.") ? static_cast
<void> (0) : __assert_fail ("CGM.getLangOpts().OpenMPIsDevice && \"Initialization of entries is \" \"only required for the device \" \"code generation.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3747, __PRETTY_FUNCTION__))
3747 "code generation.")((CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "
"only required for the device " "code generation.") ? static_cast
<void> (0) : __assert_fail ("CGM.getLangOpts().OpenMPIsDevice && \"Initialization of entries is \" \"only required for the device \" \"code generation.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3747, __PRETTY_FUNCTION__))
;
3748 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] =
3749 OffloadEntryInfoTargetRegion(Order, /*Addr=*/nullptr, /*ID=*/nullptr,
3750 OMPTargetRegionEntryTargetRegion);
3751 ++OffloadingEntriesNum;
3752}
3753
3754void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3755 registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
3756 StringRef ParentName, unsigned LineNum,
3757 llvm::Constant *Addr, llvm::Constant *ID,
3758 OMPTargetRegionEntryKind Flags) {
3759 // If we are emitting code for a target, the entry is already initialized,
3760 // only has to be registered.
3761 if (CGM.getLangOpts().OpenMPIsDevice) {
3762 if (!hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum)) {
3763 unsigned DiagID = CGM.getDiags().getCustomDiagID(
3764 DiagnosticsEngine::Error,
3765 "Unable to find target region on line '%0' in the device code.");
3766 CGM.getDiags().Report(DiagID) << LineNum;
3767 return;
3768 }
3769 auto &Entry =
3770 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum];
3771 assert(Entry.isValid() && "Entry not initialized!")((Entry.isValid() && "Entry not initialized!") ? static_cast
<void> (0) : __assert_fail ("Entry.isValid() && \"Entry not initialized!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3771, __PRETTY_FUNCTION__))
;
3772 Entry.setAddress(Addr);
3773 Entry.setID(ID);
3774 Entry.setFlags(Flags);
3775 } else {
3776 OffloadEntryInfoTargetRegion Entry(OffloadingEntriesNum, Addr, ID, Flags);
3777 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] = Entry;
3778 ++OffloadingEntriesNum;
3779 }
3780}
3781
3782bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::hasTargetRegionEntryInfo(
3783 unsigned DeviceID, unsigned FileID, StringRef ParentName,
3784 unsigned LineNum) const {
3785 auto PerDevice = OffloadEntriesTargetRegion.find(DeviceID);
3786 if (PerDevice == OffloadEntriesTargetRegion.end())
3787 return false;
3788 auto PerFile = PerDevice->second.find(FileID);
3789 if (PerFile == PerDevice->second.end())
3790 return false;
3791 auto PerParentName = PerFile->second.find(ParentName);
3792 if (PerParentName == PerFile->second.end())
3793 return false;
3794 auto PerLine = PerParentName->second.find(LineNum);
3795 if (PerLine == PerParentName->second.end())
3796 return false;
3797 // Fail if this entry is already registered.
3798 if (PerLine->second.getAddress() || PerLine->second.getID())
3799 return false;
3800 return true;
3801}
3802
3803void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::actOnTargetRegionEntriesInfo(
3804 const OffloadTargetRegionEntryInfoActTy &Action) {
3805 // Scan all target region entries and perform the provided action.
3806 for (const auto &D : OffloadEntriesTargetRegion)
3807 for (const auto &F : D.second)
3808 for (const auto &P : F.second)
3809 for (const auto &L : P.second)
3810 Action(D.first, F.first, P.first(), L.first, L.second);
3811}
3812
3813void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3814 initializeDeviceGlobalVarEntryInfo(StringRef Name,
3815 OMPTargetGlobalVarEntryKind Flags,
3816 unsigned Order) {
3817 assert(CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "((CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "
"only required for the device " "code generation.") ? static_cast
<void> (0) : __assert_fail ("CGM.getLangOpts().OpenMPIsDevice && \"Initialization of entries is \" \"only required for the device \" \"code generation.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3819, __PRETTY_FUNCTION__))
3818 "only required for the device "((CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "
"only required for the device " "code generation.") ? static_cast
<void> (0) : __assert_fail ("CGM.getLangOpts().OpenMPIsDevice && \"Initialization of entries is \" \"only required for the device \" \"code generation.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3819, __PRETTY_FUNCTION__))
3819 "code generation.")((CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "
"only required for the device " "code generation.") ? static_cast
<void> (0) : __assert_fail ("CGM.getLangOpts().OpenMPIsDevice && \"Initialization of entries is \" \"only required for the device \" \"code generation.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3819, __PRETTY_FUNCTION__))
;
3820 OffloadEntriesDeviceGlobalVar.try_emplace(Name, Order, Flags);
3821 ++OffloadingEntriesNum;
3822}
3823
3824void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3825 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
3826 CharUnits VarSize,
3827 OMPTargetGlobalVarEntryKind Flags,
3828 llvm::GlobalValue::LinkageTypes Linkage) {
3829 if (CGM.getLangOpts().OpenMPIsDevice) {
3830 auto &Entry = OffloadEntriesDeviceGlobalVar[VarName];
3831 assert(Entry.isValid() && Entry.getFlags() == Flags &&((Entry.isValid() && Entry.getFlags() == Flags &&
"Entry not initialized!") ? static_cast<void> (0) : __assert_fail
("Entry.isValid() && Entry.getFlags() == Flags && \"Entry not initialized!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3832, __PRETTY_FUNCTION__))
3832 "Entry not initialized!")((Entry.isValid() && Entry.getFlags() == Flags &&
"Entry not initialized!") ? static_cast<void> (0) : __assert_fail
("Entry.isValid() && Entry.getFlags() == Flags && \"Entry not initialized!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3832, __PRETTY_FUNCTION__))
;
3833 assert((!Entry.getAddress() || Entry.getAddress() == Addr) &&(((!Entry.getAddress() || Entry.getAddress() == Addr) &&
"Resetting with the new address.") ? static_cast<void>
(0) : __assert_fail ("(!Entry.getAddress() || Entry.getAddress() == Addr) && \"Resetting with the new address.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3834, __PRETTY_FUNCTION__))
3834 "Resetting with the new address.")(((!Entry.getAddress() || Entry.getAddress() == Addr) &&
"Resetting with the new address.") ? static_cast<void>
(0) : __assert_fail ("(!Entry.getAddress() || Entry.getAddress() == Addr) && \"Resetting with the new address.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3834, __PRETTY_FUNCTION__))
;
3835 if (Entry.getAddress() && hasDeviceGlobalVarEntryInfo(VarName)) {
3836 if (Entry.getVarSize().isZero()) {
3837 Entry.setVarSize(VarSize);
3838 Entry.setLinkage(Linkage);
3839 }
3840 return;
3841 }
3842 Entry.setVarSize(VarSize);
3843 Entry.setLinkage(Linkage);
3844 Entry.setAddress(Addr);
3845 } else {
3846 if (hasDeviceGlobalVarEntryInfo(VarName)) {
3847 auto &Entry = OffloadEntriesDeviceGlobalVar[VarName];
3848 assert(Entry.isValid() && Entry.getFlags() == Flags &&((Entry.isValid() && Entry.getFlags() == Flags &&
"Entry not initialized!") ? static_cast<void> (0) : __assert_fail
("Entry.isValid() && Entry.getFlags() == Flags && \"Entry not initialized!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3849, __PRETTY_FUNCTION__))
3849 "Entry not initialized!")((Entry.isValid() && Entry.getFlags() == Flags &&
"Entry not initialized!") ? static_cast<void> (0) : __assert_fail
("Entry.isValid() && Entry.getFlags() == Flags && \"Entry not initialized!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3849, __PRETTY_FUNCTION__))
;
3850 assert((!Entry.getAddress() || Entry.getAddress() == Addr) &&(((!Entry.getAddress() || Entry.getAddress() == Addr) &&
"Resetting with the new address.") ? static_cast<void>
(0) : __assert_fail ("(!Entry.getAddress() || Entry.getAddress() == Addr) && \"Resetting with the new address.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3851, __PRETTY_FUNCTION__))
3851 "Resetting with the new address.")(((!Entry.getAddress() || Entry.getAddress() == Addr) &&
"Resetting with the new address.") ? static_cast<void>
(0) : __assert_fail ("(!Entry.getAddress() || Entry.getAddress() == Addr) && \"Resetting with the new address.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3851, __PRETTY_FUNCTION__))
;
3852 if (Entry.getVarSize().isZero()) {
3853 Entry.setVarSize(VarSize);
3854 Entry.setLinkage(Linkage);
3855 }
3856 return;
3857 }
3858 OffloadEntriesDeviceGlobalVar.try_emplace(
3859 VarName, OffloadingEntriesNum, Addr, VarSize, Flags, Linkage);
3860 ++OffloadingEntriesNum;
3861 }
3862}
3863
3864void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3865 actOnDeviceGlobalVarEntriesInfo(
3866 const OffloadDeviceGlobalVarEntryInfoActTy &Action) {
3867 // Scan all target region entries and perform the provided action.
3868 for (const auto &E : OffloadEntriesDeviceGlobalVar)
3869 Action(E.getKey(), E.getValue());
3870}
3871
3872llvm::Function *
3873CGOpenMPRuntime::createOffloadingBinaryDescriptorRegistration() {
3874 // If we don't have entries or if we are emitting code for the device, we
3875 // don't need to do anything.
3876 if (CGM.getLangOpts().OpenMPIsDevice || OffloadEntriesInfoManager.empty())
2
Assuming the condition is false
3
Taking false branch
3877 return nullptr;
3878
3879 llvm::Module &M = CGM.getModule();
3880 ASTContext &C = CGM.getContext();
3881
3882 // Get list of devices we care about
3883 const std::vector<llvm::Triple> &Devices = CGM.getLangOpts().OMPTargetTriples;
3884
3885 // We should be creating an offloading descriptor only if there are devices
3886 // specified.
3887 assert(!Devices.empty() && "No OpenMP offloading devices??")((!Devices.empty() && "No OpenMP offloading devices??"
) ? static_cast<void> (0) : __assert_fail ("!Devices.empty() && \"No OpenMP offloading devices??\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 3887, __PRETTY_FUNCTION__))
;
4
Assuming the condition is true
5
'?' condition is true
3888
3889 // Create the external variables that will point to the begin and end of the
3890 // host entries section. These will be defined by the linker.
3891 llvm::Type *OffloadEntryTy =
3892 CGM.getTypes().ConvertTypeForMem(getTgtOffloadEntryQTy());
6
Calling 'CGOpenMPRuntime::getTgtOffloadEntryQTy'
3893 std::string EntriesBeginName = getName({"omp_offloading", "entries_begin"});
3894 auto *HostEntriesBegin = new llvm::GlobalVariable(
3895 M, OffloadEntryTy, /*isConstant=*/true,
3896 llvm::GlobalValue::ExternalLinkage, /*Initializer=*/nullptr,
3897 EntriesBeginName);
3898 std::string EntriesEndName = getName({"omp_offloading", "entries_end"});
3899 auto *HostEntriesEnd =
3900 new llvm::GlobalVariable(M, OffloadEntryTy, /*isConstant=*/true,
3901 llvm::GlobalValue::ExternalLinkage,
3902 /*Initializer=*/nullptr, EntriesEndName);
3903
3904 // Create all device images
3905 auto *DeviceImageTy = cast<llvm::StructType>(
3906 CGM.getTypes().ConvertTypeForMem(getTgtDeviceImageQTy()));
3907 ConstantInitBuilder DeviceImagesBuilder(CGM);
3908 ConstantArrayBuilder DeviceImagesEntries =
3909 DeviceImagesBuilder.beginArray(DeviceImageTy);
3910
3911 for (const llvm::Triple &Device : Devices) {
3912 StringRef T = Device.getTriple();
3913 std::string BeginName = getName({"omp_offloading", "img_start", ""});
3914 auto *ImgBegin = new llvm::GlobalVariable(
3915 M, CGM.Int8Ty, /*isConstant=*/true,
3916 llvm::GlobalValue::ExternalWeakLinkage,
3917 /*Initializer=*/nullptr, Twine(BeginName).concat(T));
3918 std::string EndName = getName({"omp_offloading", "img_end", ""});
3919 auto *ImgEnd = new llvm::GlobalVariable(
3920 M, CGM.Int8Ty, /*isConstant=*/true,
3921 llvm::GlobalValue::ExternalWeakLinkage,
3922 /*Initializer=*/nullptr, Twine(EndName).concat(T));
3923
3924 llvm::Constant *Data[] = {ImgBegin, ImgEnd, HostEntriesBegin,
3925 HostEntriesEnd};
3926 createConstantGlobalStructAndAddToParent(CGM, getTgtDeviceImageQTy(), Data,
3927 DeviceImagesEntries);
3928 }
3929
3930 // Create device images global array.
3931 std::string ImagesName = getName({"omp_offloading", "device_images"});
3932 llvm::GlobalVariable *DeviceImages =
3933 DeviceImagesEntries.finishAndCreateGlobal(ImagesName,
3934 CGM.getPointerAlign(),
3935 /*isConstant=*/true);
3936 DeviceImages->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3937
3938 // This is a Zero array to be used in the creation of the constant expressions
3939 llvm::Constant *Index[] = {llvm::Constant::getNullValue(CGM.Int32Ty),
3940 llvm::Constant::getNullValue(CGM.Int32Ty)};
3941
3942 // Create the target region descriptor.
3943 llvm::Constant *Data[] = {
3944 llvm::ConstantInt::get(CGM.Int32Ty, Devices.size()),
3945 llvm::ConstantExpr::getGetElementPtr(DeviceImages->getValueType(),
3946 DeviceImages, Index),
3947 HostEntriesBegin, HostEntriesEnd};
3948 std::string Descriptor = getName({"omp_offloading", "descriptor"});
3949 llvm::GlobalVariable *Desc = createGlobalStruct(
3950 CGM, getTgtBinaryDescriptorQTy(), /*IsConstant=*/true, Data, Descriptor);
3951
3952 // Emit code to register or unregister the descriptor at execution
3953 // startup or closing, respectively.
3954
3955 llvm::Function *UnRegFn;
3956 {
3957 FunctionArgList Args;
3958 ImplicitParamDecl DummyPtr(C, C.VoidPtrTy, ImplicitParamDecl::Other);
3959 Args.push_back(&DummyPtr);
3960
3961 CodeGenFunction CGF(CGM);
3962 // Disable debug info for global (de-)initializer because they are not part
3963 // of some particular construct.
3964 CGF.disableDebugInfo();
3965 const auto &FI =
3966 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
3967 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
3968 std::string UnregName = getName({"omp_offloading", "descriptor_unreg"});
3969 UnRegFn = CGM.CreateGlobalInitOrDestructFunction(FTy, UnregName, FI);
3970 CGF.StartFunction(GlobalDecl(), C.VoidTy, UnRegFn, FI, Args);
3971 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_unregister_lib),
3972 Desc);
3973 CGF.FinishFunction();
3974 }
3975 llvm::Function *RegFn;
3976 {
3977 CodeGenFunction CGF(CGM);
3978 // Disable debug info for global (de-)initializer because they are not part
3979 // of some particular construct.
3980 CGF.disableDebugInfo();
3981 const auto &FI = CGM.getTypes().arrangeNullaryFunction();
3982 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
3983
3984 // Encode offload target triples into the registration function name. It
3985 // will serve as a comdat key for the registration/unregistration code for
3986 // this particular combination of offloading targets.
3987 SmallVector<StringRef, 4U> RegFnNameParts(Devices.size() + 2U);
3988 RegFnNameParts[0] = "omp_offloading";
3989 RegFnNameParts[1] = "descriptor_reg";
3990 llvm::transform(Devices, std::next(RegFnNameParts.begin(), 2),
3991 [](const llvm::Triple &T) -> const std::string& {
3992 return T.getTriple();
3993 });
3994 llvm::sort(std::next(RegFnNameParts.begin(), 2), RegFnNameParts.end());
3995 std::string Descriptor = getName(RegFnNameParts);
3996 RegFn = CGM.CreateGlobalInitOrDestructFunction(FTy, Descriptor, FI);
3997 CGF.StartFunction(GlobalDecl(), C.VoidTy, RegFn, FI, FunctionArgList());
3998 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_register_lib), Desc);
3999 // Create a variable to drive the registration and unregistration of the
4000 // descriptor, so we can reuse the logic that emits Ctors and Dtors.
4001 ImplicitParamDecl RegUnregVar(C, C.getTranslationUnitDecl(),
4002 SourceLocation(), nullptr, C.CharTy,
4003 ImplicitParamDecl::Other);
4004 CGM.getCXXABI().registerGlobalDtor(CGF, RegUnregVar, UnRegFn, Desc);
4005 CGF.FinishFunction();
4006 }
4007 if (CGM.supportsCOMDAT()) {
4008 // It is sufficient to call registration function only once, so create a
4009 // COMDAT group for registration/unregistration functions and associated
4010 // data. That would reduce startup time and code size. Registration
4011 // function serves as a COMDAT group key.
4012 llvm::Comdat *ComdatKey = M.getOrInsertComdat(RegFn->getName());
4013 RegFn->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
4014 RegFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
4015 RegFn->setComdat(ComdatKey);
4016 UnRegFn->setComdat(ComdatKey);
4017 DeviceImages->setComdat(ComdatKey);
4018 Desc->setComdat(ComdatKey);
4019 }
4020 return RegFn;
4021}
4022
4023void CGOpenMPRuntime::createOffloadEntry(
4024 llvm::Constant *ID, llvm::Constant *Addr, uint64_t Size, int32_t Flags,
4025 llvm::GlobalValue::LinkageTypes Linkage) {
4026 StringRef Name = Addr->getName();
4027 llvm::Module &M = CGM.getModule();
4028 llvm::LLVMContext &C = M.getContext();
4029
4030 // Create constant string with the name.
4031 llvm::Constant *StrPtrInit = llvm::ConstantDataArray::getString(C, Name);
4032
4033 std::string StringName = getName({"omp_offloading", "entry_name"});
4034 auto *Str = new llvm::GlobalVariable(
4035 M, StrPtrInit->getType(), /*isConstant=*/true,
4036 llvm::GlobalValue::InternalLinkage, StrPtrInit, StringName);
4037 Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4038
4039 llvm::Constant *Data[] = {llvm::ConstantExpr::getBitCast(ID, CGM.VoidPtrTy),
4040 llvm::ConstantExpr::getBitCast(Str, CGM.Int8PtrTy),
4041 llvm::ConstantInt::get(CGM.SizeTy, Size),
4042 llvm::ConstantInt::get(CGM.Int32Ty, Flags),
4043 llvm::ConstantInt::get(CGM.Int32Ty, 0)};
4044 std::string EntryName = getName({"omp_offloading", "entry", ""});
4045 llvm::GlobalVariable *Entry = createGlobalStruct(
4046 CGM, getTgtOffloadEntryQTy(), /*IsConstant=*/true, Data,
4047 Twine(EntryName).concat(Name), llvm::GlobalValue::WeakAnyLinkage);
4048
4049 // The entry has to be created in the section the linker expects it to be.
4050 std::string Section = getName({"omp_offloading", "entries"});
4051 Entry->setSection(Section);
4052}
4053
4054void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
4055 // Emit the offloading entries and metadata so that the device codegen side
4056 // can easily figure out what to emit. The produced metadata looks like
4057 // this:
4058 //
4059 // !omp_offload.info = !{!1, ...}
4060 //
4061 // Right now we only generate metadata for function that contain target
4062 // regions.
4063
4064 // If we do not have entries, we don't need to do anything.
4065 if (OffloadEntriesInfoManager.empty())
4066 return;
4067
4068 llvm::Module &M = CGM.getModule();
4069 llvm::LLVMContext &C = M.getContext();
4070 SmallVector<const OffloadEntriesInfoManagerTy::OffloadEntryInfo *, 16>
4071 OrderedEntries(OffloadEntriesInfoManager.size());
4072 llvm::SmallVector<StringRef, 16> ParentFunctions(
4073 OffloadEntriesInfoManager.size());
4074
4075 // Auxiliary methods to create metadata values and strings.
4076 auto &&GetMDInt = [this](unsigned V) {
4077 return llvm::ConstantAsMetadata::get(
4078 llvm::ConstantInt::get(CGM.Int32Ty, V));
4079 };
4080
4081 auto &&GetMDString = [&C](StringRef V) { return llvm::MDString::get(C, V); };
4082
4083 // Create the offloading info metadata node.
4084 llvm::NamedMDNode *MD = M.getOrInsertNamedMetadata("omp_offload.info");
4085
4086 // Create function that emits metadata for each target region entry;
4087 auto &&TargetRegionMetadataEmitter =
4088 [&C, MD, &OrderedEntries, &ParentFunctions, &GetMDInt, &GetMDString](
4089 unsigned DeviceID, unsigned FileID, StringRef ParentName,
4090 unsigned Line,
4091 const OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion &E) {
4092 // Generate metadata for target regions. Each entry of this metadata
4093 // contains:
4094 // - Entry 0 -> Kind of this type of metadata (0).
4095 // - Entry 1 -> Device ID of the file where the entry was identified.
4096 // - Entry 2 -> File ID of the file where the entry was identified.
4097 // - Entry 3 -> Mangled name of the function where the entry was
4098 // identified.
4099 // - Entry 4 -> Line in the file where the entry was identified.
4100 // - Entry 5 -> Order the entry was created.
4101 // The first element of the metadata node is the kind.
4102 llvm::Metadata *Ops[] = {GetMDInt(E.getKind()), GetMDInt(DeviceID),
4103 GetMDInt(FileID), GetMDString(ParentName),
4104 GetMDInt(Line), GetMDInt(E.getOrder())};
4105
4106 // Save this entry in the right position of the ordered entries array.
4107 OrderedEntries[E.getOrder()] = &E;
4108 ParentFunctions[E.getOrder()] = ParentName;
4109
4110 // Add metadata to the named metadata node.
4111 MD->addOperand(llvm::MDNode::get(C, Ops));
4112 };
4113
4114 OffloadEntriesInfoManager.actOnTargetRegionEntriesInfo(
4115 TargetRegionMetadataEmitter);
4116
4117 // Create function that emits metadata for each device global variable entry;
4118 auto &&DeviceGlobalVarMetadataEmitter =
4119 [&C, &OrderedEntries, &GetMDInt, &GetMDString,
4120 MD](StringRef MangledName,
4121 const OffloadEntriesInfoManagerTy::OffloadEntryInfoDeviceGlobalVar
4122 &E) {
4123 // Generate metadata for global variables. Each entry of this metadata
4124 // contains:
4125 // - Entry 0 -> Kind of this type of metadata (1).
4126 // - Entry 1 -> Mangled name of the variable.
4127 // - Entry 2 -> Declare target kind.
4128 // - Entry 3 -> Order the entry was created.
4129 // The first element of the metadata node is the kind.
4130 llvm::Metadata *Ops[] = {
4131 GetMDInt(E.getKind()), GetMDString(MangledName),
4132 GetMDInt(E.getFlags()), GetMDInt(E.getOrder())};
4133
4134 // Save this entry in the right position of the ordered entries array.
4135 OrderedEntries[E.getOrder()] = &E;
4136
4137 // Add metadata to the named metadata node.
4138 MD->addOperand(llvm::MDNode::get(C, Ops));
4139 };
4140
4141 OffloadEntriesInfoManager.actOnDeviceGlobalVarEntriesInfo(
4142 DeviceGlobalVarMetadataEmitter);
4143
4144 for (const auto *E : OrderedEntries) {
4145 assert(E && "All ordered entries must exist!")((E && "All ordered entries must exist!") ? static_cast
<void> (0) : __assert_fail ("E && \"All ordered entries must exist!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4145, __PRETTY_FUNCTION__))
;
4146 if (const auto *CE =
4147 dyn_cast<OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion>(
4148 E)) {
4149 if (!CE->getID() || !CE->getAddress()) {
4150 // Do not blame the entry if the parent funtion is not emitted.
4151 StringRef FnName = ParentFunctions[CE->getOrder()];
4152 if (!CGM.GetGlobalValue(FnName))
4153 continue;
4154 unsigned DiagID = CGM.getDiags().getCustomDiagID(
4155 DiagnosticsEngine::Error,
4156 "Offloading entry for target region is incorrect: either the "
4157 "address or the ID is invalid.");
4158 CGM.getDiags().Report(DiagID);
4159 continue;
4160 }
4161 createOffloadEntry(CE->getID(), CE->getAddress(), /*Size=*/0,
4162 CE->getFlags(), llvm::GlobalValue::WeakAnyLinkage);
4163 } else if (const auto *CE =
4164 dyn_cast<OffloadEntriesInfoManagerTy::
4165 OffloadEntryInfoDeviceGlobalVar>(E)) {
4166 OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags =
4167 static_cast<OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind>(
4168 CE->getFlags());
4169 switch (Flags) {
4170 case OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo: {
4171 if (!CE->getAddress()) {
4172 unsigned DiagID = CGM.getDiags().getCustomDiagID(
4173 DiagnosticsEngine::Error,
4174 "Offloading entry for declare target variable is incorrect: the "
4175 "address is invalid.");
4176 CGM.getDiags().Report(DiagID);
4177 continue;
4178 }
4179 // The vaiable has no definition - no need to add the entry.
4180 if (CE->getVarSize().isZero())
4181 continue;
4182 break;
4183 }
4184 case OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryLink:
4185 assert(((CGM.getLangOpts().OpenMPIsDevice && !CE->getAddress()) ||((((CGM.getLangOpts().OpenMPIsDevice && !CE->getAddress
()) || (!CGM.getLangOpts().OpenMPIsDevice && CE->getAddress
())) && "Declaret target link address is set.") ? static_cast
<void> (0) : __assert_fail ("((CGM.getLangOpts().OpenMPIsDevice && !CE->getAddress()) || (!CGM.getLangOpts().OpenMPIsDevice && CE->getAddress())) && \"Declaret target link address is set.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4187, __PRETTY_FUNCTION__))
4186 (!CGM.getLangOpts().OpenMPIsDevice && CE->getAddress())) &&((((CGM.getLangOpts().OpenMPIsDevice && !CE->getAddress
()) || (!CGM.getLangOpts().OpenMPIsDevice && CE->getAddress
())) && "Declaret target link address is set.") ? static_cast
<void> (0) : __assert_fail ("((CGM.getLangOpts().OpenMPIsDevice && !CE->getAddress()) || (!CGM.getLangOpts().OpenMPIsDevice && CE->getAddress())) && \"Declaret target link address is set.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4187, __PRETTY_FUNCTION__))
4187 "Declaret target link address is set.")((((CGM.getLangOpts().OpenMPIsDevice && !CE->getAddress
()) || (!CGM.getLangOpts().OpenMPIsDevice && CE->getAddress
())) && "Declaret target link address is set.") ? static_cast
<void> (0) : __assert_fail ("((CGM.getLangOpts().OpenMPIsDevice && !CE->getAddress()) || (!CGM.getLangOpts().OpenMPIsDevice && CE->getAddress())) && \"Declaret target link address is set.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4187, __PRETTY_FUNCTION__))
;
4188 if (CGM.getLangOpts().OpenMPIsDevice)
4189 continue;
4190 if (!CE->getAddress()) {
4191 unsigned DiagID = CGM.getDiags().getCustomDiagID(
4192 DiagnosticsEngine::Error,
4193 "Offloading entry for declare target variable is incorrect: the "
4194 "address is invalid.");
4195 CGM.getDiags().Report(DiagID);
4196 continue;
4197 }
4198 break;
4199 }
4200 createOffloadEntry(CE->getAddress(), CE->getAddress(),
4201 CE->getVarSize().getQuantity(), Flags,
4202 CE->getLinkage());
4203 } else {
4204 llvm_unreachable("Unsupported entry kind.")::llvm::llvm_unreachable_internal("Unsupported entry kind.", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4204)
;
4205 }
4206 }
4207}
4208
4209/// Loads all the offload entries information from the host IR
4210/// metadata.
4211void CGOpenMPRuntime::loadOffloadInfoMetadata() {
4212 // If we are in target mode, load the metadata from the host IR. This code has
4213 // to match the metadaata creation in createOffloadEntriesAndInfoMetadata().
4214
4215 if (!CGM.getLangOpts().OpenMPIsDevice)
4216 return;
4217
4218 if (CGM.getLangOpts().OMPHostIRFile.empty())
4219 return;
4220
4221 auto Buf = llvm::MemoryBuffer::getFile(CGM.getLangOpts().OMPHostIRFile);
4222 if (auto EC = Buf.getError()) {
4223 CGM.getDiags().Report(diag::err_cannot_open_file)
4224 << CGM.getLangOpts().OMPHostIRFile << EC.message();
4225 return;
4226 }
4227
4228 llvm::LLVMContext C;
4229 auto ME = expectedToErrorOrAndEmitErrors(
4230 C, llvm::parseBitcodeFile(Buf.get()->getMemBufferRef(), C));
4231
4232 if (auto EC = ME.getError()) {
4233 unsigned DiagID = CGM.getDiags().getCustomDiagID(
4234 DiagnosticsEngine::Error, "Unable to parse host IR file '%0':'%1'");
4235 CGM.getDiags().Report(DiagID)
4236 << CGM.getLangOpts().OMPHostIRFile << EC.message();
4237 return;
4238 }
4239
4240 llvm::NamedMDNode *MD = ME.get()->getNamedMetadata("omp_offload.info");
4241 if (!MD)
4242 return;
4243
4244 for (llvm::MDNode *MN : MD->operands()) {
4245 auto &&GetMDInt = [MN](unsigned Idx) {
4246 auto *V = cast<llvm::ConstantAsMetadata>(MN->getOperand(Idx));
4247 return cast<llvm::ConstantInt>(V->getValue())->getZExtValue();
4248 };
4249
4250 auto &&GetMDString = [MN](unsigned Idx) {
4251 auto *V = cast<llvm::MDString>(MN->getOperand(Idx));
4252 return V->getString();
4253 };
4254
4255 switch (GetMDInt(0)) {
4256 default:
4257 llvm_unreachable("Unexpected metadata!")::llvm::llvm_unreachable_internal("Unexpected metadata!", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4257)
;
4258 break;
4259 case OffloadEntriesInfoManagerTy::OffloadEntryInfo::
4260 OffloadingEntryInfoTargetRegion:
4261 OffloadEntriesInfoManager.initializeTargetRegionEntryInfo(
4262 /*DeviceID=*/GetMDInt(1), /*FileID=*/GetMDInt(2),
4263 /*ParentName=*/GetMDString(3), /*Line=*/GetMDInt(4),
4264 /*Order=*/GetMDInt(5));
4265 break;
4266 case OffloadEntriesInfoManagerTy::OffloadEntryInfo::
4267 OffloadingEntryInfoDeviceGlobalVar:
4268 OffloadEntriesInfoManager.initializeDeviceGlobalVarEntryInfo(
4269 /*MangledName=*/GetMDString(1),
4270 static_cast<OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind>(
4271 /*Flags=*/GetMDInt(2)),
4272 /*Order=*/GetMDInt(3));
4273 break;
4274 }
4275 }
4276}
4277
4278void CGOpenMPRuntime::emitKmpRoutineEntryT(QualType KmpInt32Ty) {
4279 if (!KmpRoutineEntryPtrTy) {
4280 // Build typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *); type.
4281 ASTContext &C = CGM.getContext();
4282 QualType KmpRoutineEntryTyArgs[] = {KmpInt32Ty, C.VoidPtrTy};
4283 FunctionProtoType::ExtProtoInfo EPI;
4284 KmpRoutineEntryPtrQTy = C.getPointerType(
4285 C.getFunctionType(KmpInt32Ty, KmpRoutineEntryTyArgs, EPI));
4286 KmpRoutineEntryPtrTy = CGM.getTypes().ConvertType(KmpRoutineEntryPtrQTy);
4287 }
4288}
4289
4290QualType CGOpenMPRuntime::getTgtOffloadEntryQTy() {
4291 // Make sure the type of the entry is already created. This is the type we
4292 // have to create:
4293 // struct __tgt_offload_entry{
4294 // void *addr; // Pointer to the offload entry info.
4295 // // (function or global)
4296 // char *name; // Name of the function or global.
4297 // size_t size; // Size of the entry info (0 if it a function).
4298 // int32_t flags; // Flags associated with the entry, e.g. 'link'.
4299 // int32_t reserved; // Reserved, to use by the runtime library.
4300 // };
4301 if (TgtOffloadEntryQTy.isNull()) {
7
Taking true branch
4302 ASTContext &C = CGM.getContext();
4303 RecordDecl *RD = C.buildImplicitRecord("__tgt_offload_entry");
4304 RD->startDefinition();
4305 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
4306 addFieldToRecordDecl(C, RD, C.getPointerType(C.CharTy));
4307 addFieldToRecordDecl(C, RD, C.getSizeType());
4308 addFieldToRecordDecl(
4309 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
4310 addFieldToRecordDecl(
4311 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
4312 RD->completeDefinition();
4313 RD->addAttr(PackedAttr::CreateImplicit(C));
8
Calling 'PackedAttr::CreateImplicit'
4314 TgtOffloadEntryQTy = C.getRecordType(RD);
4315 }
4316 return TgtOffloadEntryQTy;
4317}
4318
4319QualType CGOpenMPRuntime::getTgtDeviceImageQTy() {
4320 // These are the types we need to build:
4321 // struct __tgt_device_image{
4322 // void *ImageStart; // Pointer to the target code start.
4323 // void *ImageEnd; // Pointer to the target code end.
4324 // // We also add the host entries to the device image, as it may be useful
4325 // // for the target runtime to have access to that information.
4326 // __tgt_offload_entry *EntriesBegin; // Begin of the table with all
4327 // // the entries.
4328 // __tgt_offload_entry *EntriesEnd; // End of the table with all the
4329 // // entries (non inclusive).
4330 // };
4331 if (TgtDeviceImageQTy.isNull()) {
4332 ASTContext &C = CGM.getContext();
4333 RecordDecl *RD = C.buildImplicitRecord("__tgt_device_image");
4334 RD->startDefinition();
4335 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
4336 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
4337 addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
4338 addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
4339 RD->completeDefinition();
4340 TgtDeviceImageQTy = C.getRecordType(RD);
4341 }
4342 return TgtDeviceImageQTy;
4343}
4344
4345QualType CGOpenMPRuntime::getTgtBinaryDescriptorQTy() {
4346 // struct __tgt_bin_desc{
4347 // int32_t NumDevices; // Number of devices supported.
4348 // __tgt_device_image *DeviceImages; // Arrays of device images
4349 // // (one per device).
4350 // __tgt_offload_entry *EntriesBegin; // Begin of the table with all the
4351 // // entries.
4352 // __tgt_offload_entry *EntriesEnd; // End of the table with all the
4353 // // entries (non inclusive).
4354 // };
4355 if (TgtBinaryDescriptorQTy.isNull()) {
4356 ASTContext &C = CGM.getContext();
4357 RecordDecl *RD = C.buildImplicitRecord("__tgt_bin_desc");
4358 RD->startDefinition();
4359 addFieldToRecordDecl(
4360 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
4361 addFieldToRecordDecl(C, RD, C.getPointerType(getTgtDeviceImageQTy()));
4362 addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
4363 addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
4364 RD->completeDefinition();
4365 TgtBinaryDescriptorQTy = C.getRecordType(RD);
4366 }
4367 return TgtBinaryDescriptorQTy;
4368}
4369
4370namespace {
4371struct PrivateHelpersTy {
4372 PrivateHelpersTy(const VarDecl *Original, const VarDecl *PrivateCopy,
4373 const VarDecl *PrivateElemInit)
4374 : Original(Original), PrivateCopy(PrivateCopy),
4375 PrivateElemInit(PrivateElemInit) {}
4376 const VarDecl *Original;
4377 const VarDecl *PrivateCopy;
4378 const VarDecl *PrivateElemInit;
4379};
4380typedef std::pair<CharUnits /*Align*/, PrivateHelpersTy> PrivateDataTy;
4381} // anonymous namespace
4382
4383static RecordDecl *
4384createPrivatesRecordDecl(CodeGenModule &CGM, ArrayRef<PrivateDataTy> Privates) {
4385 if (!Privates.empty()) {
4386 ASTContext &C = CGM.getContext();
4387 // Build struct .kmp_privates_t. {
4388 // /* private vars */
4389 // };
4390 RecordDecl *RD = C.buildImplicitRecord(".kmp_privates.t");
4391 RD->startDefinition();
4392 for (const auto &Pair : Privates) {
4393 const VarDecl *VD = Pair.second.Original;
4394 QualType Type = VD->getType().getNonReferenceType();
4395 FieldDecl *FD = addFieldToRecordDecl(C, RD, Type);
4396 if (VD->hasAttrs()) {
4397 for (specific_attr_iterator<AlignedAttr> I(VD->getAttrs().begin()),
4398 E(VD->getAttrs().end());
4399 I != E; ++I)
4400 FD->addAttr(*I);
4401 }
4402 }
4403 RD->completeDefinition();
4404 return RD;
4405 }
4406 return nullptr;
4407}
4408
4409static RecordDecl *
4410createKmpTaskTRecordDecl(CodeGenModule &CGM, OpenMPDirectiveKind Kind,
4411 QualType KmpInt32Ty,
4412 QualType KmpRoutineEntryPointerQTy) {
4413 ASTContext &C = CGM.getContext();
4414 // Build struct kmp_task_t {
4415 // void * shareds;
4416 // kmp_routine_entry_t routine;
4417 // kmp_int32 part_id;
4418 // kmp_cmplrdata_t data1;
4419 // kmp_cmplrdata_t data2;
4420 // For taskloops additional fields:
4421 // kmp_uint64 lb;
4422 // kmp_uint64 ub;
4423 // kmp_int64 st;
4424 // kmp_int32 liter;
4425 // void * reductions;
4426 // };
4427 RecordDecl *UD = C.buildImplicitRecord("kmp_cmplrdata_t", TTK_Union);
4428 UD->startDefinition();
4429 addFieldToRecordDecl(C, UD, KmpInt32Ty);
4430 addFieldToRecordDecl(C, UD, KmpRoutineEntryPointerQTy);
4431 UD->completeDefinition();
4432 QualType KmpCmplrdataTy = C.getRecordType(UD);
4433 RecordDecl *RD = C.buildImplicitRecord("kmp_task_t");
4434 RD->startDefinition();
4435 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
4436 addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy);
4437 addFieldToRecordDecl(C, RD, KmpInt32Ty);
4438 addFieldToRecordDecl(C, RD, KmpCmplrdataTy);
4439 addFieldToRecordDecl(C, RD, KmpCmplrdataTy);
4440 if (isOpenMPTaskLoopDirective(Kind)) {
4441 QualType KmpUInt64Ty =
4442 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
4443 QualType KmpInt64Ty =
4444 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
4445 addFieldToRecordDecl(C, RD, KmpUInt64Ty);
4446 addFieldToRecordDecl(C, RD, KmpUInt64Ty);
4447 addFieldToRecordDecl(C, RD, KmpInt64Ty);
4448 addFieldToRecordDecl(C, RD, KmpInt32Ty);
4449 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
4450 }
4451 RD->completeDefinition();
4452 return RD;
4453}
4454
4455static RecordDecl *
4456createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy,
4457 ArrayRef<PrivateDataTy> Privates) {
4458 ASTContext &C = CGM.getContext();
4459 // Build struct kmp_task_t_with_privates {
4460 // kmp_task_t task_data;
4461 // .kmp_privates_t. privates;
4462 // };
4463 RecordDecl *RD = C.buildImplicitRecord("kmp_task_t_with_privates");
4464 RD->startDefinition();
4465 addFieldToRecordDecl(C, RD, KmpTaskTQTy);
4466 if (const RecordDecl *PrivateRD = createPrivatesRecordDecl(CGM, Privates))
4467 addFieldToRecordDecl(C, RD, C.getRecordType(PrivateRD));
4468 RD->completeDefinition();
4469 return RD;
4470}
4471
4472/// Emit a proxy function which accepts kmp_task_t as the second
4473/// argument.
4474/// \code
4475/// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
4476/// TaskFunction(gtid, tt->part_id, &tt->privates, task_privates_map, tt,
4477/// For taskloops:
4478/// tt->task_data.lb, tt->task_data.ub, tt->task_data.st, tt->task_data.liter,
4479/// tt->reductions, tt->shareds);
4480/// return 0;
4481/// }
4482/// \endcode
4483static llvm::Function *
4484emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc,
4485 OpenMPDirectiveKind Kind, QualType KmpInt32Ty,
4486 QualType KmpTaskTWithPrivatesPtrQTy,
4487 QualType KmpTaskTWithPrivatesQTy, QualType KmpTaskTQTy,
4488 QualType SharedsPtrTy, llvm::Function *TaskFunction,
4489 llvm::Value *TaskPrivatesMap) {
4490 ASTContext &C = CGM.getContext();
4491 FunctionArgList Args;
4492 ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty,
4493 ImplicitParamDecl::Other);
4494 ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4495 KmpTaskTWithPrivatesPtrQTy.withRestrict(),
4496 ImplicitParamDecl::Other);
4497 Args.push_back(&GtidArg);
4498 Args.push_back(&TaskTypeArg);
4499 const auto &TaskEntryFnInfo =
4500 CGM.getTypes().arrangeBuiltinFunctionDeclaration(KmpInt32Ty, Args);
4501 llvm::FunctionType *TaskEntryTy =
4502 CGM.getTypes().GetFunctionType(TaskEntryFnInfo);
4503 std::string Name = CGM.getOpenMPRuntime().getName({"omp_task_entry", ""});
4504 auto *TaskEntry = llvm::Function::Create(
4505 TaskEntryTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.getModule());
4506 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskEntry, TaskEntryFnInfo);
4507 TaskEntry->setDoesNotRecurse();
4508 CodeGenFunction CGF(CGM);
4509 CGF.StartFunction(GlobalDecl(), KmpInt32Ty, TaskEntry, TaskEntryFnInfo, Args,
4510 Loc, Loc);
4511
4512 // TaskFunction(gtid, tt->task_data.part_id, &tt->privates, task_privates_map,
4513 // tt,
4514 // For taskloops:
4515 // tt->task_data.lb, tt->task_data.ub, tt->task_data.st, tt->task_data.liter,
4516 // tt->task_data.shareds);
4517 llvm::Value *GtidParam = CGF.EmitLoadOfScalar(
4518 CGF.GetAddrOfLocalVar(&GtidArg), /*Volatile=*/false, KmpInt32Ty, Loc);
4519 LValue TDBase = CGF.EmitLoadOfPointerLValue(
4520 CGF.GetAddrOfLocalVar(&TaskTypeArg),
4521 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
4522 const auto *KmpTaskTWithPrivatesQTyRD =
4523 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
4524 LValue Base =
4525 CGF.EmitLValueForField(TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
4526 const auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
4527 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
4528 LValue PartIdLVal = CGF.EmitLValueForField(Base, *PartIdFI);
4529 llvm::Value *PartidParam = PartIdLVal.getPointer();
4530
4531 auto SharedsFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds);
4532 LValue SharedsLVal = CGF.EmitLValueForField(Base, *SharedsFI);
4533 llvm::Value *SharedsParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4534 CGF.EmitLoadOfScalar(SharedsLVal, Loc),
4535 CGF.ConvertTypeForMem(SharedsPtrTy));
4536
4537 auto PrivatesFI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
4538 llvm::Value *PrivatesParam;
4539 if (PrivatesFI != KmpTaskTWithPrivatesQTyRD->field_end()) {
4540 LValue PrivatesLVal = CGF.EmitLValueForField(TDBase, *PrivatesFI);
4541 PrivatesParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4542 PrivatesLVal.getPointer(), CGF.VoidPtrTy);
4543 } else {
4544 PrivatesParam = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
4545 }
4546
4547 llvm::Value *CommonArgs[] = {GtidParam, PartidParam, PrivatesParam,
4548 TaskPrivatesMap,
4549 CGF.Builder
4550 .CreatePointerBitCastOrAddrSpaceCast(
4551 TDBase.getAddress(), CGF.VoidPtrTy)
4552 .getPointer()};
4553 SmallVector<llvm::Value *, 16> CallArgs(std::begin(CommonArgs),
4554 std::end(CommonArgs));
4555 if (isOpenMPTaskLoopDirective(Kind)) {
4556 auto LBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound);
4557 LValue LBLVal = CGF.EmitLValueForField(Base, *LBFI);
4558 llvm::Value *LBParam = CGF.EmitLoadOfScalar(LBLVal, Loc);
4559 auto UBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound);
4560 LValue UBLVal = CGF.EmitLValueForField(Base, *UBFI);
4561 llvm::Value *UBParam = CGF.EmitLoadOfScalar(UBLVal, Loc);
4562 auto StFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTStride);
4563 LValue StLVal = CGF.EmitLValueForField(Base, *StFI);
4564 llvm::Value *StParam = CGF.EmitLoadOfScalar(StLVal, Loc);
4565 auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
4566 LValue LILVal = CGF.EmitLValueForField(Base, *LIFI);
4567 llvm::Value *LIParam = CGF.EmitLoadOfScalar(LILVal, Loc);
4568 auto RFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTReductions);
4569 LValue RLVal = CGF.EmitLValueForField(Base, *RFI);
4570 llvm::Value *RParam = CGF.EmitLoadOfScalar(RLVal, Loc);
4571 CallArgs.push_back(LBParam);
4572 CallArgs.push_back(UBParam);
4573 CallArgs.push_back(StParam);
4574 CallArgs.push_back(LIParam);
4575 CallArgs.push_back(RParam);
4576 }
4577 CallArgs.push_back(SharedsParam);
4578
4579 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskFunction,
4580 CallArgs);
4581 CGF.EmitStoreThroughLValue(RValue::get(CGF.Builder.getInt32(/*C=*/0)),
4582 CGF.MakeAddrLValue(CGF.ReturnValue, KmpInt32Ty));
4583 CGF.FinishFunction();
4584 return TaskEntry;
4585}
4586
4587static llvm::Value *emitDestructorsFunction(CodeGenModule &CGM,
4588 SourceLocation Loc,
4589 QualType KmpInt32Ty,
4590 QualType KmpTaskTWithPrivatesPtrQTy,
4591 QualType KmpTaskTWithPrivatesQTy) {
4592 ASTContext &C = CGM.getContext();
4593 FunctionArgList Args;
4594 ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty,
4595 ImplicitParamDecl::Other);
4596 ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4597 KmpTaskTWithPrivatesPtrQTy.withRestrict(),
4598 ImplicitParamDecl::Other);
4599 Args.push_back(&GtidArg);
4600 Args.push_back(&TaskTypeArg);
4601 const auto &DestructorFnInfo =
4602 CGM.getTypes().arrangeBuiltinFunctionDeclaration(KmpInt32Ty, Args);
4603 llvm::FunctionType *DestructorFnTy =
4604 CGM.getTypes().GetFunctionType(DestructorFnInfo);
4605 std::string Name =
4606 CGM.getOpenMPRuntime().getName({"omp_task_destructor", ""});
4607 auto *DestructorFn =
4608 llvm::Function::Create(DestructorFnTy, llvm::GlobalValue::InternalLinkage,
4609 Name, &CGM.getModule());
4610 CGM.SetInternalFunctionAttributes(GlobalDecl(), DestructorFn,
4611 DestructorFnInfo);
4612 DestructorFn->setDoesNotRecurse();
4613 CodeGenFunction CGF(CGM);
4614 CGF.StartFunction(GlobalDecl(), KmpInt32Ty, DestructorFn, DestructorFnInfo,
4615 Args, Loc, Loc);
4616
4617 LValue Base = CGF.EmitLoadOfPointerLValue(
4618 CGF.GetAddrOfLocalVar(&TaskTypeArg),
4619 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
4620 const auto *KmpTaskTWithPrivatesQTyRD =
4621 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
4622 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
4623 Base = CGF.EmitLValueForField(Base, *FI);
4624 for (const auto *Field :
4625 cast<RecordDecl>(FI->getType()->getAsTagDecl())->fields()) {
4626 if (QualType::DestructionKind DtorKind =
4627 Field->getType().isDestructedType()) {
4628 LValue FieldLValue = CGF.EmitLValueForField(Base, Field);
4629 CGF.pushDestroy(DtorKind, FieldLValue.getAddress(), Field->getType());
4630 }
4631 }
4632 CGF.FinishFunction();
4633 return DestructorFn;
4634}
4635
4636/// Emit a privates mapping function for correct handling of private and
4637/// firstprivate variables.
4638/// \code
4639/// void .omp_task_privates_map.(const .privates. *noalias privs, <ty1>
4640/// **noalias priv1,..., <tyn> **noalias privn) {
4641/// *priv1 = &.privates.priv1;
4642/// ...;
4643/// *privn = &.privates.privn;
4644/// }
4645/// \endcode
4646static llvm::Value *
4647emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc,
4648 ArrayRef<const Expr *> PrivateVars,
4649 ArrayRef<const Expr *> FirstprivateVars,
4650 ArrayRef<const Expr *> LastprivateVars,
4651 QualType PrivatesQTy,
4652 ArrayRef<PrivateDataTy> Privates) {
4653 ASTContext &C = CGM.getContext();
4654 FunctionArgList Args;
4655 ImplicitParamDecl TaskPrivatesArg(
4656 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4657 C.getPointerType(PrivatesQTy).withConst().withRestrict(),
4658 ImplicitParamDecl::Other);
4659 Args.push_back(&TaskPrivatesArg);
4660 llvm::DenseMap<const VarDecl *, unsigned> PrivateVarsPos;
4661 unsigned Counter = 1;
4662 for (const Expr *E : PrivateVars) {
4663 Args.push_back(ImplicitParamDecl::Create(
4664 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4665 C.getPointerType(C.getPointerType(E->getType()))
4666 .withConst()
4667 .withRestrict(),
4668 ImplicitParamDecl::Other));
4669 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4670 PrivateVarsPos[VD] = Counter;
4671 ++Counter;
4672 }
4673 for (const Expr *E : FirstprivateVars) {
4674 Args.push_back(ImplicitParamDecl::Create(
4675 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4676 C.getPointerType(C.getPointerType(E->getType()))
4677 .withConst()
4678 .withRestrict(),
4679 ImplicitParamDecl::Other));
4680 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4681 PrivateVarsPos[VD] = Counter;
4682 ++Counter;
4683 }
4684 for (const Expr *E : LastprivateVars) {
4685 Args.push_back(ImplicitParamDecl::Create(
4686 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4687 C.getPointerType(C.getPointerType(E->getType()))
4688 .withConst()
4689 .withRestrict(),
4690 ImplicitParamDecl::Other));
4691 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4692 PrivateVarsPos[VD] = Counter;
4693 ++Counter;
4694 }
4695 const auto &TaskPrivatesMapFnInfo =
4696 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
4697 llvm::FunctionType *TaskPrivatesMapTy =
4698 CGM.getTypes().GetFunctionType(TaskPrivatesMapFnInfo);
4699 std::string Name =
4700 CGM.getOpenMPRuntime().getName({"omp_task_privates_map", ""});
4701 auto *TaskPrivatesMap = llvm::Function::Create(
4702 TaskPrivatesMapTy, llvm::GlobalValue::InternalLinkage, Name,
4703 &CGM.getModule());
4704 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskPrivatesMap,
4705 TaskPrivatesMapFnInfo);
4706 if (CGM.getLangOpts().Optimize) {
4707 TaskPrivatesMap->removeFnAttr(llvm::Attribute::NoInline);
4708 TaskPrivatesMap->removeFnAttr(llvm::Attribute::OptimizeNone);
4709 TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
4710 }
4711 CodeGenFunction CGF(CGM);
4712 CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskPrivatesMap,
4713 TaskPrivatesMapFnInfo, Args, Loc, Loc);
4714
4715 // *privi = &.privates.privi;
4716 LValue Base = CGF.EmitLoadOfPointerLValue(
4717 CGF.GetAddrOfLocalVar(&TaskPrivatesArg),
4718 TaskPrivatesArg.getType()->castAs<PointerType>());
4719 const auto *PrivatesQTyRD = cast<RecordDecl>(PrivatesQTy->getAsTagDecl());
4720 Counter = 0;
4721 for (const FieldDecl *Field : PrivatesQTyRD->fields()) {
4722 LValue FieldLVal = CGF.EmitLValueForField(Base, Field);
4723 const VarDecl *VD = Args[PrivateVarsPos[Privates[Counter].second.Original]];
4724 LValue RefLVal =
4725 CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(VD), VD->getType());
4726 LValue RefLoadLVal = CGF.EmitLoadOfPointerLValue(
4727 RefLVal.getAddress(), RefLVal.getType()->castAs<PointerType>());
4728 CGF.EmitStoreOfScalar(FieldLVal.getPointer(), RefLoadLVal);
4729 ++Counter;
4730 }
4731 CGF.FinishFunction();
4732 return TaskPrivatesMap;
4733}
4734
4735/// Emit initialization for private variables in task-based directives.
4736static void emitPrivatesInit(CodeGenFunction &CGF,
4737 const OMPExecutableDirective &D,
4738 Address KmpTaskSharedsPtr, LValue TDBase,
4739 const RecordDecl *KmpTaskTWithPrivatesQTyRD,
4740 QualType SharedsTy, QualType SharedsPtrTy,
4741 const OMPTaskDataTy &Data,
4742 ArrayRef<PrivateDataTy> Privates, bool ForDup) {
4743 ASTContext &C = CGF.getContext();
4744 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
4745 LValue PrivatesBase = CGF.EmitLValueForField(TDBase, *FI);
4746 OpenMPDirectiveKind Kind = isOpenMPTaskLoopDirective(D.getDirectiveKind())
4747 ? OMPD_taskloop
4748 : OMPD_task;
4749 const CapturedStmt &CS = *D.getCapturedStmt(Kind);
4750 CodeGenFunction::CGCapturedStmtInfo CapturesInfo(CS);
4751 LValue SrcBase;
4752 bool IsTargetTask =
4753 isOpenMPTargetDataManagementDirective(D.getDirectiveKind()) ||
4754 isOpenMPTargetExecutionDirective(D.getDirectiveKind());
4755 // For target-based directives skip 3 firstprivate arrays BasePointersArray,
4756 // PointersArray and SizesArray. The original variables for these arrays are
4757 // not captured and we get their addresses explicitly.
4758 if ((!IsTargetTask && !Data.FirstprivateVars.empty()) ||
4759 (IsTargetTask && KmpTaskSharedsPtr.isValid())) {
4760 SrcBase = CGF.MakeAddrLValue(
4761 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4762 KmpTaskSharedsPtr, CGF.ConvertTypeForMem(SharedsPtrTy)),
4763 SharedsTy);
4764 }
4765 FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
4766 for (const PrivateDataTy &Pair : Privates) {
4767 const VarDecl *VD = Pair.second.PrivateCopy;
4768 const Expr *Init = VD->getAnyInitializer();
4769 if (Init && (!ForDup || (isa<CXXConstructExpr>(Init) &&
4770 !CGF.isTrivialInitializer(Init)))) {
4771 LValue PrivateLValue = CGF.EmitLValueForField(PrivatesBase, *FI);
4772 if (const VarDecl *Elem = Pair.second.PrivateElemInit) {
4773 const VarDecl *OriginalVD = Pair.second.Original;
4774 // Check if the variable is the target-based BasePointersArray,
4775 // PointersArray or SizesArray.
4776 LValue SharedRefLValue;
4777 QualType Type = PrivateLValue.getType();
4778 const FieldDecl *SharedField = CapturesInfo.lookup(OriginalVD);
4779 if (IsTargetTask && !SharedField) {
4780 assert(isa<ImplicitParamDecl>(OriginalVD) &&((isa<ImplicitParamDecl>(OriginalVD) && isa<
CapturedDecl>(OriginalVD->getDeclContext()) && cast
<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams
() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl
>(OriginalVD->getDeclContext()) ->getDeclContext()) &&
"Expected artificial target data variable.") ? static_cast<
void> (0) : __assert_fail ("isa<ImplicitParamDecl>(OriginalVD) && isa<CapturedDecl>(OriginalVD->getDeclContext()) && cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getDeclContext()) && \"Expected artificial target data variable.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4787, __PRETTY_FUNCTION__))
4781 isa<CapturedDecl>(OriginalVD->getDeclContext()) &&((isa<ImplicitParamDecl>(OriginalVD) && isa<
CapturedDecl>(OriginalVD->getDeclContext()) && cast
<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams
() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl
>(OriginalVD->getDeclContext()) ->getDeclContext()) &&
"Expected artificial target data variable.") ? static_cast<
void> (0) : __assert_fail ("isa<ImplicitParamDecl>(OriginalVD) && isa<CapturedDecl>(OriginalVD->getDeclContext()) && cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getDeclContext()) && \"Expected artificial target data variable.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4787, __PRETTY_FUNCTION__))
4782 cast<CapturedDecl>(OriginalVD->getDeclContext())((isa<ImplicitParamDecl>(OriginalVD) && isa<
CapturedDecl>(OriginalVD->getDeclContext()) && cast
<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams
() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl
>(OriginalVD->getDeclContext()) ->getDeclContext()) &&
"Expected artificial target data variable.") ? static_cast<
void> (0) : __assert_fail ("isa<ImplicitParamDecl>(OriginalVD) && isa<CapturedDecl>(OriginalVD->getDeclContext()) && cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getDeclContext()) && \"Expected artificial target data variable.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4787, __PRETTY_FUNCTION__))
4783 ->getNumParams() == 0 &&((isa<ImplicitParamDecl>(OriginalVD) && isa<
CapturedDecl>(OriginalVD->getDeclContext()) && cast
<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams
() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl
>(OriginalVD->getDeclContext()) ->getDeclContext()) &&
"Expected artificial target data variable.") ? static_cast<
void> (0) : __assert_fail ("isa<ImplicitParamDecl>(OriginalVD) && isa<CapturedDecl>(OriginalVD->getDeclContext()) && cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getDeclContext()) && \"Expected artificial target data variable.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4787, __PRETTY_FUNCTION__))
4784 isa<TranslationUnitDecl>(((isa<ImplicitParamDecl>(OriginalVD) && isa<
CapturedDecl>(OriginalVD->getDeclContext()) && cast
<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams
() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl
>(OriginalVD->getDeclContext()) ->getDeclContext()) &&
"Expected artificial target data variable.") ? static_cast<
void> (0) : __assert_fail ("isa<ImplicitParamDecl>(OriginalVD) && isa<CapturedDecl>(OriginalVD->getDeclContext()) && cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getDeclContext()) && \"Expected artificial target data variable.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4787, __PRETTY_FUNCTION__))
4785 cast<CapturedDecl>(OriginalVD->getDeclContext())((isa<ImplicitParamDecl>(OriginalVD) && isa<
CapturedDecl>(OriginalVD->getDeclContext()) && cast
<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams
() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl
>(OriginalVD->getDeclContext()) ->getDeclContext()) &&
"Expected artificial target data variable.") ? static_cast<
void> (0) : __assert_fail ("isa<ImplicitParamDecl>(OriginalVD) && isa<CapturedDecl>(OriginalVD->getDeclContext()) && cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getDeclContext()) && \"Expected artificial target data variable.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4787, __PRETTY_FUNCTION__))
4786 ->getDeclContext()) &&((isa<ImplicitParamDecl>(OriginalVD) && isa<
CapturedDecl>(OriginalVD->getDeclContext()) && cast
<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams
() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl
>(OriginalVD->getDeclContext()) ->getDeclContext()) &&
"Expected artificial target data variable.") ? static_cast<
void> (0) : __assert_fail ("isa<ImplicitParamDecl>(OriginalVD) && isa<CapturedDecl>(OriginalVD->getDeclContext()) && cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getDeclContext()) && \"Expected artificial target data variable.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4787, __PRETTY_FUNCTION__))
4787 "Expected artificial target data variable.")((isa<ImplicitParamDecl>(OriginalVD) && isa<
CapturedDecl>(OriginalVD->getDeclContext()) && cast
<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams
() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl
>(OriginalVD->getDeclContext()) ->getDeclContext()) &&
"Expected artificial target data variable.") ? static_cast<
void> (0) : __assert_fail ("isa<ImplicitParamDecl>(OriginalVD) && isa<CapturedDecl>(OriginalVD->getDeclContext()) && cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getNumParams() == 0 && isa<TranslationUnitDecl>( cast<CapturedDecl>(OriginalVD->getDeclContext()) ->getDeclContext()) && \"Expected artificial target data variable.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4787, __PRETTY_FUNCTION__))
;
4788 SharedRefLValue =
4789 CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(OriginalVD), Type);
4790 } else {
4791 SharedRefLValue = CGF.EmitLValueForField(SrcBase, SharedField);
4792 SharedRefLValue = CGF.MakeAddrLValue(
4793 Address(SharedRefLValue.getPointer(), C.getDeclAlign(OriginalVD)),
4794 SharedRefLValue.getType(), LValueBaseInfo(AlignmentSource::Decl),
4795 SharedRefLValue.getTBAAInfo());
4796 }
4797 if (Type->isArrayType()) {
4798 // Initialize firstprivate array.
4799 if (!isa<CXXConstructExpr>(Init) || CGF.isTrivialInitializer(Init)) {
4800 // Perform simple memcpy.
4801 CGF.EmitAggregateAssign(PrivateLValue, SharedRefLValue, Type);
4802 } else {
4803 // Initialize firstprivate array using element-by-element
4804 // initialization.
4805 CGF.EmitOMPAggregateAssign(
4806 PrivateLValue.getAddress(), SharedRefLValue.getAddress(), Type,
4807 [&CGF, Elem, Init, &CapturesInfo](Address DestElement,
4808 Address SrcElement) {
4809 // Clean up any temporaries needed by the initialization.
4810 CodeGenFunction::OMPPrivateScope InitScope(CGF);
4811 InitScope.addPrivate(
4812 Elem, [SrcElement]() -> Address { return SrcElement; });
4813 (void)InitScope.Privatize();
4814 // Emit initialization for single element.
4815 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(
4816 CGF, &CapturesInfo);
4817 CGF.EmitAnyExprToMem(Init, DestElement,
4818 Init->getType().getQualifiers(),
4819 /*IsInitializer=*/false);
4820 });
4821 }
4822 } else {
4823 CodeGenFunction::OMPPrivateScope InitScope(CGF);
4824 InitScope.addPrivate(Elem, [SharedRefLValue]() -> Address {
4825 return SharedRefLValue.getAddress();
4826 });
4827 (void)InitScope.Privatize();
4828 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CapturesInfo);
4829 CGF.EmitExprAsInit(Init, VD, PrivateLValue,
4830 /*capturedByInit=*/false);
4831 }
4832 } else {
4833 CGF.EmitExprAsInit(Init, VD, PrivateLValue, /*capturedByInit=*/false);
4834 }
4835 }
4836 ++FI;
4837 }
4838}
4839
4840/// Check if duplication function is required for taskloops.
4841static bool checkInitIsRequired(CodeGenFunction &CGF,
4842 ArrayRef<PrivateDataTy> Privates) {
4843 bool InitRequired = false;
4844 for (const PrivateDataTy &Pair : Privates) {
4845 const VarDecl *VD = Pair.second.PrivateCopy;
4846 const Expr *Init = VD->getAnyInitializer();
4847 InitRequired = InitRequired || (Init && isa<CXXConstructExpr>(Init) &&
4848 !CGF.isTrivialInitializer(Init));
4849 if (InitRequired)
4850 break;
4851 }
4852 return InitRequired;
4853}
4854
4855
4856/// Emit task_dup function (for initialization of
4857/// private/firstprivate/lastprivate vars and last_iter flag)
4858/// \code
4859/// void __task_dup_entry(kmp_task_t *task_dst, const kmp_task_t *task_src, int
4860/// lastpriv) {
4861/// // setup lastprivate flag
4862/// task_dst->last = lastpriv;
4863/// // could be constructor calls here...
4864/// }
4865/// \endcode
4866static llvm::Value *
4867emitTaskDupFunction(CodeGenModule &CGM, SourceLocation Loc,
4868 const OMPExecutableDirective &D,
4869 QualType KmpTaskTWithPrivatesPtrQTy,
4870 const RecordDecl *KmpTaskTWithPrivatesQTyRD,
4871 const RecordDecl *KmpTaskTQTyRD, QualType SharedsTy,
4872 QualType SharedsPtrTy, const OMPTaskDataTy &Data,
4873 ArrayRef<PrivateDataTy> Privates, bool WithLastIter) {
4874 ASTContext &C = CGM.getContext();
4875 FunctionArgList Args;
4876 ImplicitParamDecl DstArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4877 KmpTaskTWithPrivatesPtrQTy,
4878 ImplicitParamDecl::Other);
4879 ImplicitParamDecl SrcArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4880 KmpTaskTWithPrivatesPtrQTy,
4881 ImplicitParamDecl::Other);
4882 ImplicitParamDecl LastprivArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.IntTy,
4883 ImplicitParamDecl::Other);
4884 Args.push_back(&DstArg);
4885 Args.push_back(&SrcArg);
4886 Args.push_back(&LastprivArg);
4887 const auto &TaskDupFnInfo =
4888 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
4889 llvm::FunctionType *TaskDupTy = CGM.getTypes().GetFunctionType(TaskDupFnInfo);
4890 std::string Name = CGM.getOpenMPRuntime().getName({"omp_task_dup", ""});
4891 auto *TaskDup = llvm::Function::Create(
4892 TaskDupTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.getModule());
4893 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskDup, TaskDupFnInfo);
4894 TaskDup->setDoesNotRecurse();
4895 CodeGenFunction CGF(CGM);
4896 CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskDup, TaskDupFnInfo, Args, Loc,
4897 Loc);
4898
4899 LValue TDBase = CGF.EmitLoadOfPointerLValue(
4900 CGF.GetAddrOfLocalVar(&DstArg),
4901 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
4902 // task_dst->liter = lastpriv;
4903 if (WithLastIter) {
4904 auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
4905 LValue Base = CGF.EmitLValueForField(
4906 TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
4907 LValue LILVal = CGF.EmitLValueForField(Base, *LIFI);
4908 llvm::Value *Lastpriv = CGF.EmitLoadOfScalar(
4909 CGF.GetAddrOfLocalVar(&LastprivArg), /*Volatile=*/false, C.IntTy, Loc);
4910 CGF.EmitStoreOfScalar(Lastpriv, LILVal);
4911 }
4912
4913 // Emit initial values for private copies (if any).
4914 assert(!Privates.empty())((!Privates.empty()) ? static_cast<void> (0) : __assert_fail
("!Privates.empty()", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 4914, __PRETTY_FUNCTION__))
;
4915 Address KmpTaskSharedsPtr = Address::invalid();
4916 if (!Data.FirstprivateVars.empty()) {
4917 LValue TDBase = CGF.EmitLoadOfPointerLValue(
4918 CGF.GetAddrOfLocalVar(&SrcArg),
4919 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
4920 LValue Base = CGF.EmitLValueForField(
4921 TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
4922 KmpTaskSharedsPtr = Address(
4923 CGF.EmitLoadOfScalar(CGF.EmitLValueForField(
4924 Base, *std::next(KmpTaskTQTyRD->field_begin(),
4925 KmpTaskTShareds)),
4926 Loc),
4927 CGF.getNaturalTypeAlignment(SharedsTy));
4928 }
4929 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, TDBase, KmpTaskTWithPrivatesQTyRD,
4930 SharedsTy, SharedsPtrTy, Data, Privates, /*ForDup=*/true);
4931 CGF.FinishFunction();
4932 return TaskDup;
4933}
4934
4935/// Checks if destructor function is required to be generated.
4936/// \return true if cleanups are required, false otherwise.
4937static bool
4938checkDestructorsRequired(const RecordDecl *KmpTaskTWithPrivatesQTyRD) {
4939 bool NeedsCleanup = false;
4940 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
4941 const auto *PrivateRD = cast<RecordDecl>(FI->getType()->getAsTagDecl());
4942 for (const FieldDecl *FD : PrivateRD->fields()) {
4943 NeedsCleanup = NeedsCleanup || FD->getType().isDestructedType();
4944 if (NeedsCleanup)
4945 break;
4946 }
4947 return NeedsCleanup;
4948}
4949
4950CGOpenMPRuntime::TaskResultTy
4951CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
4952 const OMPExecutableDirective &D,
4953 llvm::Function *TaskFunction, QualType SharedsTy,
4954 Address Shareds, const OMPTaskDataTy &Data) {
4955 ASTContext &C = CGM.getContext();
4956 llvm::SmallVector<PrivateDataTy, 4> Privates;
4957 // Aggregate privates and sort them by the alignment.
4958 auto I = Data.PrivateCopies.begin();
4959 for (const Expr *E : Data.PrivateVars) {
4960 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4961 Privates.emplace_back(
4962 C.getDeclAlign(VD),
4963 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4964 /*PrivateElemInit=*/nullptr));
4965 ++I;
4966 }
4967 I = Data.FirstprivateCopies.begin();
4968 auto IElemInitRef = Data.FirstprivateInits.begin();
4969 for (const Expr *E : Data.FirstprivateVars) {
4970 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4971 Privates.emplace_back(
4972 C.getDeclAlign(VD),
4973 PrivateHelpersTy(
4974 VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4975 cast<VarDecl>(cast<DeclRefExpr>(*IElemInitRef)->getDecl())));
4976 ++I;
4977 ++IElemInitRef;
4978 }
4979 I = Data.LastprivateCopies.begin();
4980 for (const Expr *E : Data.LastprivateVars) {
4981 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4982 Privates.emplace_back(
4983 C.getDeclAlign(VD),
4984 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4985 /*PrivateElemInit=*/nullptr));
4986 ++I;
4987 }
4988 llvm::stable_sort(Privates, [](PrivateDataTy L, PrivateDataTy R) {
4989 return L.first > R.first;
4990 });
4991 QualType KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
4992 // Build type kmp_routine_entry_t (if not built yet).
4993 emitKmpRoutineEntryT(KmpInt32Ty);
4994 // Build type kmp_task_t (if not built yet).
4995 if (isOpenMPTaskLoopDirective(D.getDirectiveKind())) {
4996 if (SavedKmpTaskloopTQTy.isNull()) {
4997 SavedKmpTaskloopTQTy = C.getRecordType(createKmpTaskTRecordDecl(
4998 CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
4999 }
5000 KmpTaskTQTy = SavedKmpTaskloopTQTy;
5001 } else {
5002 assert((D.getDirectiveKind() == OMPD_task ||(((D.getDirectiveKind() == OMPD_task || isOpenMPTargetExecutionDirective
(D.getDirectiveKind()) || isOpenMPTargetDataManagementDirective
(D.getDirectiveKind())) && "Expected taskloop, task or target directive"
) ? static_cast<void> (0) : __assert_fail ("(D.getDirectiveKind() == OMPD_task || isOpenMPTargetExecutionDirective(D.getDirectiveKind()) || isOpenMPTargetDataManagementDirective(D.getDirectiveKind())) && \"Expected taskloop, task or target directive\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 5005, __PRETTY_FUNCTION__))
5003 isOpenMPTargetExecutionDirective(D.getDirectiveKind()) ||(((D.getDirectiveKind() == OMPD_task || isOpenMPTargetExecutionDirective
(D.getDirectiveKind()) || isOpenMPTargetDataManagementDirective
(D.getDirectiveKind())) && "Expected taskloop, task or target directive"
) ? static_cast<void> (0) : __assert_fail ("(D.getDirectiveKind() == OMPD_task || isOpenMPTargetExecutionDirective(D.getDirectiveKind()) || isOpenMPTargetDataManagementDirective(D.getDirectiveKind())) && \"Expected taskloop, task or target directive\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 5005, __PRETTY_FUNCTION__))
5004 isOpenMPTargetDataManagementDirective(D.getDirectiveKind())) &&(((D.getDirectiveKind() == OMPD_task || isOpenMPTargetExecutionDirective
(D.getDirectiveKind()) || isOpenMPTargetDataManagementDirective
(D.getDirectiveKind())) && "Expected taskloop, task or target directive"
) ? static_cast<void> (0) : __assert_fail ("(D.getDirectiveKind() == OMPD_task || isOpenMPTargetExecutionDirective(D.getDirectiveKind()) || isOpenMPTargetDataManagementDirective(D.getDirectiveKind())) && \"Expected taskloop, task or target directive\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 5005, __PRETTY_FUNCTION__))
5005 "Expected taskloop, task or target directive")(((D.getDirectiveKind() == OMPD_task || isOpenMPTargetExecutionDirective
(D.getDirectiveKind()) || isOpenMPTargetDataManagementDirective
(D.getDirectiveKind())) && "Expected taskloop, task or target directive"
) ? static_cast<void> (0) : __assert_fail ("(D.getDirectiveKind() == OMPD_task || isOpenMPTargetExecutionDirective(D.getDirectiveKind()) || isOpenMPTargetDataManagementDirective(D.getDirectiveKind())) && \"Expected taskloop, task or target directive\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 5005, __PRETTY_FUNCTION__))
;
5006 if (SavedKmpTaskTQTy.isNull()) {
5007 SavedKmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl(
5008 CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
5009 }
5010 KmpTaskTQTy = SavedKmpTaskTQTy;
5011 }
5012 const auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
5013 // Build particular struct kmp_task_t for the given task.
5014 const RecordDecl *KmpTaskTWithPrivatesQTyRD =
5015 createKmpTaskTWithPrivatesRecordDecl(CGM, KmpTaskTQTy, Privates);
5016 QualType KmpTaskTWithPrivatesQTy = C.getRecordType(KmpTaskTWithPrivatesQTyRD);
5017 QualType KmpTaskTWithPrivatesPtrQTy =
5018 C.getPointerType(KmpTaskTWithPrivatesQTy);
5019 llvm::Type *KmpTaskTWithPrivatesTy = CGF.ConvertType(KmpTaskTWithPrivatesQTy);
5020 llvm::Type *KmpTaskTWithPrivatesPtrTy =
5021 KmpTaskTWithPrivatesTy->getPointerTo();
5022 llvm::Value *KmpTaskTWithPrivatesTySize =
5023 CGF.getTypeSize(KmpTaskTWithPrivatesQTy);
5024 QualType SharedsPtrTy = C.getPointerType(SharedsTy);
5025
5026 // Emit initial values for private copies (if any).
5027 llvm::Value *TaskPrivatesMap = nullptr;
5028 llvm::Type *TaskPrivatesMapTy =
5029 std::next(TaskFunction->arg_begin(), 3)->getType();
5030 if (!Privates.empty()) {
5031 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
5032 TaskPrivatesMap = emitTaskPrivateMappingFunction(
5033 CGM, Loc, Data.PrivateVars, Data.FirstprivateVars, Data.LastprivateVars,
5034 FI->getType(), Privates);
5035 TaskPrivatesMap = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5036 TaskPrivatesMap, TaskPrivatesMapTy);
5037 } else {
5038 TaskPrivatesMap = llvm::ConstantPointerNull::get(
5039 cast<llvm::PointerType>(TaskPrivatesMapTy));
5040 }
5041 // Build a proxy function kmp_int32 .omp_task_entry.(kmp_int32 gtid,
5042 // kmp_task_t *tt);
5043 llvm::Function *TaskEntry = emitProxyTaskFunction(
5044 CGM, Loc, D.getDirectiveKind(), KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
5045 KmpTaskTWithPrivatesQTy, KmpTaskTQTy, SharedsPtrTy, TaskFunction,
5046 TaskPrivatesMap);
5047
5048 // Build call kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
5049 // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
5050 // kmp_routine_entry_t *task_entry);
5051 // Task flags. Format is taken from
5052 // https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h,
5053 // description of kmp_tasking_flags struct.
5054 enum {
5055 TiedFlag = 0x1,
5056 FinalFlag = 0x2,
5057 DestructorsFlag = 0x8,
5058 PriorityFlag = 0x20
5059 };
5060 unsigned Flags = Data.Tied ? TiedFlag : 0;
5061 bool NeedsCleanup = false;
5062 if (!Privates.empty()) {
5063 NeedsCleanup = checkDestructorsRequired(KmpTaskTWithPrivatesQTyRD);
5064 if (NeedsCleanup)
5065 Flags = Flags | DestructorsFlag;
5066 }
5067 if (Data.Priority.getInt())
5068 Flags = Flags | PriorityFlag;
5069 llvm::Value *TaskFlags =
5070 Data.Final.getPointer()
5071 ? CGF.Builder.CreateSelect(Data.Final.getPointer(),
5072 CGF.Builder.getInt32(FinalFlag),
5073 CGF.Builder.getInt32(/*C=*/0))
5074 : CGF.Builder.getInt32(Data.Final.getInt() ? FinalFlag : 0);
5075 TaskFlags = CGF.Builder.CreateOr(TaskFlags, CGF.Builder.getInt32(Flags));
5076 llvm::Value *SharedsSize = CGM.getSize(C.getTypeSizeInChars(SharedsTy));
5077 llvm::Value *AllocArgs[] = {emitUpdateLocation(CGF, Loc),
5078 getThreadID(CGF, Loc), TaskFlags,
5079 KmpTaskTWithPrivatesTySize, SharedsSize,
5080 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5081 TaskEntry, KmpRoutineEntryPtrTy)};
5082 llvm::Value *NewTask = CGF.EmitRuntimeCall(
5083 createRuntimeFunction(OMPRTL__kmpc_omp_task_alloc), AllocArgs);
5084 llvm::Value *NewTaskNewTaskTTy =
5085 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5086 NewTask, KmpTaskTWithPrivatesPtrTy);
5087 LValue Base = CGF.MakeNaturalAlignAddrLValue(NewTaskNewTaskTTy,
5088 KmpTaskTWithPrivatesQTy);
5089 LValue TDBase =
5090 CGF.EmitLValueForField(Base, *KmpTaskTWithPrivatesQTyRD->field_begin());
5091 // Fill the data in the resulting kmp_task_t record.
5092 // Copy shareds if there are any.
5093 Address KmpTaskSharedsPtr = Address::invalid();
5094 if (!SharedsTy->getAsStructureType()->getDecl()->field_empty()) {
5095 KmpTaskSharedsPtr =
5096 Address(CGF.EmitLoadOfScalar(
5097 CGF.EmitLValueForField(
5098 TDBase, *std::next(KmpTaskTQTyRD->field_begin(),
5099 KmpTaskTShareds)),
5100 Loc),
5101 CGF.getNaturalTypeAlignment(SharedsTy));
5102 LValue Dest = CGF.MakeAddrLValue(KmpTaskSharedsPtr, SharedsTy);
5103 LValue Src = CGF.MakeAddrLValue(Shareds, SharedsTy);
5104 CGF.EmitAggregateCopy(Dest, Src, SharedsTy, AggValueSlot::DoesNotOverlap);
5105 }
5106 // Emit initial values for private copies (if any).
5107 TaskResultTy Result;
5108 if (!Privates.empty()) {
5109 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, Base, KmpTaskTWithPrivatesQTyRD,
5110 SharedsTy, SharedsPtrTy, Data, Privates,
5111 /*ForDup=*/false);
5112 if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) &&
5113 (!Data.LastprivateVars.empty() || checkInitIsRequired(CGF, Privates))) {
5114 Result.TaskDupFn = emitTaskDupFunction(
5115 CGM, Loc, D, KmpTaskTWithPrivatesPtrQTy, KmpTaskTWithPrivatesQTyRD,
5116 KmpTaskTQTyRD, SharedsTy, SharedsPtrTy, Data, Privates,
5117 /*WithLastIter=*/!Data.LastprivateVars.empty());
5118 }
5119 }
5120 // Fields of union "kmp_cmplrdata_t" for destructors and priority.
5121 enum { Priority = 0, Destructors = 1 };
5122 // Provide pointer to function with destructors for privates.
5123 auto FI = std::next(KmpTaskTQTyRD->field_begin(), Data1);
5124 const RecordDecl *KmpCmplrdataUD =
5125 (*FI)->getType()->getAsUnionType()->getDecl();
5126 if (NeedsCleanup) {
5127 llvm::Value *DestructorFn = emitDestructorsFunction(
5128 CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
5129 KmpTaskTWithPrivatesQTy);
5130 LValue Data1LV = CGF.EmitLValueForField(TDBase, *FI);
5131 LValue DestructorsLV = CGF.EmitLValueForField(
5132 Data1LV, *std::next(KmpCmplrdataUD->field_begin(), Destructors));
5133 CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5134 DestructorFn, KmpRoutineEntryPtrTy),
5135 DestructorsLV);
5136 }
5137 // Set priority.
5138 if (Data.Priority.getInt()) {
5139 LValue Data2LV = CGF.EmitLValueForField(
5140 TDBase, *std::next(KmpTaskTQTyRD->field_begin(), Data2));
5141 LValue PriorityLV = CGF.EmitLValueForField(
5142 Data2LV, *std::next(KmpCmplrdataUD->field_begin(), Priority));
5143 CGF.EmitStoreOfScalar(Data.Priority.getPointer(), PriorityLV);
5144 }
5145 Result.NewTask = NewTask;
5146 Result.TaskEntry = TaskEntry;
5147 Result.NewTaskNewTaskTTy = NewTaskNewTaskTTy;
5148 Result.TDBase = TDBase;
5149 Result.KmpTaskTQTyRD = KmpTaskTQTyRD;
5150 return Result;
5151}
5152
5153void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
5154 const OMPExecutableDirective &D,
5155 llvm::Function *TaskFunction,
5156 QualType SharedsTy, Address Shareds,
5157 const Expr *IfCond,
5158 const OMPTaskDataTy &Data) {
5159 if (!CGF.HaveInsertPoint())
5160 return;
5161
5162 TaskResultTy Result =
5163 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
5164 llvm::Value *NewTask = Result.NewTask;
5165 llvm::Function *TaskEntry = Result.TaskEntry;
5166 llvm::Value *NewTaskNewTaskTTy = Result.NewTaskNewTaskTTy;
5167 LValue TDBase = Result.TDBase;
5168 const RecordDecl *KmpTaskTQTyRD = Result.KmpTaskTQTyRD;
5169 ASTContext &C = CGM.getContext();
5170 // Process list of dependences.
5171 Address DependenciesArray = Address::invalid();
5172 unsigned NumDependencies = Data.Dependences.size();
5173 if (NumDependencies) {
5174 // Dependence kind for RTL.
5175 enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3, DepMutexInOutSet = 0x4 };
5176 enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags };
5177 RecordDecl *KmpDependInfoRD;
5178 QualType FlagsTy =
5179 C.getIntTypeForBitwidth(C.getTypeSize(C.BoolTy), /*Signed=*/false);
5180 llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy);
5181 if (KmpDependInfoTy.isNull()) {
5182 KmpDependInfoRD = C.buildImplicitRecord("kmp_depend_info");
5183 KmpDependInfoRD->startDefinition();
5184 addFieldToRecordDecl(C, KmpDependInfoRD, C.getIntPtrType());
5185 addFieldToRecordDecl(C, KmpDependInfoRD, C.getSizeType());
5186 addFieldToRecordDecl(C, KmpDependInfoRD, FlagsTy);
5187 KmpDependInfoRD->completeDefinition();
5188 KmpDependInfoTy = C.getRecordType(KmpDependInfoRD);
5189 } else {
5190 KmpDependInfoRD = cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
5191 }
5192 // Define type kmp_depend_info[<Dependences.size()>];
5193 QualType KmpDependInfoArrayTy = C.getConstantArrayType(
5194 KmpDependInfoTy, llvm::APInt(/*numBits=*/64, NumDependencies),
5195 ArrayType::Normal, /*IndexTypeQuals=*/0);
5196 // kmp_depend_info[<Dependences.size()>] deps;
5197 DependenciesArray =
5198 CGF.CreateMemTemp(KmpDependInfoArrayTy, ".dep.arr.addr");
5199 for (unsigned I = 0; I < NumDependencies; ++I) {
5200 const Expr *E = Data.Dependences[I].second;
5201 LValue Addr = CGF.EmitLValue(E);
5202 llvm::Value *Size;
5203 QualType Ty = E->getType();
5204 if (const auto *ASE =
5205 dyn_cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts())) {
5206 LValue UpAddrLVal =
5207 CGF.EmitOMPArraySectionExpr(ASE, /*LowerBound=*/false);
5208 llvm::Value *UpAddr =
5209 CGF.Builder.CreateConstGEP1_32(UpAddrLVal.getPointer(), /*Idx0=*/1);
5210 llvm::Value *LowIntPtr =
5211 CGF.Builder.CreatePtrToInt(Addr.getPointer(), CGM.SizeTy);
5212 llvm::Value *UpIntPtr = CGF.Builder.CreatePtrToInt(UpAddr, CGM.SizeTy);
5213 Size = CGF.Builder.CreateNUWSub(UpIntPtr, LowIntPtr);
5214 } else {
5215 Size = CGF.getTypeSize(Ty);
5216 }
5217 LValue Base = CGF.MakeAddrLValue(
5218 CGF.Builder.CreateConstArrayGEP(DependenciesArray, I),
5219 KmpDependInfoTy);
5220 // deps[i].base_addr = &<Dependences[i].second>;
5221 LValue BaseAddrLVal = CGF.EmitLValueForField(
5222 Base, *std::next(KmpDependInfoRD->field_begin(), BaseAddr));
5223 CGF.EmitStoreOfScalar(
5224 CGF.Builder.CreatePtrToInt(Addr.getPointer(), CGF.IntPtrTy),
5225 BaseAddrLVal);
5226 // deps[i].len = sizeof(<Dependences[i].second>);
5227 LValue LenLVal = CGF.EmitLValueForField(
5228 Base, *std::next(KmpDependInfoRD->field_begin(), Len));
5229 CGF.EmitStoreOfScalar(Size, LenLVal);
5230 // deps[i].flags = <Dependences[i].first>;
5231 RTLDependenceKindTy DepKind;
5232 switch (Data.Dependences[I].first) {
5233 case OMPC_DEPEND_in:
5234 DepKind = DepIn;
5235 break;
5236 // Out and InOut dependencies must use the same code.
5237 case OMPC_DEPEND_out:
5238 case OMPC_DEPEND_inout:
5239 DepKind = DepInOut;
5240 break;
5241 case OMPC_DEPEND_mutexinoutset:
5242 DepKind = DepMutexInOutSet;
5243 break;
5244 case OMPC_DEPEND_source:
5245 case OMPC_DEPEND_sink:
5246 case OMPC_DEPEND_unknown:
5247 llvm_unreachable("Unknown task dependence type")::llvm::llvm_unreachable_internal("Unknown task dependence type"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 5247)
;
5248 }
5249 LValue FlagsLVal = CGF.EmitLValueForField(
5250 Base, *std::next(KmpDependInfoRD->field_begin(), Flags));
5251 CGF.EmitStoreOfScalar(llvm::ConstantInt::get(LLVMFlagsTy, DepKind),
5252 FlagsLVal);
5253 }
5254 DependenciesArray = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5255 CGF.Builder.CreateConstArrayGEP(DependenciesArray, 0), CGF.VoidPtrTy);
5256 }
5257
5258 // NOTE: routine and part_id fields are initialized by __kmpc_omp_task_alloc()
5259 // libcall.
5260 // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid,
5261 // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
5262 // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list) if dependence
5263 // list is not empty
5264 llvm::Value *ThreadID = getThreadID(CGF, Loc);
5265 llvm::Value *UpLoc = emitUpdateLocation(CGF, Loc);
5266 llvm::Value *TaskArgs[] = { UpLoc, ThreadID, NewTask };
5267 llvm::Value *DepTaskArgs[7];
5268 if (NumDependencies) {
5269 DepTaskArgs[0] = UpLoc;
5270 DepTaskArgs[1] = ThreadID;
5271 DepTaskArgs[2] = NewTask;
5272 DepTaskArgs[3] = CGF.Builder.getInt32(NumDependencies);
5273 DepTaskArgs[4] = DependenciesArray.getPointer();
5274 DepTaskArgs[5] = CGF.Builder.getInt32(0);
5275 DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5276 }
5277 auto &&ThenCodeGen = [this, &Data, TDBase, KmpTaskTQTyRD, NumDependencies,
5278 &TaskArgs,
5279 &DepTaskArgs](CodeGenFunction &CGF, PrePostActionTy &) {
5280 if (!Data.Tied) {
5281 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
5282 LValue PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI);
5283 CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal);
5284 }
5285 if (NumDependencies) {
5286 CGF.EmitRuntimeCall(
5287 createRuntimeFunction(OMPRTL__kmpc_omp_task_with_deps), DepTaskArgs);
5288 } else {
5289 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task),
5290 TaskArgs);
5291 }
5292 // Check if parent region is untied and build return for untied task;
5293 if (auto *Region =
5294 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
5295 Region->emitUntiedSwitch(CGF);
5296 };
5297
5298 llvm::Value *DepWaitTaskArgs[6];
5299 if (NumDependencies) {
5300 DepWaitTaskArgs[0] = UpLoc;
5301 DepWaitTaskArgs[1] = ThreadID;
5302 DepWaitTaskArgs[2] = CGF.Builder.getInt32(NumDependencies);
5303 DepWaitTaskArgs[3] = DependenciesArray.getPointer();
5304 DepWaitTaskArgs[4] = CGF.Builder.getInt32(0);
5305 DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5306 }
5307 auto &&ElseCodeGen = [&TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry,
5308 NumDependencies, &DepWaitTaskArgs,
5309 Loc](CodeGenFunction &CGF, PrePostActionTy &) {
5310 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
5311 CodeGenFunction::RunCleanupsScope LocalScope(CGF);
5312 // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
5313 // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
5314 // ndeps_noalias, kmp_depend_info_t *noalias_dep_list); if dependence info
5315 // is specified.
5316 if (NumDependencies)
5317 CGF.EmitRuntimeCall(RT.createRuntimeFunction(OMPRTL__kmpc_omp_wait_deps),
5318 DepWaitTaskArgs);
5319 // Call proxy_task_entry(gtid, new_task);
5320 auto &&CodeGen = [TaskEntry, ThreadID, NewTaskNewTaskTTy,
5321 Loc](CodeGenFunction &CGF, PrePostActionTy &Action) {
5322 Action.Enter(CGF);
5323 llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy};
5324 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskEntry,
5325 OutlinedFnArgs);
5326 };
5327
5328 // Build void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
5329 // kmp_task_t *new_task);
5330 // Build void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid,
5331 // kmp_task_t *new_task);
5332 RegionCodeGenTy RCG(CodeGen);
5333 CommonActionTy Action(
5334 RT.createRuntimeFunction(OMPRTL__kmpc_omp_task_begin_if0), TaskArgs,
5335 RT.createRuntimeFunction(OMPRTL__kmpc_omp_task_complete_if0), TaskArgs);
5336 RCG.setAction(Action);
5337 RCG(CGF);
5338 };
5339
5340 if (IfCond) {
5341 emitOMPIfClause(CGF, IfCond, ThenCodeGen, ElseCodeGen);
5342 } else {
5343 RegionCodeGenTy ThenRCG(ThenCodeGen);
5344 ThenRCG(CGF);
5345 }
5346}
5347
5348void CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
5349 const OMPLoopDirective &D,
5350 llvm::Function *TaskFunction,
5351 QualType SharedsTy, Address Shareds,
5352 const Expr *IfCond,
5353 const OMPTaskDataTy &Data) {
5354 if (!CGF.HaveInsertPoint())
5355 return;
5356 TaskResultTy Result =
5357 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
5358 // NOTE: routine and part_id fields are initialized by __kmpc_omp_task_alloc()
5359 // libcall.
5360 // Call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
5361 // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
5362 // sched, kmp_uint64 grainsize, void *task_dup);
5363 llvm::Value *ThreadID = getThreadID(CGF, Loc);
5364 llvm::Value *UpLoc = emitUpdateLocation(CGF, Loc);
5365 llvm::Value *IfVal;
5366 if (IfCond) {
5367 IfVal = CGF.Builder.CreateIntCast(CGF.EvaluateExprAsBool(IfCond), CGF.IntTy,
5368 /*isSigned=*/true);
5369 } else {
5370 IfVal = llvm::ConstantInt::getSigned(CGF.IntTy, /*V=*/1);
5371 }
5372
5373 LValue LBLVal = CGF.EmitLValueForField(
5374 Result.TDBase,
5375 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound));
5376 const auto *LBVar =
5377 cast<VarDecl>(cast<DeclRefExpr>(D.getLowerBoundVariable())->getDecl());
5378 CGF.EmitAnyExprToMem(LBVar->getInit(), LBLVal.getAddress(), LBLVal.getQuals(),
5379 /*IsInitializer=*/true);
5380 LValue UBLVal = CGF.EmitLValueForField(
5381 Result.TDBase,
5382 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound));
5383 const auto *UBVar =
5384 cast<VarDecl>(cast<DeclRefExpr>(D.getUpperBoundVariable())->getDecl());
5385 CGF.EmitAnyExprToMem(UBVar->getInit(), UBLVal.getAddress(), UBLVal.getQuals(),
5386 /*IsInitializer=*/true);
5387 LValue StLVal = CGF.EmitLValueForField(
5388 Result.TDBase,
5389 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTStride));
5390 const auto *StVar =
5391 cast<VarDecl>(cast<DeclRefExpr>(D.getStrideVariable())->getDecl());
5392 CGF.EmitAnyExprToMem(StVar->getInit(), StLVal.getAddress(), StLVal.getQuals(),
5393 /*IsInitializer=*/true);
5394 // Store reductions address.
5395 LValue RedLVal = CGF.EmitLValueForField(
5396 Result.TDBase,
5397 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTReductions));
5398 if (Data.Reductions) {
5399 CGF.EmitStoreOfScalar(Data.Reductions, RedLVal);
5400 } else {
5401 CGF.EmitNullInitialization(RedLVal.getAddress(),
5402 CGF.getContext().VoidPtrTy);
5403 }
5404 enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 };
5405 llvm::Value *TaskArgs[] = {
5406 UpLoc,
5407 ThreadID,
5408 Result.NewTask,
5409 IfVal,
5410 LBLVal.getPointer(),
5411 UBLVal.getPointer(),
5412 CGF.EmitLoadOfScalar(StLVal, Loc),
5413 llvm::ConstantInt::getSigned(
5414 CGF.IntTy, 1), // Always 1 because taskgroup emitted by the compiler
5415 llvm::ConstantInt::getSigned(
5416 CGF.IntTy, Data.Schedule.getPointer()
5417 ? Data.Schedule.getInt() ? NumTasks : Grainsize
5418 : NoSchedule),
5419 Data.Schedule.getPointer()
5420 ? CGF.Builder.CreateIntCast(Data.Schedule.getPointer(), CGF.Int64Ty,
5421 /*isSigned=*/false)
5422 : llvm::ConstantInt::get(CGF.Int64Ty, /*V=*/0),
5423 Result.TaskDupFn ? CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5424 Result.TaskDupFn, CGF.VoidPtrTy)
5425 : llvm::ConstantPointerNull::get(CGF.VoidPtrTy)};
5426 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_taskloop), TaskArgs);
5427}
5428
5429/// Emit reduction operation for each element of array (required for
5430/// array sections) LHS op = RHS.
5431/// \param Type Type of array.
5432/// \param LHSVar Variable on the left side of the reduction operation
5433/// (references element of array in original variable).
5434/// \param RHSVar Variable on the right side of the reduction operation
5435/// (references element of array in original variable).
5436/// \param RedOpGen Generator of reduction operation with use of LHSVar and
5437/// RHSVar.
5438static void EmitOMPAggregateReduction(
5439 CodeGenFunction &CGF, QualType Type, const VarDecl *LHSVar,
5440 const VarDecl *RHSVar,
5441 const llvm::function_ref<void(CodeGenFunction &CGF, const Expr *,
5442 const Expr *, const Expr *)> &RedOpGen,
5443 const Expr *XExpr = nullptr, const Expr *EExpr = nullptr,
5444 const Expr *UpExpr = nullptr) {
5445 // Perform element-by-element initialization.
5446 QualType ElementTy;
5447 Address LHSAddr = CGF.GetAddrOfLocalVar(LHSVar);
5448 Address RHSAddr = CGF.GetAddrOfLocalVar(RHSVar);
5449
5450 // Drill down to the base element type on both arrays.
5451 const ArrayType *ArrayTy = Type->getAsArrayTypeUnsafe();
5452 llvm::Value *NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, LHSAddr);
5453
5454 llvm::Value *RHSBegin = RHSAddr.getPointer();
5455 llvm::Value *LHSBegin = LHSAddr.getPointer();
5456 // Cast from pointer to array type to pointer to single element.
5457 llvm::Value *LHSEnd = CGF.Builder.CreateGEP(LHSBegin, NumElements);
5458 // The basic structure here is a while-do loop.
5459 llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.arraycpy.body");
5460 llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.arraycpy.done");
5461 llvm::Value *IsEmpty =
5462 CGF.Builder.CreateICmpEQ(LHSBegin, LHSEnd, "omp.arraycpy.isempty");
5463 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
5464
5465 // Enter the loop body, making that address the current address.
5466 llvm::BasicBlock *EntryBB = CGF.Builder.GetInsertBlock();
5467 CGF.EmitBlock(BodyBB);
5468
5469 CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
5470
5471 llvm::PHINode *RHSElementPHI = CGF.Builder.CreatePHI(
5472 RHSBegin->getType(), 2, "omp.arraycpy.srcElementPast");
5473 RHSElementPHI->addIncoming(RHSBegin, EntryBB);
5474 Address RHSElementCurrent =
5475 Address(RHSElementPHI,
5476 RHSAddr.getAlignment().alignmentOfArrayElement(ElementSize));
5477
5478 llvm::PHINode *LHSElementPHI = CGF.Builder.CreatePHI(
5479 LHSBegin->getType(), 2, "omp.arraycpy.destElementPast");
5480 LHSElementPHI->addIncoming(LHSBegin, EntryBB);
5481 Address LHSElementCurrent =
5482 Address(LHSElementPHI,
5483 LHSAddr.getAlignment().alignmentOfArrayElement(ElementSize));
5484
5485 // Emit copy.
5486 CodeGenFunction::OMPPrivateScope Scope(CGF);
5487 Scope.addPrivate(LHSVar, [=]() { return LHSElementCurrent; });
5488 Scope.addPrivate(RHSVar, [=]() { return RHSElementCurrent; });
5489 Scope.Privatize();
5490 RedOpGen(CGF, XExpr, EExpr, UpExpr);
5491 Scope.ForceCleanup();
5492
5493 // Shift the address forward by one element.
5494 llvm::Value *LHSElementNext = CGF.Builder.CreateConstGEP1_32(
5495 LHSElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
5496 llvm::Value *RHSElementNext = CGF.Builder.CreateConstGEP1_32(
5497 RHSElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element");
5498 // Check whether we've reached the end.
5499 llvm::Value *Done =
5500 CGF.Builder.CreateICmpEQ(LHSElementNext, LHSEnd, "omp.arraycpy.done");
5501 CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
5502 LHSElementPHI->addIncoming(LHSElementNext, CGF.Builder.GetInsertBlock());
5503 RHSElementPHI->addIncoming(RHSElementNext, CGF.Builder.GetInsertBlock());
5504
5505 // Done.
5506 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
5507}
5508
5509/// Emit reduction combiner. If the combiner is a simple expression emit it as
5510/// is, otherwise consider it as combiner of UDR decl and emit it as a call of
5511/// UDR combiner function.
5512static void emitReductionCombiner(CodeGenFunction &CGF,
5513 const Expr *ReductionOp) {
5514 if (const auto *CE = dyn_cast<CallExpr>(ReductionOp))
5515 if (const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
5516 if (const auto *DRE =
5517 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
5518 if (const auto *DRD =
5519 dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl())) {
5520 std::pair<llvm::Function *, llvm::Function *> Reduction =
5521 CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
5522 RValue Func = RValue::get(Reduction.first);
5523 CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
5524 CGF.EmitIgnoredExpr(ReductionOp);
5525 return;
5526 }
5527 CGF.EmitIgnoredExpr(ReductionOp);
5528}
5529
5530llvm::Function *CGOpenMPRuntime::emitReductionFunction(
5531 SourceLocation Loc, llvm::Type *ArgsType, ArrayRef<const Expr *> Privates,
5532 ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
5533 ArrayRef<const Expr *> ReductionOps) {
5534 ASTContext &C = CGM.getContext();
5535
5536 // void reduction_func(void *LHSArg, void *RHSArg);
5537 FunctionArgList Args;
5538 ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
5539 ImplicitParamDecl::Other);
5540 ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
5541 ImplicitParamDecl::Other);
5542 Args.push_back(&LHSArg);
5543 Args.push_back(&RHSArg);
5544 const auto &CGFI =
5545 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
5546 std::string Name = getName({"omp", "reduction", "reduction_func"});
5547 auto *Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(CGFI),
5548 llvm::GlobalValue::InternalLinkage, Name,
5549 &CGM.getModule());
5550 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
5551 Fn->setDoesNotRecurse();
5552 CodeGenFunction CGF(CGM);
5553 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
5554
5555 // Dst = (void*[n])(LHSArg);
5556 // Src = (void*[n])(RHSArg);
5557 Address LHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5558 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&LHSArg)),
5559 ArgsType), CGF.getPointerAlign());
5560 Address RHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5561 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&RHSArg)),
5562 ArgsType), CGF.getPointerAlign());
5563
5564 // ...
5565 // *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
5566 // ...
5567 CodeGenFunction::OMPPrivateScope Scope(CGF);
5568 auto IPriv = Privates.begin();
5569 unsigned Idx = 0;
5570 for (unsigned I = 0, E = ReductionOps.size(); I < E; ++I, ++IPriv, ++Idx) {
5571 const auto *RHSVar =
5572 cast<VarDecl>(cast<DeclRefExpr>(RHSExprs[I])->getDecl());
5573 Scope.addPrivate(RHSVar, [&CGF, RHS, Idx, RHSVar]() {
5574 return emitAddrOfVarFromArray(CGF, RHS, Idx, RHSVar);
5575 });
5576 const auto *LHSVar =
5577 cast<VarDecl>(cast<DeclRefExpr>(LHSExprs[I])->getDecl());
5578 Scope.addPrivate(LHSVar, [&CGF, LHS, Idx, LHSVar]() {
5579 return emitAddrOfVarFromArray(CGF, LHS, Idx, LHSVar);
5580 });
5581 QualType PrivTy = (*IPriv)->getType();
5582 if (PrivTy->isVariablyModifiedType()) {
5583 // Get array size and emit VLA type.
5584 ++Idx;
5585 Address Elem = CGF.Builder.CreateConstArrayGEP(LHS, Idx);
5586 llvm::Value *Ptr = CGF.Builder.CreateLoad(Elem);
5587 const VariableArrayType *VLA =
5588 CGF.getContext().getAsVariableArrayType(PrivTy);
5589 const auto *OVE = cast<OpaqueValueExpr>(VLA->getSizeExpr());
5590 CodeGenFunction::OpaqueValueMapping OpaqueMap(
5591 CGF, OVE, RValue::get(CGF.Builder.CreatePtrToInt(Ptr, CGF.SizeTy)));
5592 CGF.EmitVariablyModifiedType(PrivTy);
5593 }
5594 }
5595 Scope.Privatize();
5596 IPriv = Privates.begin();
5597 auto ILHS = LHSExprs.begin();
5598 auto IRHS = RHSExprs.begin();
5599 for (const Expr *E : ReductionOps) {
5600 if ((*IPriv)->getType()->isArrayType()) {
5601 // Emit reduction for array section.
5602 const auto *LHSVar = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5603 const auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5604 EmitOMPAggregateReduction(
5605 CGF, (*IPriv)->getType(), LHSVar, RHSVar,
5606 [=](CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *) {
5607 emitReductionCombiner(CGF, E);
5608 });
5609 } else {
5610 // Emit reduction for array subscript or single variable.
5611 emitReductionCombiner(CGF, E);
5612 }
5613 ++IPriv;
5614 ++ILHS;
5615 ++IRHS;
5616 }
5617 Scope.ForceCleanup();
5618 CGF.FinishFunction();
5619 return Fn;
5620}
5621
5622void CGOpenMPRuntime::emitSingleReductionCombiner(CodeGenFunction &CGF,
5623 const Expr *ReductionOp,
5624 const Expr *PrivateRef,
5625 const DeclRefExpr *LHS,
5626 const DeclRefExpr *RHS) {
5627 if (PrivateRef->getType()->isArrayType()) {
5628 // Emit reduction for array section.
5629 const auto *LHSVar = cast<VarDecl>(LHS->getDecl());
5630 const auto *RHSVar = cast<VarDecl>(RHS->getDecl());
5631 EmitOMPAggregateReduction(
5632 CGF, PrivateRef->getType(), LHSVar, RHSVar,
5633 [=](CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *) {
5634 emitReductionCombiner(CGF, ReductionOp);
5635 });
5636 } else {
5637 // Emit reduction for array subscript or single variable.
5638 emitReductionCombiner(CGF, ReductionOp);
5639 }
5640}
5641
5642void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
5643 ArrayRef<const Expr *> Privates,
5644 ArrayRef<const Expr *> LHSExprs,
5645 ArrayRef<const Expr *> RHSExprs,
5646 ArrayRef<const Expr *> ReductionOps,
5647 ReductionOptionsTy Options) {
5648 if (!CGF.HaveInsertPoint())
5649 return;
5650
5651 bool WithNowait = Options.WithNowait;
5652 bool SimpleReduction = Options.SimpleReduction;
5653
5654 // Next code should be emitted for reduction:
5655 //
5656 // static kmp_critical_name lock = { 0 };
5657 //
5658 // void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
5659 // *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
5660 // ...
5661 // *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
5662 // *(Type<n>-1*)rhs[<n>-1]);
5663 // }
5664 //
5665 // ...
5666 // void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
5667 // switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
5668 // RedList, reduce_func, &<lock>)) {
5669 // case 1:
5670 // ...
5671 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5672 // ...
5673 // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5674 // break;
5675 // case 2:
5676 // ...
5677 // Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
5678 // ...
5679 // [__kmpc_end_reduce(<loc>, <gtid>, &<lock>);]
5680 // break;
5681 // default:;
5682 // }
5683 //
5684 // if SimpleReduction is true, only the next code is generated:
5685 // ...
5686 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5687 // ...
5688
5689 ASTContext &C = CGM.getContext();
5690
5691 if (SimpleReduction) {
5692 CodeGenFunction::RunCleanupsScope Scope(CGF);
5693 auto IPriv = Privates.begin();
5694 auto ILHS = LHSExprs.begin();
5695 auto IRHS = RHSExprs.begin();
5696 for (const Expr *E : ReductionOps) {
5697 emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
5698 cast<DeclRefExpr>(*IRHS));
5699 ++IPriv;
5700 ++ILHS;
5701 ++IRHS;
5702 }
5703 return;
5704 }
5705
5706 // 1. Build a list of reduction variables.
5707 // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
5708 auto Size = RHSExprs.size();
5709 for (const Expr *E : Privates) {
5710 if (E->getType()->isVariablyModifiedType())
5711 // Reserve place for array size.
5712 ++Size;
5713 }
5714 llvm::APInt ArraySize(/*unsigned int numBits=*/32, Size);
5715 QualType ReductionArrayTy =
5716 C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
5717 /*IndexTypeQuals=*/0);
5718 Address ReductionList =
5719 CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list");
5720 auto IPriv = Privates.begin();
5721 unsigned Idx = 0;
5722 for (unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
5723 Address Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
5724 CGF.Builder.CreateStore(
5725 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5726 CGF.EmitLValue(RHSExprs[I]).getPointer(), CGF.VoidPtrTy),
5727 Elem);
5728 if ((*IPriv)->getType()->isVariablyModifiedType()) {
5729 // Store array size.
5730 ++Idx;
5731 Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
5732 llvm::Value *Size = CGF.Builder.CreateIntCast(
5733 CGF.getVLASize(
5734 CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
5735 .NumElts,
5736 CGF.SizeTy, /*isSigned=*/false);
5737 CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
5738 Elem);
5739 }
5740 }
5741
5742 // 2. Emit reduce_func().
5743 llvm::Function *ReductionFn = emitReductionFunction(
5744 Loc, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(), Privates,
5745 LHSExprs, RHSExprs, ReductionOps);
5746
5747 // 3. Create static kmp_critical_name lock = { 0 };
5748 std::string Name = getName({"reduction"});
5749 llvm::Value *Lock = getCriticalRegionLock(Name);
5750
5751 // 4. Build res = __kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
5752 // RedList, reduce_func, &<lock>);
5753 llvm::Value *IdentTLoc = emitUpdateLocation(CGF, Loc, OMP_ATOMIC_REDUCE);
5754 llvm::Value *ThreadId = getThreadID(CGF, Loc);
5755 llvm::Value *ReductionArrayTySize = CGF.getTypeSize(ReductionArrayTy);
5756 llvm::Value *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5757 ReductionList.getPointer(), CGF.VoidPtrTy);
5758 llvm::Value *Args[] = {
5759 IdentTLoc, // ident_t *<loc>
5760 ThreadId, // i32 <gtid>
5761 CGF.Builder.getInt32(RHSExprs.size()), // i32 <n>
5762 ReductionArrayTySize, // size_type sizeof(RedList)
5763 RL, // void *RedList
5764 ReductionFn, // void (*) (void *, void *) <reduce_func>
5765 Lock // kmp_critical_name *&<lock>
5766 };
5767 llvm::Value *Res = CGF.EmitRuntimeCall(
5768 createRuntimeFunction(WithNowait ? OMPRTL__kmpc_reduce_nowait
5769 : OMPRTL__kmpc_reduce),
5770 Args);
5771
5772 // 5. Build switch(res)
5773 llvm::BasicBlock *DefaultBB = CGF.createBasicBlock(".omp.reduction.default");
5774 llvm::SwitchInst *SwInst =
5775 CGF.Builder.CreateSwitch(Res, DefaultBB, /*NumCases=*/2);
5776
5777 // 6. Build case 1:
5778 // ...
5779 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5780 // ...
5781 // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5782 // break;
5783 llvm::BasicBlock *Case1BB = CGF.createBasicBlock(".omp.reduction.case1");
5784 SwInst->addCase(CGF.Builder.getInt32(1), Case1BB);
5785 CGF.EmitBlock(Case1BB);
5786
5787 // Add emission of __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5788 llvm::Value *EndArgs[] = {
5789 IdentTLoc, // ident_t *<loc>
5790 ThreadId, // i32 <gtid>
5791 Lock // kmp_critical_name *&<lock>
5792 };
5793 auto &&CodeGen = [Privates, LHSExprs, RHSExprs, ReductionOps](
5794 CodeGenFunction &CGF, PrePostActionTy &Action) {
5795 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
5796 auto IPriv = Privates.begin();
5797 auto ILHS = LHSExprs.begin();
5798 auto IRHS = RHSExprs.begin();
5799 for (const Expr *E : ReductionOps) {
5800 RT.emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
5801 cast<DeclRefExpr>(*IRHS));
5802 ++IPriv;
5803 ++ILHS;
5804 ++IRHS;
5805 }
5806 };
5807 RegionCodeGenTy RCG(CodeGen);
5808 CommonActionTy Action(
5809 nullptr, llvm::None,
5810 createRuntimeFunction(WithNowait ? OMPRTL__kmpc_end_reduce_nowait
5811 : OMPRTL__kmpc_end_reduce),
5812 EndArgs);
5813 RCG.setAction(Action);
5814 RCG(CGF);
5815
5816 CGF.EmitBranch(DefaultBB);
5817
5818 // 7. Build case 2:
5819 // ...
5820 // Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
5821 // ...
5822 // break;
5823 llvm::BasicBlock *Case2BB = CGF.createBasicBlock(".omp.reduction.case2");
5824 SwInst->addCase(CGF.Builder.getInt32(2), Case2BB);
5825 CGF.EmitBlock(Case2BB);
5826
5827 auto &&AtomicCodeGen = [Loc, Privates, LHSExprs, RHSExprs, ReductionOps](
5828 CodeGenFunction &CGF, PrePostActionTy &Action) {
5829 auto ILHS = LHSExprs.begin();
5830 auto IRHS = RHSExprs.begin();
5831 auto IPriv = Privates.begin();
5832 for (const Expr *E : ReductionOps) {
5833 const Expr *XExpr = nullptr;
5834 const Expr *EExpr = nullptr;
5835 const Expr *UpExpr = nullptr;
5836 BinaryOperatorKind BO = BO_Comma;
5837 if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
5838 if (BO->getOpcode() == BO_Assign) {
5839 XExpr = BO->getLHS();
5840 UpExpr = BO->getRHS();
5841 }
5842 }
5843 // Try to emit update expression as a simple atomic.
5844 const Expr *RHSExpr = UpExpr;
5845 if (RHSExpr) {
5846 // Analyze RHS part of the whole expression.
5847 if (const auto *ACO = dyn_cast<AbstractConditionalOperator>(
5848 RHSExpr->IgnoreParenImpCasts())) {
5849 // If this is a conditional operator, analyze its condition for
5850 // min/max reduction operator.
5851 RHSExpr = ACO->getCond();
5852 }
5853 if (const auto *BORHS =
5854 dyn_cast<BinaryOperator>(RHSExpr->IgnoreParenImpCasts())) {
5855 EExpr = BORHS->getRHS();
5856 BO = BORHS->getOpcode();
5857 }
5858 }
5859 if (XExpr) {
5860 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5861 auto &&AtomicRedGen = [BO, VD,
5862 Loc](CodeGenFunction &CGF, const Expr *XExpr,
5863 const Expr *EExpr, const Expr *UpExpr) {
5864 LValue X = CGF.EmitLValue(XExpr);
5865 RValue E;
5866 if (EExpr)
5867 E = CGF.EmitAnyExpr(EExpr);
5868 CGF.EmitOMPAtomicSimpleUpdateExpr(
5869 X, E, BO, /*IsXLHSInRHSPart=*/true,
5870 llvm::AtomicOrdering::Monotonic, Loc,
5871 [&CGF, UpExpr, VD, Loc](RValue XRValue) {
5872 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
5873 PrivateScope.addPrivate(
5874 VD, [&CGF, VD, XRValue, Loc]() {
5875 Address LHSTemp = CGF.CreateMemTemp(VD->getType());
5876 CGF.emitOMPSimpleStore(
5877 CGF.MakeAddrLValue(LHSTemp, VD->getType()), XRValue,
5878 VD->getType().getNonReferenceType(), Loc);
5879 return LHSTemp;
5880 });
5881 (void)PrivateScope.Privatize();
5882 return CGF.EmitAnyExpr(UpExpr);
5883 });
5884 };
5885 if ((*IPriv)->getType()->isArrayType()) {
5886 // Emit atomic reduction for array section.
5887 const auto *RHSVar =
5888 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5889 EmitOMPAggregateReduction(CGF, (*IPriv)->getType(), VD, RHSVar,
5890 AtomicRedGen, XExpr, EExpr, UpExpr);
5891 } else {
5892 // Emit atomic reduction for array subscript or single variable.
5893 AtomicRedGen(CGF, XExpr, EExpr, UpExpr);
5894 }
5895 } else {
5896 // Emit as a critical region.
5897 auto &&CritRedGen = [E, Loc](CodeGenFunction &CGF, const Expr *,
5898 const Expr *, const Expr *) {
5899 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
5900 std::string Name = RT.getName({"atomic_reduction"});
5901 RT.emitCriticalRegion(
5902 CGF, Name,
5903 [=](CodeGenFunction &CGF, PrePostActionTy &Action) {
5904 Action.Enter(CGF);
5905 emitReductionCombiner(CGF, E);
5906 },
5907 Loc);
5908 };
5909 if ((*IPriv)->getType()->isArrayType()) {
5910 const auto *LHSVar =
5911 cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5912 const auto *RHSVar =
5913 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5914 EmitOMPAggregateReduction(CGF, (*IPriv)->getType(), LHSVar, RHSVar,
5915 CritRedGen);
5916 } else {
5917 CritRedGen(CGF, nullptr, nullptr, nullptr);
5918 }
5919 }
5920 ++ILHS;
5921 ++IRHS;
5922 ++IPriv;
5923 }
5924 };
5925 RegionCodeGenTy AtomicRCG(AtomicCodeGen);
5926 if (!WithNowait) {
5927 // Add emission of __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
5928 llvm::Value *EndArgs[] = {
5929 IdentTLoc, // ident_t *<loc>
5930 ThreadId, // i32 <gtid>
5931 Lock // kmp_critical_name *&<lock>
5932 };
5933 CommonActionTy Action(nullptr, llvm::None,
5934 createRuntimeFunction(OMPRTL__kmpc_end_reduce),
5935 EndArgs);
5936 AtomicRCG.setAction(Action);
5937 AtomicRCG(CGF);
5938 } else {
5939 AtomicRCG(CGF);
5940 }
5941
5942 CGF.EmitBranch(DefaultBB);
5943 CGF.EmitBlock(DefaultBB, /*IsFinished=*/true);
5944}
5945
5946/// Generates unique name for artificial threadprivate variables.
5947/// Format is: <Prefix> "." <Decl_mangled_name> "_" "<Decl_start_loc_raw_enc>"
5948static std::string generateUniqueName(CodeGenModule &CGM, StringRef Prefix,
5949 const Expr *Ref) {
5950 SmallString<256> Buffer;
5951 llvm::raw_svector_ostream Out(Buffer);
5952 const clang::DeclRefExpr *DE;
5953 const VarDecl *D = ::getBaseDecl(Ref, DE);
5954 if (!D)
5955 D = cast<VarDecl>(cast<DeclRefExpr>(Ref)->getDecl());
5956 D = D->getCanonicalDecl();
5957 std::string Name = CGM.getOpenMPRuntime().getName(
5958 {D->isLocalVarDeclOrParm() ? D->getName() : CGM.getMangledName(D)});
5959 Out << Prefix << Name << "_"
5960 << D->getCanonicalDecl()->getBeginLoc().getRawEncoding();
5961 return Out.str();
5962}
5963
5964/// Emits reduction initializer function:
5965/// \code
5966/// void @.red_init(void* %arg) {
5967/// %0 = bitcast void* %arg to <type>*
5968/// store <type> <init>, <type>* %0
5969/// ret void
5970/// }
5971/// \endcode
5972static llvm::Value *emitReduceInitFunction(CodeGenModule &CGM,
5973 SourceLocation Loc,
5974 ReductionCodeGen &RCG, unsigned N) {
5975 ASTContext &C = CGM.getContext();
5976 FunctionArgList Args;
5977 ImplicitParamDecl Param(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
5978 ImplicitParamDecl::Other);
5979 Args.emplace_back(&Param);
5980 const auto &FnInfo =
5981 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
5982 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
5983 std::string Name = CGM.getOpenMPRuntime().getName({"red_init", ""});
5984 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
5985 Name, &CGM.getModule());
5986 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
5987 Fn->setDoesNotRecurse();
5988 CodeGenFunction CGF(CGM);
5989 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
5990 Address PrivateAddr = CGF.EmitLoadOfPointer(
5991 CGF.GetAddrOfLocalVar(&Param),
5992 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
5993 llvm::Value *Size = nullptr;
5994 // If the size of the reduction item is non-constant, load it from global
5995 // threadprivate variable.
5996 if (RCG.getSizes(N).second) {
5997 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
5998 CGF, CGM.getContext().getSizeType(),
5999 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
6000 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
6001 CGM.getContext().getSizeType(), Loc);
6002 }
6003 RCG.emitAggregateType(CGF, N, Size);
6004 LValue SharedLVal;
6005 // If initializer uses initializer from declare reduction construct, emit a
6006 // pointer to the address of the original reduction item (reuired by reduction
6007 // initializer)
6008 if (RCG.usesReductionInitializer(N)) {
6009 Address SharedAddr =
6010 CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
6011 CGF, CGM.getContext().VoidPtrTy,
6012 generateUniqueName(CGM, "reduction", RCG.getRefExpr(N)));
6013 SharedAddr = CGF.EmitLoadOfPointer(
6014 SharedAddr,
6015 CGM.getContext().VoidPtrTy.castAs<PointerType>()->getTypePtr());
6016 SharedLVal = CGF.MakeAddrLValue(SharedAddr, CGM.getContext().VoidPtrTy);
6017 } else {
6018 SharedLVal = CGF.MakeNaturalAlignAddrLValue(
6019 llvm::ConstantPointerNull::get(CGM.VoidPtrTy),
6020 CGM.getContext().VoidPtrTy);
6021 }
6022 // Emit the initializer:
6023 // %0 = bitcast void* %arg to <type>*
6024 // store <type> <init>, <type>* %0
6025 RCG.emitInitialization(CGF, N, PrivateAddr, SharedLVal,
6026 [](CodeGenFunction &) { return false; });
6027 CGF.FinishFunction();
6028 return Fn;
6029}
6030
6031/// Emits reduction combiner function:
6032/// \code
6033/// void @.red_comb(void* %arg0, void* %arg1) {
6034/// %lhs = bitcast void* %arg0 to <type>*
6035/// %rhs = bitcast void* %arg1 to <type>*
6036/// %2 = <ReductionOp>(<type>* %lhs, <type>* %rhs)
6037/// store <type> %2, <type>* %lhs
6038/// ret void
6039/// }
6040/// \endcode
6041static llvm::Value *emitReduceCombFunction(CodeGenModule &CGM,
6042 SourceLocation Loc,
6043 ReductionCodeGen &RCG, unsigned N,
6044 const Expr *ReductionOp,
6045 const Expr *LHS, const Expr *RHS,
6046 const Expr *PrivateRef) {
6047 ASTContext &C = CGM.getContext();
6048 const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(LHS)->getDecl());
6049 const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(RHS)->getDecl());
6050 FunctionArgList Args;
6051 ImplicitParamDecl ParamInOut(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
6052 C.VoidPtrTy, ImplicitParamDecl::Other);
6053 ImplicitParamDecl ParamIn(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
6054 ImplicitParamDecl::Other);
6055 Args.emplace_back(&ParamInOut);
6056 Args.emplace_back(&ParamIn);
6057 const auto &FnInfo =
6058 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
6059 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
6060 std::string Name = CGM.getOpenMPRuntime().getName({"red_comb", ""});
6061 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
6062 Name, &CGM.getModule());
6063 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
6064 Fn->setDoesNotRecurse();
6065 CodeGenFunction CGF(CGM);
6066 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
6067 llvm::Value *Size = nullptr;
6068 // If the size of the reduction item is non-constant, load it from global
6069 // threadprivate variable.
6070 if (RCG.getSizes(N).second) {
6071 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
6072 CGF, CGM.getContext().getSizeType(),
6073 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
6074 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
6075 CGM.getContext().getSizeType(), Loc);
6076 }
6077 RCG.emitAggregateType(CGF, N, Size);
6078 // Remap lhs and rhs variables to the addresses of the function arguments.
6079 // %lhs = bitcast void* %arg0 to <type>*
6080 // %rhs = bitcast void* %arg1 to <type>*
6081 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
6082 PrivateScope.addPrivate(LHSVD, [&C, &CGF, &ParamInOut, LHSVD]() {
6083 // Pull out the pointer to the variable.
6084 Address PtrAddr = CGF.EmitLoadOfPointer(
6085 CGF.GetAddrOfLocalVar(&ParamInOut),
6086 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
6087 return CGF.Builder.CreateElementBitCast(
6088 PtrAddr, CGF.ConvertTypeForMem(LHSVD->getType()));
6089 });
6090 PrivateScope.addPrivate(RHSVD, [&C, &CGF, &ParamIn, RHSVD]() {
6091 // Pull out the pointer to the variable.
6092 Address PtrAddr = CGF.EmitLoadOfPointer(
6093 CGF.GetAddrOfLocalVar(&ParamIn),
6094 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
6095 return CGF.Builder.CreateElementBitCast(
6096 PtrAddr, CGF.ConvertTypeForMem(RHSVD->getType()));
6097 });
6098 PrivateScope.Privatize();
6099 // Emit the combiner body:
6100 // %2 = <ReductionOp>(<type> *%lhs, <type> *%rhs)
6101 // store <type> %2, <type>* %lhs
6102 CGM.getOpenMPRuntime().emitSingleReductionCombiner(
6103 CGF, ReductionOp, PrivateRef, cast<DeclRefExpr>(LHS),
6104 cast<DeclRefExpr>(RHS));
6105 CGF.FinishFunction();
6106 return Fn;
6107}
6108
6109/// Emits reduction finalizer function:
6110/// \code
6111/// void @.red_fini(void* %arg) {
6112/// %0 = bitcast void* %arg to <type>*
6113/// <destroy>(<type>* %0)
6114/// ret void
6115/// }
6116/// \endcode
6117static llvm::Value *emitReduceFiniFunction(CodeGenModule &CGM,
6118 SourceLocation Loc,
6119 ReductionCodeGen &RCG, unsigned N) {
6120 if (!RCG.needCleanups(N))
6121 return nullptr;
6122 ASTContext &C = CGM.getContext();
6123 FunctionArgList Args;
6124 ImplicitParamDecl Param(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
6125 ImplicitParamDecl::Other);
6126 Args.emplace_back(&Param);
6127 const auto &FnInfo =
6128 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
6129 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
6130 std::string Name = CGM.getOpenMPRuntime().getName({"red_fini", ""});
6131 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
6132 Name, &CGM.getModule());
6133 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
6134 Fn->setDoesNotRecurse();
6135 CodeGenFunction CGF(CGM);
6136 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
6137 Address PrivateAddr = CGF.EmitLoadOfPointer(
6138 CGF.GetAddrOfLocalVar(&Param),
6139 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
6140 llvm::Value *Size = nullptr;
6141 // If the size of the reduction item is non-constant, load it from global
6142 // threadprivate variable.
6143 if (RCG.getSizes(N).second) {
6144 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
6145 CGF, CGM.getContext().getSizeType(),
6146 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
6147 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
6148 CGM.getContext().getSizeType(), Loc);
6149 }
6150 RCG.emitAggregateType(CGF, N, Size);
6151 // Emit the finalizer body:
6152 // <destroy>(<type>* %0)
6153 RCG.emitCleanups(CGF, N, PrivateAddr);
6154 CGF.FinishFunction();
6155 return Fn;
6156}
6157
6158llvm::Value *CGOpenMPRuntime::emitTaskReductionInit(
6159 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> LHSExprs,
6160 ArrayRef<const Expr *> RHSExprs, const OMPTaskDataTy &Data) {
6161 if (!CGF.HaveInsertPoint() || Data.ReductionVars.empty())
6162 return nullptr;
6163
6164 // Build typedef struct:
6165 // kmp_task_red_input {
6166 // void *reduce_shar; // shared reduction item
6167 // size_t reduce_size; // size of data item
6168 // void *reduce_init; // data initialization routine
6169 // void *reduce_fini; // data finalization routine
6170 // void *reduce_comb; // data combiner routine
6171 // kmp_task_red_flags_t flags; // flags for additional info from compiler
6172 // } kmp_task_red_input_t;
6173 ASTContext &C = CGM.getContext();
6174 RecordDecl *RD = C.buildImplicitRecord("kmp_task_red_input_t");
6175 RD->startDefinition();
6176 const FieldDecl *SharedFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6177 const FieldDecl *SizeFD = addFieldToRecordDecl(C, RD, C.getSizeType());
6178 const FieldDecl *InitFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6179 const FieldDecl *FiniFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6180 const FieldDecl *CombFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6181 const FieldDecl *FlagsFD = addFieldToRecordDecl(
6182 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/false));
6183 RD->completeDefinition();
6184 QualType RDType = C.getRecordType(RD);
6185 unsigned Size = Data.ReductionVars.size();
6186 llvm::APInt ArraySize(/*numBits=*/64, Size);
6187 QualType ArrayRDType = C.getConstantArrayType(
6188 RDType, ArraySize, ArrayType::Normal, /*IndexTypeQuals=*/0);
6189 // kmp_task_red_input_t .rd_input.[Size];
6190 Address TaskRedInput = CGF.CreateMemTemp(ArrayRDType, ".rd_input.");
6191 ReductionCodeGen RCG(Data.ReductionVars, Data.ReductionCopies,
6192 Data.ReductionOps);
6193 for (unsigned Cnt = 0; Cnt < Size; ++Cnt) {
6194 // kmp_task_red_input_t &ElemLVal = .rd_input.[Cnt];
6195 llvm::Value *Idxs[] = {llvm::ConstantInt::get(CGM.SizeTy, /*V=*/0),
6196 llvm::ConstantInt::get(CGM.SizeTy, Cnt)};
6197 llvm::Value *GEP = CGF.EmitCheckedInBoundsGEP(
6198 TaskRedInput.getPointer(), Idxs,
6199 /*SignedIndices=*/false, /*IsSubtraction=*/false, Loc,
6200 ".rd_input.gep.");
6201 LValue ElemLVal = CGF.MakeNaturalAlignAddrLValue(GEP, RDType);
6202 // ElemLVal.reduce_shar = &Shareds[Cnt];
6203 LValue SharedLVal = CGF.EmitLValueForField(ElemLVal, SharedFD);
6204 RCG.emitSharedLValue(CGF, Cnt);
6205 llvm::Value *CastedShared =
6206 CGF.EmitCastToVoidPtr(RCG.getSharedLValue(Cnt).getPointer());
6207 CGF.EmitStoreOfScalar(CastedShared, SharedLVal);
6208 RCG.emitAggregateType(CGF, Cnt);
6209 llvm::Value *SizeValInChars;
6210 llvm::Value *SizeVal;
6211 std::tie(SizeValInChars, SizeVal) = RCG.getSizes(Cnt);
6212 // We use delayed creation/initialization for VLAs, array sections and
6213 // custom reduction initializations. It is required because runtime does not
6214 // provide the way to pass the sizes of VLAs/array sections to
6215 // initializer/combiner/finalizer functions and does not pass the pointer to
6216 // original reduction item to the initializer. Instead threadprivate global
6217 // variables are used to store these values and use them in the functions.
6218 bool DelayedCreation = !!SizeVal;
6219 SizeValInChars = CGF.Builder.CreateIntCast(SizeValInChars, CGM.SizeTy,
6220 /*isSigned=*/false);
6221 LValue SizeLVal = CGF.EmitLValueForField(ElemLVal, SizeFD);
6222 CGF.EmitStoreOfScalar(SizeValInChars, SizeLVal);
6223 // ElemLVal.reduce_init = init;
6224 LValue InitLVal = CGF.EmitLValueForField(ElemLVal, InitFD);
6225 llvm::Value *InitAddr =
6226 CGF.EmitCastToVoidPtr(emitReduceInitFunction(CGM, Loc, RCG, Cnt));
6227 CGF.EmitStoreOfScalar(InitAddr, InitLVal);
6228 DelayedCreation = DelayedCreation || RCG.usesReductionInitializer(Cnt);
6229 // ElemLVal.reduce_fini = fini;
6230 LValue FiniLVal = CGF.EmitLValueForField(ElemLVal, FiniFD);
6231 llvm::Value *Fini = emitReduceFiniFunction(CGM, Loc, RCG, Cnt);
6232 llvm::Value *FiniAddr = Fini
6233 ? CGF.EmitCastToVoidPtr(Fini)
6234 : llvm::ConstantPointerNull::get(CGM.VoidPtrTy);
6235 CGF.EmitStoreOfScalar(FiniAddr, FiniLVal);
6236 // ElemLVal.reduce_comb = comb;
6237 LValue CombLVal = CGF.EmitLValueForField(ElemLVal, CombFD);
6238 llvm::Value *CombAddr = CGF.EmitCastToVoidPtr(emitReduceCombFunction(
6239 CGM, Loc, RCG, Cnt, Data.ReductionOps[Cnt], LHSExprs[Cnt],
6240 RHSExprs[Cnt], Data.ReductionCopies[Cnt]));
6241 CGF.EmitStoreOfScalar(CombAddr, CombLVal);
6242 // ElemLVal.flags = 0;
6243 LValue FlagsLVal = CGF.EmitLValueForField(ElemLVal, FlagsFD);
6244 if (DelayedCreation) {
6245 CGF.EmitStoreOfScalar(
6246 llvm::ConstantInt::get(CGM.Int32Ty, /*V=*/1, /*IsSigned=*/true),
6247 FlagsLVal);
6248 } else
6249 CGF.EmitNullInitialization(FlagsLVal.getAddress(), FlagsLVal.getType());
6250 }
6251 // Build call void *__kmpc_task_reduction_init(int gtid, int num_data, void
6252 // *data);
6253 llvm::Value *Args[] = {
6254 CGF.Builder.CreateIntCast(getThreadID(CGF, Loc), CGM.IntTy,
6255 /*isSigned=*/true),
6256 llvm::ConstantInt::get(CGM.IntTy, Size, /*isSigned=*/true),
6257 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(TaskRedInput.getPointer(),
6258 CGM.VoidPtrTy)};
6259 return CGF.EmitRuntimeCall(
6260 createRuntimeFunction(OMPRTL__kmpc_task_reduction_init), Args);
6261}
6262
6263void CGOpenMPRuntime::emitTaskReductionFixups(CodeGenFunction &CGF,
6264 SourceLocation Loc,
6265 ReductionCodeGen &RCG,
6266 unsigned N) {
6267 auto Sizes = RCG.getSizes(N);
6268 // Emit threadprivate global variable if the type is non-constant
6269 // (Sizes.second = nullptr).
6270 if (Sizes.second) {
6271 llvm::Value *SizeVal = CGF.Builder.CreateIntCast(Sizes.second, CGM.SizeTy,
6272 /*isSigned=*/false);
6273 Address SizeAddr = getAddrOfArtificialThreadPrivate(
6274 CGF, CGM.getContext().getSizeType(),
6275 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
6276 CGF.Builder.CreateStore(SizeVal, SizeAddr, /*IsVolatile=*/false);
6277 }
6278 // Store address of the original reduction item if custom initializer is used.
6279 if (RCG.usesReductionInitializer(N)) {
6280 Address SharedAddr = getAddrOfArtificialThreadPrivate(
6281 CGF, CGM.getContext().VoidPtrTy,
6282 generateUniqueName(CGM, "reduction", RCG.getRefExpr(N)));
6283 CGF.Builder.CreateStore(
6284 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
6285 RCG.getSharedLValue(N).getPointer(), CGM.VoidPtrTy),
6286 SharedAddr, /*IsVolatile=*/false);
6287 }
6288}
6289
6290Address CGOpenMPRuntime::getTaskReductionItem(CodeGenFunction &CGF,
6291 SourceLocation Loc,
6292 llvm::Value *ReductionsPtr,
6293 LValue SharedLVal) {
6294 // Build call void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
6295 // *d);
6296 llvm::Value *Args[] = {
6297 CGF.Builder.CreateIntCast(getThreadID(CGF, Loc), CGM.IntTy,
6298 /*isSigned=*/true),
6299 ReductionsPtr,
6300 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(SharedLVal.getPointer(),
6301 CGM.VoidPtrTy)};
6302 return Address(
6303 CGF.EmitRuntimeCall(
6304 createRuntimeFunction(OMPRTL__kmpc_task_reduction_get_th_data), Args),
6305 SharedLVal.getAlignment());
6306}
6307
6308void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
6309 SourceLocation Loc) {
6310 if (!CGF.HaveInsertPoint())
6311 return;
6312 // Build call kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
6313 // global_tid);
6314 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
6315 // Ignore return result until untied tasks are supported.
6316 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskwait), Args);
6317 if (auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
6318 Region->emitUntiedSwitch(CGF);
6319}
6320
6321void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,
6322 OpenMPDirectiveKind InnerKind,
6323 const RegionCodeGenTy &CodeGen,
6324 bool HasCancel) {
6325 if (!CGF.HaveInsertPoint())
6326 return;
6327 InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel);
6328 CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr);
6329}
6330
6331namespace {
6332enum RTCancelKind {
6333 CancelNoreq = 0,
6334 CancelParallel = 1,
6335 CancelLoop = 2,
6336 CancelSections = 3,
6337 CancelTaskgroup = 4
6338};
6339} // anonymous namespace
6340
6341static RTCancelKind getCancellationKind(OpenMPDirectiveKind CancelRegion) {
6342 RTCancelKind CancelKind = CancelNoreq;
6343 if (CancelRegion == OMPD_parallel)
6344 CancelKind = CancelParallel;
6345 else if (CancelRegion == OMPD_for)
6346 CancelKind = CancelLoop;
6347 else if (CancelRegion == OMPD_sections)
6348 CancelKind = CancelSections;
6349 else {
6350 assert(CancelRegion == OMPD_taskgroup)((CancelRegion == OMPD_taskgroup) ? static_cast<void> (
0) : __assert_fail ("CancelRegion == OMPD_taskgroup", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6350, __PRETTY_FUNCTION__))
;
6351 CancelKind = CancelTaskgroup;
6352 }
6353 return CancelKind;
6354}
6355
6356void CGOpenMPRuntime::emitCancellationPointCall(
6357 CodeGenFunction &CGF, SourceLocation Loc,
6358 OpenMPDirectiveKind CancelRegion) {
6359 if (!CGF.HaveInsertPoint())
6360 return;
6361 // Build call kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
6362 // global_tid, kmp_int32 cncl_kind);
6363 if (auto *OMPRegionInfo =
6364 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
6365 // For 'cancellation point taskgroup', the task region info may not have a
6366 // cancel. This may instead happen in another adjacent task.
6367 if (CancelRegion == OMPD_taskgroup || OMPRegionInfo->hasCancel()) {
6368 llvm::Value *Args[] = {
6369 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
6370 CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
6371 // Ignore return result until untied tasks are supported.
6372 llvm::Value *Result = CGF.EmitRuntimeCall(
6373 createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args);
6374 // if (__kmpc_cancellationpoint()) {
6375 // exit from construct;
6376 // }
6377 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
6378 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
6379 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
6380 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6381 CGF.EmitBlock(ExitBB);
6382 // exit from construct;
6383 CodeGenFunction::JumpDest CancelDest =
6384 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
6385 CGF.EmitBranchThroughCleanup(CancelDest);
6386 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
6387 }
6388 }
6389}
6390
6391void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
6392 const Expr *IfCond,
6393 OpenMPDirectiveKind CancelRegion) {
6394 if (!CGF.HaveInsertPoint())
6395 return;
6396 // Build call kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
6397 // kmp_int32 cncl_kind);
6398 if (auto *OMPRegionInfo =
6399 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
6400 auto &&ThenGen = [Loc, CancelRegion, OMPRegionInfo](CodeGenFunction &CGF,
6401 PrePostActionTy &) {
6402 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
6403 llvm::Value *Args[] = {
6404 RT.emitUpdateLocation(CGF, Loc), RT.getThreadID(CGF, Loc),
6405 CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
6406 // Ignore return result until untied tasks are supported.
6407 llvm::Value *Result = CGF.EmitRuntimeCall(
6408 RT.createRuntimeFunction(OMPRTL__kmpc_cancel), Args);
6409 // if (__kmpc_cancel()) {
6410 // exit from construct;
6411 // }
6412 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
6413 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
6414 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
6415 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6416 CGF.EmitBlock(ExitBB);
6417 // exit from construct;
6418 CodeGenFunction::JumpDest CancelDest =
6419 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
6420 CGF.EmitBranchThroughCleanup(CancelDest);
6421 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
6422 };
6423 if (IfCond) {
6424 emitOMPIfClause(CGF, IfCond, ThenGen,
6425 [](CodeGenFunction &, PrePostActionTy &) {});
6426 } else {
6427 RegionCodeGenTy ThenRCG(ThenGen);
6428 ThenRCG(CGF);
6429 }
6430 }
6431}
6432
6433void CGOpenMPRuntime::emitTargetOutlinedFunction(
6434 const OMPExecutableDirective &D, StringRef ParentName,
6435 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
6436 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
6437 assert(!ParentName.empty() && "Invalid target region parent name!")((!ParentName.empty() && "Invalid target region parent name!"
) ? static_cast<void> (0) : __assert_fail ("!ParentName.empty() && \"Invalid target region parent name!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6437, __PRETTY_FUNCTION__))
;
6438 HasEmittedTargetRegion = true;
6439 emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
6440 IsOffloadEntry, CodeGen);
6441}
6442
6443void CGOpenMPRuntime::emitTargetOutlinedFunctionHelper(
6444 const OMPExecutableDirective &D, StringRef ParentName,
6445 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
6446 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
6447 // Create a unique name for the entry function using the source location
6448 // information of the current target region. The name will be something like:
6449 //
6450 // __omp_offloading_DD_FFFF_PP_lBB
6451 //
6452 // where DD_FFFF is an ID unique to the file (device and file IDs), PP is the
6453 // mangled name of the function that encloses the target region and BB is the
6454 // line number of the target region.
6455
6456 unsigned DeviceID;
6457 unsigned FileID;
6458 unsigned Line;
6459 getTargetEntryUniqueInfo(CGM.getContext(), D.getBeginLoc(), DeviceID, FileID,
6460 Line);
6461 SmallString<64> EntryFnName;
6462 {
6463 llvm::raw_svector_ostream OS(EntryFnName);
6464 OS << "__omp_offloading" << llvm::format("_%x", DeviceID)
6465 << llvm::format("_%x_", FileID) << ParentName << "_l" << Line;
6466 }
6467
6468 const CapturedStmt &CS = *D.getCapturedStmt(OMPD_target);
6469
6470 CodeGenFunction CGF(CGM, true);
6471 CGOpenMPTargetRegionInfo CGInfo(CS, CodeGen, EntryFnName);
6472 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6473
6474 OutlinedFn = CGF.GenerateOpenMPCapturedStmtFunction(CS);
6475
6476 // If this target outline function is not an offload entry, we don't need to
6477 // register it.
6478 if (!IsOffloadEntry)
6479 return;
6480
6481 // The target region ID is used by the runtime library to identify the current
6482 // target region, so it only has to be unique and not necessarily point to
6483 // anything. It could be the pointer to the outlined function that implements
6484 // the target region, but we aren't using that so that the compiler doesn't
6485 // need to keep that, and could therefore inline the host function if proven
6486 // worthwhile during optimization. In the other hand, if emitting code for the
6487 // device, the ID has to be the function address so that it can retrieved from
6488 // the offloading entry and launched by the runtime library. We also mark the
6489 // outlined function to have external linkage in case we are emitting code for
6490 // the device, because these functions will be entry points to the device.
6491
6492 if (CGM.getLangOpts().OpenMPIsDevice) {
6493 OutlinedFnID = llvm::ConstantExpr::getBitCast(OutlinedFn, CGM.Int8PtrTy);
6494 OutlinedFn->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6495 OutlinedFn->setDSOLocal(false);
6496 } else {
6497 std::string Name = getName({EntryFnName, "region_id"});
6498 OutlinedFnID = new llvm::GlobalVariable(
6499 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
6500 llvm::GlobalValue::WeakAnyLinkage,
6501 llvm::Constant::getNullValue(CGM.Int8Ty), Name);
6502 }
6503
6504 // Register the information for the entry associated with this target region.
6505 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
6506 DeviceID, FileID, ParentName, Line, OutlinedFn, OutlinedFnID,
6507 OffloadEntriesInfoManagerTy::OMPTargetRegionEntryTargetRegion);
6508}
6509
6510/// Checks if the expression is constant or does not have non-trivial function
6511/// calls.
6512static bool isTrivial(ASTContext &Ctx, const Expr * E) {
6513 // We can skip constant expressions.
6514 // We can skip expressions with trivial calls or simple expressions.
6515 return (E->isEvaluatable(Ctx, Expr::SE_AllowUndefinedBehavior) ||
6516 !E->hasNonTrivialCall(Ctx)) &&
6517 !E->HasSideEffects(Ctx, /*IncludePossibleEffects=*/true);
6518}
6519
6520const Stmt *CGOpenMPRuntime::getSingleCompoundChild(ASTContext &Ctx,
6521 const Stmt *Body) {
6522 const Stmt *Child = Body->IgnoreContainers();
6523 while (const auto *C = dyn_cast_or_null<CompoundStmt>(Child)) {
6524 Child = nullptr;
6525 for (const Stmt *S : C->body()) {
6526 if (const auto *E = dyn_cast<Expr>(S)) {
6527 if (isTrivial(Ctx, E))
6528 continue;
6529 }
6530 // Some of the statements can be ignored.
6531 if (isa<AsmStmt>(S) || isa<NullStmt>(S) || isa<OMPFlushDirective>(S) ||
6532 isa<OMPBarrierDirective>(S) || isa<OMPTaskyieldDirective>(S))
6533 continue;
6534 // Analyze declarations.
6535 if (const auto *DS = dyn_cast<DeclStmt>(S)) {
6536 if (llvm::all_of(DS->decls(), [&Ctx](const Decl *D) {
6537 if (isa<EmptyDecl>(D) || isa<DeclContext>(D) ||
6538 isa<TypeDecl>(D) || isa<PragmaCommentDecl>(D) ||
6539 isa<PragmaDetectMismatchDecl>(D) || isa<UsingDecl>(D) ||
6540 isa<UsingDirectiveDecl>(D) ||
6541 isa<OMPDeclareReductionDecl>(D) ||
6542 isa<OMPThreadPrivateDecl>(D) || isa<OMPAllocateDecl>(D))
6543 return true;
6544 const auto *VD = dyn_cast<VarDecl>(D);
6545 if (!VD)
6546 return false;
6547 return VD->isConstexpr() ||
6548 ((VD->getType().isTrivialType(Ctx) ||
6549 VD->getType()->isReferenceType()) &&
6550 (!VD->hasInit() || isTrivial(Ctx, VD->getInit())));
6551 }))
6552 continue;
6553 }
6554 // Found multiple children - cannot get the one child only.
6555 if (Child)
6556 return nullptr;
6557 Child = S;
6558 }
6559 if (Child)
6560 Child = Child->IgnoreContainers();
6561 }
6562 return Child;
6563}
6564
6565/// Emit the number of teams for a target directive. Inspect the num_teams
6566/// clause associated with a teams construct combined or closely nested
6567/// with the target directive.
6568///
6569/// Emit a team of size one for directives such as 'target parallel' that
6570/// have no associated teams construct.
6571///
6572/// Otherwise, return nullptr.
6573static llvm::Value *
6574emitNumTeamsForTargetDirective(CodeGenFunction &CGF,
6575 const OMPExecutableDirective &D) {
6576 assert(!CGF.getLangOpts().OpenMPIsDevice &&((!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the teams directive expected to be emitted "
"only for the host!") ? static_cast<void> (0) : __assert_fail
("!CGF.getLangOpts().OpenMPIsDevice && \"Clauses associated with the teams directive expected to be emitted \" \"only for the host!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6578, __PRETTY_FUNCTION__))
6577 "Clauses associated with the teams directive expected to be emitted "((!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the teams directive expected to be emitted "
"only for the host!") ? static_cast<void> (0) : __assert_fail
("!CGF.getLangOpts().OpenMPIsDevice && \"Clauses associated with the teams directive expected to be emitted \" \"only for the host!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6578, __PRETTY_FUNCTION__))
6578 "only for the host!")((!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the teams directive expected to be emitted "
"only for the host!") ? static_cast<void> (0) : __assert_fail
("!CGF.getLangOpts().OpenMPIsDevice && \"Clauses associated with the teams directive expected to be emitted \" \"only for the host!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6578, __PRETTY_FUNCTION__))
;
6579 OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
6580 assert(isOpenMPTargetExecutionDirective(DirectiveKind) &&((isOpenMPTargetExecutionDirective(DirectiveKind) && "Expected target-based executable directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPTargetExecutionDirective(DirectiveKind) && \"Expected target-based executable directive.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6581, __PRETTY_FUNCTION__))
6581 "Expected target-based executable directive.")((isOpenMPTargetExecutionDirective(DirectiveKind) && "Expected target-based executable directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPTargetExecutionDirective(DirectiveKind) && \"Expected target-based executable directive.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6581, __PRETTY_FUNCTION__))
;
6582 CGBuilderTy &Bld = CGF.Builder;
6583 switch (DirectiveKind) {
6584 case OMPD_target: {
6585 const auto *CS = D.getInnermostCapturedStmt();
6586 const auto *Body =
6587 CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
6588 const Stmt *ChildStmt =
6589 CGOpenMPRuntime::getSingleCompoundChild(CGF.getContext(), Body);
6590 if (const auto *NestedDir =
6591 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
6592 if (isOpenMPTeamsDirective(NestedDir->getDirectiveKind())) {
6593 if (NestedDir->hasClausesOfKind<OMPNumTeamsClause>()) {
6594 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6595 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6596 const Expr *NumTeams =
6597 NestedDir->getSingleClause<OMPNumTeamsClause>()->getNumTeams();
6598 llvm::Value *NumTeamsVal =
6599 CGF.EmitScalarExpr(NumTeams,
6600 /*IgnoreResultAssign*/ true);
6601 return Bld.CreateIntCast(NumTeamsVal, CGF.Int32Ty,
6602 /*IsSigned=*/true);
6603 }
6604 return Bld.getInt32(0);
6605 }
6606 if (isOpenMPParallelDirective(NestedDir->getDirectiveKind()) ||
6607 isOpenMPSimdDirective(NestedDir->getDirectiveKind()))
6608 return Bld.getInt32(1);
6609 return Bld.getInt32(0);
6610 }
6611 return nullptr;
6612 }
6613 case OMPD_target_teams:
6614 case OMPD_target_teams_distribute:
6615 case OMPD_target_teams_distribute_simd:
6616 case OMPD_target_teams_distribute_parallel_for:
6617 case OMPD_target_teams_distribute_parallel_for_simd: {
6618 if (D.hasClausesOfKind<OMPNumTeamsClause>()) {
6619 CodeGenFunction::RunCleanupsScope NumTeamsScope(CGF);
6620 const Expr *NumTeams =
6621 D.getSingleClause<OMPNumTeamsClause>()->getNumTeams();
6622 llvm::Value *NumTeamsVal =
6623 CGF.EmitScalarExpr(NumTeams,
6624 /*IgnoreResultAssign*/ true);
6625 return Bld.CreateIntCast(NumTeamsVal, CGF.Int32Ty,
6626 /*IsSigned=*/true);
6627 }
6628 return Bld.getInt32(0);
6629 }
6630 case OMPD_target_parallel:
6631 case OMPD_target_parallel_for:
6632 case OMPD_target_parallel_for_simd:
6633 case OMPD_target_simd:
6634 return Bld.getInt32(1);
6635 case OMPD_parallel:
6636 case OMPD_for:
6637 case OMPD_parallel_for:
6638 case OMPD_parallel_sections:
6639 case OMPD_for_simd:
6640 case OMPD_parallel_for_simd:
6641 case OMPD_cancel:
6642 case OMPD_cancellation_point:
6643 case OMPD_ordered:
6644 case OMPD_threadprivate:
6645 case OMPD_allocate:
6646 case OMPD_task:
6647 case OMPD_simd:
6648 case OMPD_sections:
6649 case OMPD_section:
6650 case OMPD_single:
6651 case OMPD_master:
6652 case OMPD_critical:
6653 case OMPD_taskyield:
6654 case OMPD_barrier:
6655 case OMPD_taskwait:
6656 case OMPD_taskgroup:
6657 case OMPD_atomic:
6658 case OMPD_flush:
6659 case OMPD_teams:
6660 case OMPD_target_data:
6661 case OMPD_target_exit_data:
6662 case OMPD_target_enter_data:
6663 case OMPD_distribute:
6664 case OMPD_distribute_simd:
6665 case OMPD_distribute_parallel_for:
6666 case OMPD_distribute_parallel_for_simd:
6667 case OMPD_teams_distribute:
6668 case OMPD_teams_distribute_simd:
6669 case OMPD_teams_distribute_parallel_for:
6670 case OMPD_teams_distribute_parallel_for_simd:
6671 case OMPD_target_update:
6672 case OMPD_declare_simd:
6673 case OMPD_declare_target:
6674 case OMPD_end_declare_target:
6675 case OMPD_declare_reduction:
6676 case OMPD_declare_mapper:
6677 case OMPD_taskloop:
6678 case OMPD_taskloop_simd:
6679 case OMPD_requires:
6680 case OMPD_unknown:
6681 break;
6682 }
6683 llvm_unreachable("Unexpected directive kind.")::llvm::llvm_unreachable_internal("Unexpected directive kind."
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6683)
;
6684}
6685
6686static llvm::Value *getNumThreads(CodeGenFunction &CGF, const CapturedStmt *CS,
6687 llvm::Value *DefaultThreadLimitVal) {
6688 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6689 CGF.getContext(), CS->getCapturedStmt());
6690 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
6691 if (isOpenMPParallelDirective(Dir->getDirectiveKind())) {
6692 llvm::Value *NumThreads = nullptr;
6693 llvm::Value *CondVal = nullptr;
6694 // Handle if clause. If if clause present, the number of threads is
6695 // calculated as <cond> ? (<numthreads> ? <numthreads> : 0 ) : 1.
6696 if (Dir->hasClausesOfKind<OMPIfClause>()) {
6697 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6698 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6699 const OMPIfClause *IfClause = nullptr;
6700 for (const auto *C : Dir->getClausesOfKind<OMPIfClause>()) {
6701 if (C->getNameModifier() == OMPD_unknown ||
6702 C->getNameModifier() == OMPD_parallel) {
6703 IfClause = C;
6704 break;
6705 }
6706 }
6707 if (IfClause) {
6708 const Expr *Cond = IfClause->getCondition();
6709 bool Result;
6710 if (Cond->EvaluateAsBooleanCondition(Result, CGF.getContext())) {
6711 if (!Result)
6712 return CGF.Builder.getInt32(1);
6713 } else {
6714 CodeGenFunction::LexicalScope Scope(CGF, Cond->getSourceRange());
6715 if (const auto *PreInit =
6716 cast_or_null<DeclStmt>(IfClause->getPreInitStmt())) {
6717 for (const auto *I : PreInit->decls()) {
6718 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
6719 CGF.EmitVarDecl(cast<VarDecl>(*I));
6720 } else {
6721 CodeGenFunction::AutoVarEmission Emission =
6722 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
6723 CGF.EmitAutoVarCleanups(Emission);
6724 }
6725 }
6726 }
6727 CondVal = CGF.EvaluateExprAsBool(Cond);
6728 }
6729 }
6730 }
6731 // Check the value of num_threads clause iff if clause was not specified
6732 // or is not evaluated to false.
6733 if (Dir->hasClausesOfKind<OMPNumThreadsClause>()) {
6734 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6735 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6736 const auto *NumThreadsClause =
6737 Dir->getSingleClause<OMPNumThreadsClause>();
6738 CodeGenFunction::LexicalScope Scope(
6739 CGF, NumThreadsClause->getNumThreads()->getSourceRange());
6740 if (const auto *PreInit =
6741 cast_or_null<DeclStmt>(NumThreadsClause->getPreInitStmt())) {
6742 for (const auto *I : PreInit->decls()) {
6743 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
6744 CGF.EmitVarDecl(cast<VarDecl>(*I));
6745 } else {
6746 CodeGenFunction::AutoVarEmission Emission =
6747 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
6748 CGF.EmitAutoVarCleanups(Emission);
6749 }
6750 }
6751 }
6752 NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads());
6753 NumThreads = CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty,
6754 /*IsSigned=*/false);
6755 if (DefaultThreadLimitVal)
6756 NumThreads = CGF.Builder.CreateSelect(
6757 CGF.Builder.CreateICmpULT(DefaultThreadLimitVal, NumThreads),
6758 DefaultThreadLimitVal, NumThreads);
6759 } else {
6760 NumThreads = DefaultThreadLimitVal ? DefaultThreadLimitVal
6761 : CGF.Builder.getInt32(0);
6762 }
6763 // Process condition of the if clause.
6764 if (CondVal) {
6765 NumThreads = CGF.Builder.CreateSelect(CondVal, NumThreads,
6766 CGF.Builder.getInt32(1));
6767 }
6768 return NumThreads;
6769 }
6770 if (isOpenMPSimdDirective(Dir->getDirectiveKind()))
6771 return CGF.Builder.getInt32(1);
6772 return DefaultThreadLimitVal;
6773 }
6774 return DefaultThreadLimitVal ? DefaultThreadLimitVal
6775 : CGF.Builder.getInt32(0);
6776}
6777
6778/// Emit the number of threads for a target directive. Inspect the
6779/// thread_limit clause associated with a teams construct combined or closely
6780/// nested with the target directive.
6781///
6782/// Emit the num_threads clause for directives such as 'target parallel' that
6783/// have no associated teams construct.
6784///
6785/// Otherwise, return nullptr.
6786static llvm::Value *
6787emitNumThreadsForTargetDirective(CodeGenFunction &CGF,
6788 const OMPExecutableDirective &D) {
6789 assert(!CGF.getLangOpts().OpenMPIsDevice &&((!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the teams directive expected to be emitted "
"only for the host!") ? static_cast<void> (0) : __assert_fail
("!CGF.getLangOpts().OpenMPIsDevice && \"Clauses associated with the teams directive expected to be emitted \" \"only for the host!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6791, __PRETTY_FUNCTION__))
6790 "Clauses associated with the teams directive expected to be emitted "((!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the teams directive expected to be emitted "
"only for the host!") ? static_cast<void> (0) : __assert_fail
("!CGF.getLangOpts().OpenMPIsDevice && \"Clauses associated with the teams directive expected to be emitted \" \"only for the host!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6791, __PRETTY_FUNCTION__))
6791 "only for the host!")((!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the teams directive expected to be emitted "
"only for the host!") ? static_cast<void> (0) : __assert_fail
("!CGF.getLangOpts().OpenMPIsDevice && \"Clauses associated with the teams directive expected to be emitted \" \"only for the host!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6791, __PRETTY_FUNCTION__))
;
6792 OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
6793 assert(isOpenMPTargetExecutionDirective(DirectiveKind) &&((isOpenMPTargetExecutionDirective(DirectiveKind) && "Expected target-based executable directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPTargetExecutionDirective(DirectiveKind) && \"Expected target-based executable directive.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6794, __PRETTY_FUNCTION__))
6794 "Expected target-based executable directive.")((isOpenMPTargetExecutionDirective(DirectiveKind) && "Expected target-based executable directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPTargetExecutionDirective(DirectiveKind) && \"Expected target-based executable directive.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6794, __PRETTY_FUNCTION__))
;
6795 CGBuilderTy &Bld = CGF.Builder;
6796 llvm::Value *ThreadLimitVal = nullptr;
6797 llvm::Value *NumThreadsVal = nullptr;
6798 switch (DirectiveKind) {
6799 case OMPD_target: {
6800 const CapturedStmt *CS = D.getInnermostCapturedStmt();
6801 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6802 return NumThreads;
6803 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6804 CGF.getContext(), CS->getCapturedStmt());
6805 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
6806 if (Dir->hasClausesOfKind<OMPThreadLimitClause>()) {
6807 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6808 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6809 const auto *ThreadLimitClause =
6810 Dir->getSingleClause<OMPThreadLimitClause>();
6811 CodeGenFunction::LexicalScope Scope(
6812 CGF, ThreadLimitClause->getThreadLimit()->getSourceRange());
6813 if (const auto *PreInit =
6814 cast_or_null<DeclStmt>(ThreadLimitClause->getPreInitStmt())) {
6815 for (const auto *I : PreInit->decls()) {
6816 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
6817 CGF.EmitVarDecl(cast<VarDecl>(*I));
6818 } else {
6819 CodeGenFunction::AutoVarEmission Emission =
6820 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
6821 CGF.EmitAutoVarCleanups(Emission);
6822 }
6823 }
6824 }
6825 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6826 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6827 ThreadLimitVal =
6828 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
6829 }
6830 if (isOpenMPTeamsDirective(Dir->getDirectiveKind()) &&
6831 !isOpenMPDistributeDirective(Dir->getDirectiveKind())) {
6832 CS = Dir->getInnermostCapturedStmt();
6833 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6834 CGF.getContext(), CS->getCapturedStmt());
6835 Dir = dyn_cast_or_null<OMPExecutableDirective>(Child);
6836 }
6837 if (Dir && isOpenMPDistributeDirective(Dir->getDirectiveKind()) &&
6838 !isOpenMPSimdDirective(Dir->getDirectiveKind())) {
6839 CS = Dir->getInnermostCapturedStmt();
6840 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6841 return NumThreads;
6842 }
6843 if (Dir && isOpenMPSimdDirective(Dir->getDirectiveKind()))
6844 return Bld.getInt32(1);
6845 }
6846 return ThreadLimitVal ? ThreadLimitVal : Bld.getInt32(0);
6847 }
6848 case OMPD_target_teams: {
6849 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
6850 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
6851 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
6852 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6853 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6854 ThreadLimitVal =
6855 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
6856 }
6857 const CapturedStmt *CS = D.getInnermostCapturedStmt();
6858 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6859 return NumThreads;
6860 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6861 CGF.getContext(), CS->getCapturedStmt());
6862 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
6863 if (Dir->getDirectiveKind() == OMPD_distribute) {
6864 CS = Dir->getInnermostCapturedStmt();
6865 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6866 return NumThreads;
6867 }
6868 }
6869 return ThreadLimitVal ? ThreadLimitVal : Bld.getInt32(0);
6870 }
6871 case OMPD_target_teams_distribute:
6872 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
6873 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
6874 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
6875 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6876 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6877 ThreadLimitVal =
6878 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
6879 }
6880 return getNumThreads(CGF, D.getInnermostCapturedStmt(), ThreadLimitVal);
6881 case OMPD_target_parallel:
6882 case OMPD_target_parallel_for:
6883 case OMPD_target_parallel_for_simd:
6884 case OMPD_target_teams_distribute_parallel_for:
6885 case OMPD_target_teams_distribute_parallel_for_simd: {
6886 llvm::Value *CondVal = nullptr;
6887 // Handle if clause. If if clause present, the number of threads is
6888 // calculated as <cond> ? (<numthreads> ? <numthreads> : 0 ) : 1.
6889 if (D.hasClausesOfKind<OMPIfClause>()) {
6890 const OMPIfClause *IfClause = nullptr;
6891 for (const auto *C : D.getClausesOfKind<OMPIfClause>()) {
6892 if (C->getNameModifier() == OMPD_unknown ||
6893 C->getNameModifier() == OMPD_parallel) {
6894 IfClause = C;
6895 break;
6896 }
6897 }
6898 if (IfClause) {
6899 const Expr *Cond = IfClause->getCondition();
6900 bool Result;
6901 if (Cond->EvaluateAsBooleanCondition(Result, CGF.getContext())) {
6902 if (!Result)
6903 return Bld.getInt32(1);
6904 } else {
6905 CodeGenFunction::RunCleanupsScope Scope(CGF);
6906 CondVal = CGF.EvaluateExprAsBool(Cond);
6907 }
6908 }
6909 }
6910 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
6911 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
6912 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
6913 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6914 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6915 ThreadLimitVal =
6916 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
6917 }
6918 if (D.hasClausesOfKind<OMPNumThreadsClause>()) {
6919 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
6920 const auto *NumThreadsClause = D.getSingleClause<OMPNumThreadsClause>();
6921 llvm::Value *NumThreads = CGF.EmitScalarExpr(
6922 NumThreadsClause->getNumThreads(), /*IgnoreResultAssign=*/true);
6923 NumThreadsVal =
6924 Bld.CreateIntCast(NumThreads, CGF.Int32Ty, /*IsSigned=*/false);
6925 ThreadLimitVal = ThreadLimitVal
6926 ? Bld.CreateSelect(Bld.CreateICmpULT(NumThreadsVal,
6927 ThreadLimitVal),
6928 NumThreadsVal, ThreadLimitVal)
6929 : NumThreadsVal;
6930 }
6931 if (!ThreadLimitVal)
6932 ThreadLimitVal = Bld.getInt32(0);
6933 if (CondVal)
6934 return Bld.CreateSelect(CondVal, ThreadLimitVal, Bld.getInt32(1));
6935 return ThreadLimitVal;
6936 }
6937 case OMPD_target_teams_distribute_simd:
6938 case OMPD_target_simd:
6939 return Bld.getInt32(1);
6940 case OMPD_parallel:
6941 case OMPD_for:
6942 case OMPD_parallel_for:
6943 case OMPD_parallel_sections:
6944 case OMPD_for_simd:
6945 case OMPD_parallel_for_simd:
6946 case OMPD_cancel:
6947 case OMPD_cancellation_point:
6948 case OMPD_ordered:
6949 case OMPD_threadprivate:
6950 case OMPD_allocate:
6951 case OMPD_task:
6952 case OMPD_simd:
6953 case OMPD_sections:
6954 case OMPD_section:
6955 case OMPD_single:
6956 case OMPD_master:
6957 case OMPD_critical:
6958 case OMPD_taskyield:
6959 case OMPD_barrier:
6960 case OMPD_taskwait:
6961 case OMPD_taskgroup:
6962 case OMPD_atomic:
6963 case OMPD_flush:
6964 case OMPD_teams:
6965 case OMPD_target_data:
6966 case OMPD_target_exit_data:
6967 case OMPD_target_enter_data:
6968 case OMPD_distribute:
6969 case OMPD_distribute_simd:
6970 case OMPD_distribute_parallel_for:
6971 case OMPD_distribute_parallel_for_simd:
6972 case OMPD_teams_distribute:
6973 case OMPD_teams_distribute_simd:
6974 case OMPD_teams_distribute_parallel_for:
6975 case OMPD_teams_distribute_parallel_for_simd:
6976 case OMPD_target_update:
6977 case OMPD_declare_simd:
6978 case OMPD_declare_target:
6979 case OMPD_end_declare_target:
6980 case OMPD_declare_reduction:
6981 case OMPD_declare_mapper:
6982 case OMPD_taskloop:
6983 case OMPD_taskloop_simd:
6984 case OMPD_requires:
6985 case OMPD_unknown:
6986 break;
6987 }
6988 llvm_unreachable("Unsupported directive kind.")::llvm::llvm_unreachable_internal("Unsupported directive kind."
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 6988)
;
6989}
6990
6991namespace {
6992LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()using ::llvm::BitmaskEnumDetail::operator~; using ::llvm::BitmaskEnumDetail
::operator|; using ::llvm::BitmaskEnumDetail::operator&; using
::llvm::BitmaskEnumDetail::operator^; using ::llvm::BitmaskEnumDetail
::operator|=; using ::llvm::BitmaskEnumDetail::operator&=
; using ::llvm::BitmaskEnumDetail::operator^=
;
6993
6994// Utility to handle information from clauses associated with a given
6995// construct that use mappable expressions (e.g. 'map' clause, 'to' clause).
6996// It provides a convenient interface to obtain the information and generate
6997// code for that information.
6998class MappableExprsHandler {
6999public:
7000 /// Values for bit flags used to specify the mapping type for
7001 /// offloading.
7002 enum OpenMPOffloadMappingFlags : uint64_t {
7003 /// No flags
7004 OMP_MAP_NONE = 0x0,
7005 /// Allocate memory on the device and move data from host to device.
7006 OMP_MAP_TO = 0x01,
7007 /// Allocate memory on the device and move data from device to host.
7008 OMP_MAP_FROM = 0x02,
7009 /// Always perform the requested mapping action on the element, even
7010 /// if it was already mapped before.
7011 OMP_MAP_ALWAYS = 0x04,
7012 /// Delete the element from the device environment, ignoring the
7013 /// current reference count associated with the element.
7014 OMP_MAP_DELETE = 0x08,
7015 /// The element being mapped is a pointer-pointee pair; both the
7016 /// pointer and the pointee should be mapped.
7017 OMP_MAP_PTR_AND_OBJ = 0x10,
7018 /// This flags signals that the base address of an entry should be
7019 /// passed to the target kernel as an argument.
7020 OMP_MAP_TARGET_PARAM = 0x20,
7021 /// Signal that the runtime library has to return the device pointer
7022 /// in the current position for the data being mapped. Used when we have the
7023 /// use_device_ptr clause.
7024 OMP_MAP_RETURN_PARAM = 0x40,
7025 /// This flag signals that the reference being passed is a pointer to
7026 /// private data.
7027 OMP_MAP_PRIVATE = 0x80,
7028 /// Pass the element to the device by value.
7029 OMP_MAP_LITERAL = 0x100,
7030 /// Implicit map
7031 OMP_MAP_IMPLICIT = 0x200,
7032 /// The 16 MSBs of the flags indicate whether the entry is member of some
7033 /// struct/class.
7034 OMP_MAP_MEMBER_OF = 0xffff000000000000,
7035 LLVM_MARK_AS_BITMASK_ENUM(/* LargestFlag = */ OMP_MAP_MEMBER_OF)LLVM_BITMASK_LARGEST_ENUMERATOR = OMP_MAP_MEMBER_OF,
7036 };
7037
7038 /// Class that associates information with a base pointer to be passed to the
7039 /// runtime library.
7040 class BasePointerInfo {
7041 /// The base pointer.
7042 llvm::Value *Ptr = nullptr;
7043 /// The base declaration that refers to this device pointer, or null if
7044 /// there is none.
7045 const ValueDecl *DevPtrDecl = nullptr;
7046
7047 public:
7048 BasePointerInfo(llvm::Value *Ptr, const ValueDecl *DevPtrDecl = nullptr)
7049 : Ptr(Ptr), DevPtrDecl(DevPtrDecl) {}
7050 llvm::Value *operator*() const { return Ptr; }
7051 const ValueDecl *getDevicePtrDecl() const { return DevPtrDecl; }
7052 void setDevicePtrDecl(const ValueDecl *D) { DevPtrDecl = D; }
7053 };
7054
7055 using MapBaseValuesArrayTy = SmallVector<BasePointerInfo, 4>;
7056 using MapValuesArrayTy = SmallVector<llvm::Value *, 4>;
7057 using MapFlagsArrayTy = SmallVector<OpenMPOffloadMappingFlags, 4>;
7058
7059 /// Map between a struct and the its lowest & highest elements which have been
7060 /// mapped.
7061 /// [ValueDecl *] --> {LE(FieldIndex, Pointer),
7062 /// HE(FieldIndex, Pointer)}
7063 struct StructRangeInfoTy {
7064 std::pair<unsigned /*FieldIndex*/, Address /*Pointer*/> LowestElem = {
7065 0, Address::invalid()};
7066 std::pair<unsigned /*FieldIndex*/, Address /*Pointer*/> HighestElem = {
7067 0, Address::invalid()};
7068 Address Base = Address::invalid();
7069 };
7070
7071private:
7072 /// Kind that defines how a device pointer has to be returned.
7073 struct MapInfo {
7074 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
7075 OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
7076 ArrayRef<OpenMPMapModifierKind> MapModifiers;
7077 bool ReturnDevicePointer = false;
7078 bool IsImplicit = false;
7079
7080 MapInfo() = default;
7081 MapInfo(
7082 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
7083 OpenMPMapClauseKind MapType,
7084 ArrayRef<OpenMPMapModifierKind> MapModifiers,
7085 bool ReturnDevicePointer, bool IsImplicit)
7086 : Components(Components), MapType(MapType), MapModifiers(MapModifiers),
7087 ReturnDevicePointer(ReturnDevicePointer), IsImplicit(IsImplicit) {}
7088 };
7089
7090 /// If use_device_ptr is used on a pointer which is a struct member and there
7091 /// is no map information about it, then emission of that entry is deferred
7092 /// until the whole struct has been processed.
7093 struct DeferredDevicePtrEntryTy {
7094 const Expr *IE = nullptr;
7095 const ValueDecl *VD = nullptr;
7096
7097 DeferredDevicePtrEntryTy(const Expr *IE, const ValueDecl *VD)
7098 : IE(IE), VD(VD) {}
7099 };
7100
7101 /// Directive from where the map clauses were extracted.
7102 const OMPExecutableDirective &CurDir;
7103
7104 /// Function the directive is being generated for.
7105 CodeGenFunction &CGF;
7106
7107 /// Set of all first private variables in the current directive.
7108 llvm::SmallPtrSet<const VarDecl *, 8> FirstPrivateDecls;
7109
7110 /// Map between device pointer declarations and their expression components.
7111 /// The key value for declarations in 'this' is null.
7112 llvm::DenseMap<
7113 const ValueDecl *,
7114 SmallVector<OMPClauseMappableExprCommon::MappableExprComponentListRef, 4>>
7115 DevPointersMap;
7116
7117 llvm::Value *getExprTypeSize(const Expr *E) const {
7118 QualType ExprTy = E->getType().getCanonicalType();
7119
7120 // Reference types are ignored for mapping purposes.
7121 if (const auto *RefTy = ExprTy->getAs<ReferenceType>())
7122 ExprTy = RefTy->getPointeeType().getCanonicalType();
7123
7124 // Given that an array section is considered a built-in type, we need to
7125 // do the calculation based on the length of the section instead of relying
7126 // on CGF.getTypeSize(E->getType()).
7127 if (const auto *OAE = dyn_cast<OMPArraySectionExpr>(E)) {
7128 QualType BaseTy = OMPArraySectionExpr::getBaseOriginalType(
7129 OAE->getBase()->IgnoreParenImpCasts())
7130 .getCanonicalType();
7131
7132 // If there is no length associated with the expression, that means we
7133 // are using the whole length of the base.
7134 if (!OAE->getLength() && OAE->getColonLoc().isValid())
7135 return CGF.getTypeSize(BaseTy);
7136
7137 llvm::Value *ElemSize;
7138 if (const auto *PTy = BaseTy->getAs<PointerType>()) {
7139 ElemSize = CGF.getTypeSize(PTy->getPointeeType().getCanonicalType());
7140 } else {
7141 const auto *ATy = cast<ArrayType>(BaseTy.getTypePtr());
7142 assert(ATy && "Expecting array type if not a pointer type.")((ATy && "Expecting array type if not a pointer type."
) ? static_cast<void> (0) : __assert_fail ("ATy && \"Expecting array type if not a pointer type.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7142, __PRETTY_FUNCTION__))
;
7143 ElemSize = CGF.getTypeSize(ATy->getElementType().getCanonicalType());
7144 }
7145
7146 // If we don't have a length at this point, that is because we have an
7147 // array section with a single element.
7148 if (!OAE->getLength())
7149 return ElemSize;
7150
7151 llvm::Value *LengthVal = CGF.EmitScalarExpr(OAE->getLength());
7152 LengthVal =
7153 CGF.Builder.CreateIntCast(LengthVal, CGF.SizeTy, /*isSigned=*/false);
7154 return CGF.Builder.CreateNUWMul(LengthVal, ElemSize);
7155 }
7156 return CGF.getTypeSize(ExprTy);
7157 }
7158
7159 /// Return the corresponding bits for a given map clause modifier. Add
7160 /// a flag marking the map as a pointer if requested. Add a flag marking the
7161 /// map as the first one of a series of maps that relate to the same map
7162 /// expression.
7163 OpenMPOffloadMappingFlags getMapTypeBits(
7164 OpenMPMapClauseKind MapType, ArrayRef<OpenMPMapModifierKind> MapModifiers,
7165 bool IsImplicit, bool AddPtrFlag, bool AddIsTargetParamFlag) const {
7166 OpenMPOffloadMappingFlags Bits =
7167 IsImplicit ? OMP_MAP_IMPLICIT : OMP_MAP_NONE;
7168 switch (MapType) {
7169 case OMPC_MAP_alloc:
7170 case OMPC_MAP_release:
7171 // alloc and release is the default behavior in the runtime library, i.e.
7172 // if we don't pass any bits alloc/release that is what the runtime is
7173 // going to do. Therefore, we don't need to signal anything for these two
7174 // type modifiers.
7175 break;
7176 case OMPC_MAP_to:
7177 Bits |= OMP_MAP_TO;
7178 break;
7179 case OMPC_MAP_from:
7180 Bits |= OMP_MAP_FROM;
7181 break;
7182 case OMPC_MAP_tofrom:
7183 Bits |= OMP_MAP_TO | OMP_MAP_FROM;
7184 break;
7185 case OMPC_MAP_delete:
7186 Bits |= OMP_MAP_DELETE;
7187 break;
7188 case OMPC_MAP_unknown:
7189 llvm_unreachable("Unexpected map type!")::llvm::llvm_unreachable_internal("Unexpected map type!", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7189)
;
7190 }
7191 if (AddPtrFlag)
7192 Bits |= OMP_MAP_PTR_AND_OBJ;
7193 if (AddIsTargetParamFlag)
7194 Bits |= OMP_MAP_TARGET_PARAM;
7195 if (llvm::find(MapModifiers, OMPC_MAP_MODIFIER_always)
7196 != MapModifiers.end())
7197 Bits |= OMP_MAP_ALWAYS;
7198 return Bits;
7199 }
7200
7201 /// Return true if the provided expression is a final array section. A
7202 /// final array section, is one whose length can't be proved to be one.
7203 bool isFinalArraySectionExpression(const Expr *E) const {
7204 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
7205
7206 // It is not an array section and therefore not a unity-size one.
7207 if (!OASE)
7208 return false;
7209
7210 // An array section with no colon always refer to a single element.
7211 if (OASE->getColonLoc().isInvalid())
7212 return false;
7213
7214 const Expr *Length = OASE->getLength();
7215
7216 // If we don't have a length we have to check if the array has size 1
7217 // for this dimension. Also, we should always expect a length if the
7218 // base type is pointer.
7219 if (!Length) {
7220 QualType BaseQTy = OMPArraySectionExpr::getBaseOriginalType(
7221 OASE->getBase()->IgnoreParenImpCasts())
7222 .getCanonicalType();
7223 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
7224 return ATy->getSize().getSExtValue() != 1;
7225 // If we don't have a constant dimension length, we have to consider
7226 // the current section as having any size, so it is not necessarily
7227 // unitary. If it happen to be unity size, that's user fault.
7228 return true;
7229 }
7230
7231 // Check if the length evaluates to 1.
7232 Expr::EvalResult Result;
7233 if (!Length->EvaluateAsInt(Result, CGF.getContext()))
7234 return true; // Can have more that size 1.
7235
7236 llvm::APSInt ConstLength = Result.Val.getInt();
7237 return ConstLength.getSExtValue() != 1;
7238 }
7239
7240 /// Generate the base pointers, section pointers, sizes and map type
7241 /// bits for the provided map type, map modifier, and expression components.
7242 /// \a IsFirstComponent should be set to true if the provided set of
7243 /// components is the first associated with a capture.
7244 void generateInfoForComponentList(
7245 OpenMPMapClauseKind MapType,
7246 ArrayRef<OpenMPMapModifierKind> MapModifiers,
7247 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
7248 MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
7249 MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
7250 StructRangeInfoTy &PartialStruct, bool IsFirstComponentList,
7251 bool IsImplicit,
7252 ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
7253 OverlappedElements = llvm::None) const {
7254 // The following summarizes what has to be generated for each map and the
7255 // types below. The generated information is expressed in this order:
7256 // base pointer, section pointer, size, flags
7257 // (to add to the ones that come from the map type and modifier).
7258 //
7259 // double d;
7260 // int i[100];
7261 // float *p;
7262 //
7263 // struct S1 {
7264 // int i;
7265 // float f[50];
7266 // }
7267 // struct S2 {
7268 // int i;
7269 // float f[50];
7270 // S1 s;
7271 // double *p;
7272 // struct S2 *ps;
7273 // }
7274 // S2 s;
7275 // S2 *ps;
7276 //
7277 // map(d)
7278 // &d, &d, sizeof(double), TARGET_PARAM | TO | FROM
7279 //
7280 // map(i)
7281 // &i, &i, 100*sizeof(int), TARGET_PARAM | TO | FROM
7282 //
7283 // map(i[1:23])
7284 // &i(=&i[0]), &i[1], 23*sizeof(int), TARGET_PARAM | TO | FROM
7285 //
7286 // map(p)
7287 // &p, &p, sizeof(float*), TARGET_PARAM | TO | FROM
7288 //
7289 // map(p[1:24])
7290 // p, &p[1], 24*sizeof(float), TARGET_PARAM | TO | FROM
7291 //
7292 // map(s)
7293 // &s, &s, sizeof(S2), TARGET_PARAM | TO | FROM
7294 //
7295 // map(s.i)
7296 // &s, &(s.i), sizeof(int), TARGET_PARAM | TO | FROM
7297 //
7298 // map(s.s.f)
7299 // &s, &(s.s.f[0]), 50*sizeof(float), TARGET_PARAM | TO | FROM
7300 //
7301 // map(s.p)
7302 // &s, &(s.p), sizeof(double*), TARGET_PARAM | TO | FROM
7303 //
7304 // map(to: s.p[:22])
7305 // &s, &(s.p), sizeof(double*), TARGET_PARAM (*)
7306 // &s, &(s.p), sizeof(double*), MEMBER_OF(1) (**)
7307 // &(s.p), &(s.p[0]), 22*sizeof(double),
7308 // MEMBER_OF(1) | PTR_AND_OBJ | TO (***)
7309 // (*) alloc space for struct members, only this is a target parameter
7310 // (**) map the pointer (nothing to be mapped in this example) (the compiler
7311 // optimizes this entry out, same in the examples below)
7312 // (***) map the pointee (map: to)
7313 //
7314 // map(s.ps)
7315 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM | TO | FROM
7316 //
7317 // map(from: s.ps->s.i)
7318 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7319 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7320 // &(s.ps), &(s.ps->s.i), sizeof(int), MEMBER_OF(1) | PTR_AND_OBJ | FROM
7321 //
7322 // map(to: s.ps->ps)
7323 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7324 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7325 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ | TO
7326 //
7327 // map(s.ps->ps->ps)
7328 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7329 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7330 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7331 // &(s.ps->ps), &(s.ps->ps->ps), sizeof(S2*), PTR_AND_OBJ | TO | FROM
7332 //
7333 // map(to: s.ps->ps->s.f[:22])
7334 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7335 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7336 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7337 // &(s.ps->ps), &(s.ps->ps->s.f[0]), 22*sizeof(float), PTR_AND_OBJ | TO
7338 //
7339 // map(ps)
7340 // &ps, &ps, sizeof(S2*), TARGET_PARAM | TO | FROM
7341 //
7342 // map(ps->i)
7343 // ps, &(ps->i), sizeof(int), TARGET_PARAM | TO | FROM
7344 //
7345 // map(ps->s.f)
7346 // ps, &(ps->s.f[0]), 50*sizeof(float), TARGET_PARAM | TO | FROM
7347 //
7348 // map(from: ps->p)
7349 // ps, &(ps->p), sizeof(double*), TARGET_PARAM | FROM
7350 //
7351 // map(to: ps->p[:22])
7352 // ps, &(ps->p), sizeof(double*), TARGET_PARAM
7353 // ps, &(ps->p), sizeof(double*), MEMBER_OF(1)
7354 // &(ps->p), &(ps->p[0]), 22*sizeof(double), MEMBER_OF(1) | PTR_AND_OBJ | TO
7355 //
7356 // map(ps->ps)
7357 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM | TO | FROM
7358 //
7359 // map(from: ps->ps->s.i)
7360 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7361 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7362 // &(ps->ps), &(ps->ps->s.i), sizeof(int), MEMBER_OF(1) | PTR_AND_OBJ | FROM
7363 //
7364 // map(from: ps->ps->ps)
7365 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7366 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7367 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ | FROM
7368 //
7369 // map(ps->ps->ps->ps)
7370 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7371 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7372 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7373 // &(ps->ps->ps), &(ps->ps->ps->ps), sizeof(S2*), PTR_AND_OBJ | TO | FROM
7374 //
7375 // map(to: ps->ps->ps->s.f[:22])
7376 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7377 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7378 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7379 // &(ps->ps->ps), &(ps->ps->ps->s.f[0]), 22*sizeof(float), PTR_AND_OBJ | TO
7380 //
7381 // map(to: s.f[:22]) map(from: s.p[:33])
7382 // &s, &(s.f[0]), 50*sizeof(float) + sizeof(struct S1) +
7383 // sizeof(double*) (**), TARGET_PARAM
7384 // &s, &(s.f[0]), 22*sizeof(float), MEMBER_OF(1) | TO
7385 // &s, &(s.p), sizeof(double*), MEMBER_OF(1)
7386 // &(s.p), &(s.p[0]), 33*sizeof(double), MEMBER_OF(1) | PTR_AND_OBJ | FROM
7387 // (*) allocate contiguous space needed to fit all mapped members even if
7388 // we allocate space for members not mapped (in this example,
7389 // s.f[22..49] and s.s are not mapped, yet we must allocate space for
7390 // them as well because they fall between &s.f[0] and &s.p)
7391 //
7392 // map(from: s.f[:22]) map(to: ps->p[:33])
7393 // &s, &(s.f[0]), 22*sizeof(float), TARGET_PARAM | FROM
7394 // ps, &(ps->p), sizeof(S2*), TARGET_PARAM
7395 // ps, &(ps->p), sizeof(double*), MEMBER_OF(2) (*)
7396 // &(ps->p), &(ps->p[0]), 33*sizeof(double), MEMBER_OF(2) | PTR_AND_OBJ | TO
7397 // (*) the struct this entry pertains to is the 2nd element in the list of
7398 // arguments, hence MEMBER_OF(2)
7399 //
7400 // map(from: s.f[:22], s.s) map(to: ps->p[:33])
7401 // &s, &(s.f[0]), 50*sizeof(float) + sizeof(struct S1), TARGET_PARAM
7402 // &s, &(s.f[0]), 22*sizeof(float), MEMBER_OF(1) | FROM
7403 // &s, &(s.s), sizeof(struct S1), MEMBER_OF(1) | FROM
7404 // ps, &(ps->p), sizeof(S2*), TARGET_PARAM
7405 // ps, &(ps->p), sizeof(double*), MEMBER_OF(4) (*)
7406 // &(ps->p), &(ps->p[0]), 33*sizeof(double), MEMBER_OF(4) | PTR_AND_OBJ | TO
7407 // (*) the struct this entry pertains to is the 4th element in the list
7408 // of arguments, hence MEMBER_OF(4)
7409
7410 // Track if the map information being generated is the first for a capture.
7411 bool IsCaptureFirstInfo = IsFirstComponentList;
7412 bool IsLink = false; // Is this variable a "declare target link"?
7413
7414 // Scan the components from the base to the complete expression.
7415 auto CI = Components.rbegin();
7416 auto CE = Components.rend();
7417 auto I = CI;
7418
7419 // Track if the map information being generated is the first for a list of
7420 // components.
7421 bool IsExpressionFirstInfo = true;
7422 Address BP = Address::invalid();
7423 const Expr *AssocExpr = I->getAssociatedExpression();
7424 const auto *AE = dyn_cast<ArraySubscriptExpr>(AssocExpr);
7425 const auto *OASE = dyn_cast<OMPArraySectionExpr>(AssocExpr);
7426
7427 if (isa<MemberExpr>(AssocExpr)) {
7428 // The base is the 'this' pointer. The content of the pointer is going
7429 // to be the base of the field being mapped.
7430 BP = CGF.LoadCXXThisAddress();
7431 } else if ((AE && isa<CXXThisExpr>(AE->getBase()->IgnoreParenImpCasts())) ||
7432 (OASE &&
7433 isa<CXXThisExpr>(OASE->getBase()->IgnoreParenImpCasts()))) {
7434 BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress();
7435 } else {
7436 // The base is the reference to the variable.
7437 // BP = &Var.
7438 BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress();
7439 if (const auto *VD =
7440 dyn_cast_or_null<VarDecl>(I->getAssociatedDeclaration())) {
7441 if (llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
7442 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
7443 if (*Res == OMPDeclareTargetDeclAttr::MT_Link) {
7444 IsLink = true;
7445 BP = CGF.CGM.getOpenMPRuntime().getAddrOfDeclareTargetLink(VD);
7446 }
7447 }
7448
7449 // If the variable is a pointer and is being dereferenced (i.e. is not
7450 // the last component), the base has to be the pointer itself, not its
7451 // reference. References are ignored for mapping purposes.
7452 QualType Ty =
7453 I->getAssociatedDeclaration()->getType().getNonReferenceType();
7454 if (Ty->isAnyPointerType() && std::next(I) != CE) {
7455 BP = CGF.EmitLoadOfPointer(BP, Ty->castAs<PointerType>());
7456
7457 // We do not need to generate individual map information for the
7458 // pointer, it can be associated with the combined storage.
7459 ++I;
7460 }
7461 }
7462
7463 // Track whether a component of the list should be marked as MEMBER_OF some
7464 // combined entry (for partial structs). Only the first PTR_AND_OBJ entry
7465 // in a component list should be marked as MEMBER_OF, all subsequent entries
7466 // do not belong to the base struct. E.g.
7467 // struct S2 s;
7468 // s.ps->ps->ps->f[:]
7469 // (1) (2) (3) (4)
7470 // ps(1) is a member pointer, ps(2) is a pointee of ps(1), so it is a
7471 // PTR_AND_OBJ entry; the PTR is ps(1), so MEMBER_OF the base struct. ps(3)
7472 // is the pointee of ps(2) which is not member of struct s, so it should not
7473 // be marked as such (it is still PTR_AND_OBJ).
7474 // The variable is initialized to false so that PTR_AND_OBJ entries which
7475 // are not struct members are not considered (e.g. array of pointers to
7476 // data).
7477 bool ShouldBeMemberOf = false;
7478
7479 // Variable keeping track of whether or not we have encountered a component
7480 // in the component list which is a member expression. Useful when we have a
7481 // pointer or a final array section, in which case it is the previous
7482 // component in the list which tells us whether we have a member expression.
7483 // E.g. X.f[:]
7484 // While processing the final array section "[:]" it is "f" which tells us
7485 // whether we are dealing with a member of a declared struct.
7486 const MemberExpr *EncounteredME = nullptr;
7487
7488 for (; I != CE; ++I) {
7489 // If the current component is member of a struct (parent struct) mark it.
7490 if (!EncounteredME) {
7491 EncounteredME = dyn_cast<MemberExpr>(I->getAssociatedExpression());
7492 // If we encounter a PTR_AND_OBJ entry from now on it should be marked
7493 // as MEMBER_OF the parent struct.
7494 if (EncounteredME)
7495 ShouldBeMemberOf = true;
7496 }
7497
7498 auto Next = std::next(I);
7499
7500 // We need to generate the addresses and sizes if this is the last
7501 // component, if the component is a pointer or if it is an array section
7502 // whose length can't be proved to be one. If this is a pointer, it
7503 // becomes the base address for the following components.
7504
7505 // A final array section, is one whose length can't be proved to be one.
7506 bool IsFinalArraySection =
7507 isFinalArraySectionExpression(I->getAssociatedExpression());
7508
7509 // Get information on whether the element is a pointer. Have to do a
7510 // special treatment for array sections given that they are built-in
7511 // types.
7512 const auto *OASE =
7513 dyn_cast<OMPArraySectionExpr>(I->getAssociatedExpression());
7514 bool IsPointer =
7515 (OASE && OMPArraySectionExpr::getBaseOriginalType(OASE)
7516 .getCanonicalType()
7517 ->isAnyPointerType()) ||
7518 I->getAssociatedExpression()->getType()->isAnyPointerType();
7519
7520 if (Next == CE || IsPointer || IsFinalArraySection) {
7521 // If this is not the last component, we expect the pointer to be
7522 // associated with an array expression or member expression.
7523 assert((Next == CE ||(((Next == CE || isa<MemberExpr>(Next->getAssociatedExpression
()) || isa<ArraySubscriptExpr>(Next->getAssociatedExpression
()) || isa<OMPArraySectionExpr>(Next->getAssociatedExpression
())) && "Unexpected expression") ? static_cast<void
> (0) : __assert_fail ("(Next == CE || isa<MemberExpr>(Next->getAssociatedExpression()) || isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) || isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) && \"Unexpected expression\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7527, __PRETTY_FUNCTION__))
7524 isa<MemberExpr>(Next->getAssociatedExpression()) ||(((Next == CE || isa<MemberExpr>(Next->getAssociatedExpression
()) || isa<ArraySubscriptExpr>(Next->getAssociatedExpression
()) || isa<OMPArraySectionExpr>(Next->getAssociatedExpression
())) && "Unexpected expression") ? static_cast<void
> (0) : __assert_fail ("(Next == CE || isa<MemberExpr>(Next->getAssociatedExpression()) || isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) || isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) && \"Unexpected expression\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7527, __PRETTY_FUNCTION__))
7525 isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) ||(((Next == CE || isa<MemberExpr>(Next->getAssociatedExpression
()) || isa<ArraySubscriptExpr>(Next->getAssociatedExpression
()) || isa<OMPArraySectionExpr>(Next->getAssociatedExpression
())) && "Unexpected expression") ? static_cast<void
> (0) : __assert_fail ("(Next == CE || isa<MemberExpr>(Next->getAssociatedExpression()) || isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) || isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) && \"Unexpected expression\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7527, __PRETTY_FUNCTION__))
7526 isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) &&(((Next == CE || isa<MemberExpr>(Next->getAssociatedExpression
()) || isa<ArraySubscriptExpr>(Next->getAssociatedExpression
()) || isa<OMPArraySectionExpr>(Next->getAssociatedExpression
())) && "Unexpected expression") ? static_cast<void
> (0) : __assert_fail ("(Next == CE || isa<MemberExpr>(Next->getAssociatedExpression()) || isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) || isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) && \"Unexpected expression\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7527, __PRETTY_FUNCTION__))
7527 "Unexpected expression")(((Next == CE || isa<MemberExpr>(Next->getAssociatedExpression
()) || isa<ArraySubscriptExpr>(Next->getAssociatedExpression
()) || isa<OMPArraySectionExpr>(Next->getAssociatedExpression
())) && "Unexpected expression") ? static_cast<void
> (0) : __assert_fail ("(Next == CE || isa<MemberExpr>(Next->getAssociatedExpression()) || isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) || isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) && \"Unexpected expression\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7527, __PRETTY_FUNCTION__))
;
7528
7529 Address LB =
7530 CGF.EmitOMPSharedLValue(I->getAssociatedExpression()).getAddress();
7531
7532 // If this component is a pointer inside the base struct then we don't
7533 // need to create any entry for it - it will be combined with the object
7534 // it is pointing to into a single PTR_AND_OBJ entry.
7535 bool IsMemberPointer =
7536 IsPointer && EncounteredME &&
7537 (dyn_cast<MemberExpr>(I->getAssociatedExpression()) ==
7538 EncounteredME);
7539 if (!OverlappedElements.empty()) {
7540 // Handle base element with the info for overlapped elements.
7541 assert(!PartialStruct.Base.isValid() && "The base element is set.")((!PartialStruct.Base.isValid() && "The base element is set."
) ? static_cast<void> (0) : __assert_fail ("!PartialStruct.Base.isValid() && \"The base element is set.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7541, __PRETTY_FUNCTION__))
;
7542 assert(Next == CE &&((Next == CE && "Expected last element for the overlapped elements."
) ? static_cast<void> (0) : __assert_fail ("Next == CE && \"Expected last element for the overlapped elements.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7543, __PRETTY_FUNCTION__))
7543 "Expected last element for the overlapped elements.")((Next == CE && "Expected last element for the overlapped elements."
) ? static_cast<void> (0) : __assert_fail ("Next == CE && \"Expected last element for the overlapped elements.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7543, __PRETTY_FUNCTION__))
;
7544 assert(!IsPointer &&((!IsPointer && "Unexpected base element with the pointer type."
) ? static_cast<void> (0) : __assert_fail ("!IsPointer && \"Unexpected base element with the pointer type.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7545, __PRETTY_FUNCTION__))
7545 "Unexpected base element with the pointer type.")((!IsPointer && "Unexpected base element with the pointer type."
) ? static_cast<void> (0) : __assert_fail ("!IsPointer && \"Unexpected base element with the pointer type.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7545, __PRETTY_FUNCTION__))
;
7546 // Mark the whole struct as the struct that requires allocation on the
7547 // device.
7548 PartialStruct.LowestElem = {0, LB};
7549 CharUnits TypeSize = CGF.getContext().getTypeSizeInChars(
7550 I->getAssociatedExpression()->getType());
7551 Address HB = CGF.Builder.CreateConstGEP(
7552 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(LB,
7553 CGF.VoidPtrTy),
7554 TypeSize.getQuantity() - 1);
7555 PartialStruct.HighestElem = {
7556 std::numeric_limits<decltype(
7557 PartialStruct.HighestElem.first)>::max(),
7558 HB};
7559 PartialStruct.Base = BP;
7560 // Emit data for non-overlapped data.
7561 OpenMPOffloadMappingFlags Flags =
7562 OMP_MAP_MEMBER_OF |
7563 getMapTypeBits(MapType, MapModifiers, IsImplicit,
7564 /*AddPtrFlag=*/false,
7565 /*AddIsTargetParamFlag=*/false);
7566 LB = BP;
7567 llvm::Value *Size = nullptr;
7568 // Do bitcopy of all non-overlapped structure elements.
7569 for (OMPClauseMappableExprCommon::MappableExprComponentListRef
7570 Component : OverlappedElements) {
7571 Address ComponentLB = Address::invalid();
7572 for (const OMPClauseMappableExprCommon::MappableComponent &MC :
7573 Component) {
7574 if (MC.getAssociatedDeclaration()) {
7575 ComponentLB =
7576 CGF.EmitOMPSharedLValue(MC.getAssociatedExpression())
7577 .getAddress();
7578 Size = CGF.Builder.CreatePtrDiff(
7579 CGF.EmitCastToVoidPtr(ComponentLB.getPointer()),
7580 CGF.EmitCastToVoidPtr(LB.getPointer()));
7581 break;
7582 }
7583 }
7584 BasePointers.push_back(BP.getPointer());
7585 Pointers.push_back(LB.getPointer());
7586 Sizes.push_back(Size);
7587 Types.push_back(Flags);
7588 LB = CGF.Builder.CreateConstGEP(ComponentLB, 1);
7589 }
7590 BasePointers.push_back(BP.getPointer());
7591 Pointers.push_back(LB.getPointer());
7592 Size = CGF.Builder.CreatePtrDiff(
7593 CGF.EmitCastToVoidPtr(
7594 CGF.Builder.CreateConstGEP(HB, 1).getPointer()),
7595 CGF.EmitCastToVoidPtr(LB.getPointer()));
7596 Sizes.push_back(Size);
7597 Types.push_back(Flags);
7598 break;
7599 }
7600 llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
7601 if (!IsMemberPointer) {
7602 BasePointers.push_back(BP.getPointer());
7603 Pointers.push_back(LB.getPointer());
7604 Sizes.push_back(Size);
7605
7606 // We need to add a pointer flag for each map that comes from the
7607 // same expression except for the first one. We also need to signal
7608 // this map is the first one that relates with the current capture
7609 // (there is a set of entries for each capture).
7610 OpenMPOffloadMappingFlags Flags = getMapTypeBits(
7611 MapType, MapModifiers, IsImplicit,
7612 !IsExpressionFirstInfo || IsLink, IsCaptureFirstInfo && !IsLink);
7613
7614 if (!IsExpressionFirstInfo) {
7615 // If we have a PTR_AND_OBJ pair where the OBJ is a pointer as well,
7616 // then we reset the TO/FROM/ALWAYS/DELETE flags.
7617 if (IsPointer)
7618 Flags &= ~(OMP_MAP_TO | OMP_MAP_FROM | OMP_MAP_ALWAYS |
7619 OMP_MAP_DELETE);
7620
7621 if (ShouldBeMemberOf) {
7622 // Set placeholder value MEMBER_OF=FFFF to indicate that the flag
7623 // should be later updated with the correct value of MEMBER_OF.
7624 Flags |= OMP_MAP_MEMBER_OF;
7625 // From now on, all subsequent PTR_AND_OBJ entries should not be
7626 // marked as MEMBER_OF.
7627 ShouldBeMemberOf = false;
7628 }
7629 }
7630
7631 Types.push_back(Flags);
7632 }
7633
7634 // If we have encountered a member expression so far, keep track of the
7635 // mapped member. If the parent is "*this", then the value declaration
7636 // is nullptr.
7637 if (EncounteredME) {
7638 const auto *FD = dyn_cast<FieldDecl>(EncounteredME->getMemberDecl());
7639 unsigned FieldIndex = FD->getFieldIndex();
7640
7641 // Update info about the lowest and highest elements for this struct
7642 if (!PartialStruct.Base.isValid()) {
7643 PartialStruct.LowestElem = {FieldIndex, LB};
7644 PartialStruct.HighestElem = {FieldIndex, LB};
7645 PartialStruct.Base = BP;
7646 } else if (FieldIndex < PartialStruct.LowestElem.first) {
7647 PartialStruct.LowestElem = {FieldIndex, LB};
7648 } else if (FieldIndex > PartialStruct.HighestElem.first) {
7649 PartialStruct.HighestElem = {FieldIndex, LB};
7650 }
7651 }
7652
7653 // If we have a final array section, we are done with this expression.
7654 if (IsFinalArraySection)
7655 break;
7656
7657 // The pointer becomes the base for the next element.
7658 if (Next != CE)
7659 BP = LB;
7660
7661 IsExpressionFirstInfo = false;
7662 IsCaptureFirstInfo = false;
7663 }
7664 }
7665 }
7666
7667 /// Return the adjusted map modifiers if the declaration a capture refers to
7668 /// appears in a first-private clause. This is expected to be used only with
7669 /// directives that start with 'target'.
7670 MappableExprsHandler::OpenMPOffloadMappingFlags
7671 getMapModifiersForPrivateClauses(const CapturedStmt::Capture &Cap) const {
7672 assert(Cap.capturesVariable() && "Expected capture by reference only!")((Cap.capturesVariable() && "Expected capture by reference only!"
) ? static_cast<void> (0) : __assert_fail ("Cap.capturesVariable() && \"Expected capture by reference only!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7672, __PRETTY_FUNCTION__))
;
7673
7674 // A first private variable captured by reference will use only the
7675 // 'private ptr' and 'map to' flag. Return the right flags if the captured
7676 // declaration is known as first-private in this handler.
7677 if (FirstPrivateDecls.count(Cap.getCapturedVar())) {
7678 if (Cap.getCapturedVar()->getType().isConstant(CGF.getContext()) &&
7679 Cap.getCaptureKind() == CapturedStmt::VCK_ByRef)
7680 return MappableExprsHandler::OMP_MAP_ALWAYS |
7681 MappableExprsHandler::OMP_MAP_TO;
7682 if (Cap.getCapturedVar()->getType()->isAnyPointerType())
7683 return MappableExprsHandler::OMP_MAP_TO |
7684 MappableExprsHandler::OMP_MAP_PTR_AND_OBJ;
7685 return MappableExprsHandler::OMP_MAP_PRIVATE |
7686 MappableExprsHandler::OMP_MAP_TO;
7687 }
7688 return MappableExprsHandler::OMP_MAP_TO |
7689 MappableExprsHandler::OMP_MAP_FROM;
7690 }
7691
7692 static OpenMPOffloadMappingFlags getMemberOfFlag(unsigned Position) {
7693 // Member of is given by the 16 MSB of the flag, so rotate by 48 bits.
7694 return static_cast<OpenMPOffloadMappingFlags>(((uint64_t)Position + 1)
7695 << 48);
7696 }
7697
7698 static void setCorrectMemberOfFlag(OpenMPOffloadMappingFlags &Flags,
7699 OpenMPOffloadMappingFlags MemberOfFlag) {
7700 // If the entry is PTR_AND_OBJ but has not been marked with the special
7701 // placeholder value 0xFFFF in the MEMBER_OF field, then it should not be
7702 // marked as MEMBER_OF.
7703 if ((Flags & OMP_MAP_PTR_AND_OBJ) &&
7704 ((Flags & OMP_MAP_MEMBER_OF) != OMP_MAP_MEMBER_OF))
7705 return;
7706
7707 // Reset the placeholder value to prepare the flag for the assignment of the
7708 // proper MEMBER_OF value.
7709 Flags &= ~OMP_MAP_MEMBER_OF;
7710 Flags |= MemberOfFlag;
7711 }
7712
7713 void getPlainLayout(const CXXRecordDecl *RD,
7714 llvm::SmallVectorImpl<const FieldDecl *> &Layout,
7715 bool AsBase) const {
7716 const CGRecordLayout &RL = CGF.getTypes().getCGRecordLayout(RD);
7717
7718 llvm::StructType *St =
7719 AsBase ? RL.getBaseSubobjectLLVMType() : RL.getLLVMType();
7720
7721 unsigned NumElements = St->getNumElements();
7722 llvm::SmallVector<
7723 llvm::PointerUnion<const CXXRecordDecl *, const FieldDecl *>, 4>
7724 RecordLayout(NumElements);
7725
7726 // Fill bases.
7727 for (const auto &I : RD->bases()) {
7728 if (I.isVirtual())
7729 continue;
7730 const auto *Base = I.getType()->getAsCXXRecordDecl();
7731 // Ignore empty bases.
7732 if (Base->isEmpty() || CGF.getContext()
7733 .getASTRecordLayout(Base)
7734 .getNonVirtualSize()
7735 .isZero())
7736 continue;
7737
7738 unsigned FieldIndex = RL.getNonVirtualBaseLLVMFieldNo(Base);
7739 RecordLayout[FieldIndex] = Base;
7740 }
7741 // Fill in virtual bases.
7742 for (const auto &I : RD->vbases()) {
7743 const auto *Base = I.getType()->getAsCXXRecordDecl();
7744 // Ignore empty bases.
7745 if (Base->isEmpty())
7746 continue;
7747 unsigned FieldIndex = RL.getVirtualBaseIndex(Base);
7748 if (RecordLayout[FieldIndex])
7749 continue;
7750 RecordLayout[FieldIndex] = Base;
7751 }
7752 // Fill in all the fields.
7753 assert(!RD->isUnion() && "Unexpected union.")((!RD->isUnion() && "Unexpected union.") ? static_cast
<void> (0) : __assert_fail ("!RD->isUnion() && \"Unexpected union.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7753, __PRETTY_FUNCTION__))
;
7754 for (const auto *Field : RD->fields()) {
7755 // Fill in non-bitfields. (Bitfields always use a zero pattern, which we
7756 // will fill in later.)
7757 if (!Field->isBitField()) {
7758 unsigned FieldIndex = RL.getLLVMFieldNo(Field);
7759 RecordLayout[FieldIndex] = Field;
7760 }
7761 }
7762 for (const llvm::PointerUnion<const CXXRecordDecl *, const FieldDecl *>
7763 &Data : RecordLayout) {
7764 if (Data.isNull())
7765 continue;
7766 if (const auto *Base = Data.dyn_cast<const CXXRecordDecl *>())
7767 getPlainLayout(Base, Layout, /*AsBase=*/true);
7768 else
7769 Layout.push_back(Data.get<const FieldDecl *>());
7770 }
7771 }
7772
7773public:
7774 MappableExprsHandler(const OMPExecutableDirective &Dir, CodeGenFunction &CGF)
7775 : CurDir(Dir), CGF(CGF) {
7776 // Extract firstprivate clause information.
7777 for (const auto *C : Dir.getClausesOfKind<OMPFirstprivateClause>())
7778 for (const auto *D : C->varlists())
7779 FirstPrivateDecls.insert(
7780 cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl());
7781 // Extract device pointer clause information.
7782 for (const auto *C : Dir.getClausesOfKind<OMPIsDevicePtrClause>())
7783 for (auto L : C->component_lists())
7784 DevPointersMap[L.first].push_back(L.second);
7785 }
7786
7787 /// Generate code for the combined entry if we have a partially mapped struct
7788 /// and take care of the mapping flags of the arguments corresponding to
7789 /// individual struct members.
7790 void emitCombinedEntry(MapBaseValuesArrayTy &BasePointers,
7791 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
7792 MapFlagsArrayTy &Types, MapFlagsArrayTy &CurTypes,
7793 const StructRangeInfoTy &PartialStruct) const {
7794 // Base is the base of the struct
7795 BasePointers.push_back(PartialStruct.Base.getPointer());
7796 // Pointer is the address of the lowest element
7797 llvm::Value *LB = PartialStruct.LowestElem.second.getPointer();
7798 Pointers.push_back(LB);
7799 // Size is (addr of {highest+1} element) - (addr of lowest element)
7800 llvm::Value *HB = PartialStruct.HighestElem.second.getPointer();
7801 llvm::Value *HAddr = CGF.Builder.CreateConstGEP1_32(HB, /*Idx0=*/1);
7802 llvm::Value *CLAddr = CGF.Builder.CreatePointerCast(LB, CGF.VoidPtrTy);
7803 llvm::Value *CHAddr = CGF.Builder.CreatePointerCast(HAddr, CGF.VoidPtrTy);
7804 llvm::Value *Diff = CGF.Builder.CreatePtrDiff(CHAddr, CLAddr);
7805 llvm::Value *Size = CGF.Builder.CreateIntCast(Diff, CGF.SizeTy,
7806 /*isSinged=*/false);
7807 Sizes.push_back(Size);
7808 // Map type is always TARGET_PARAM
7809 Types.push_back(OMP_MAP_TARGET_PARAM);
7810 // Remove TARGET_PARAM flag from the first element
7811 (*CurTypes.begin()) &= ~OMP_MAP_TARGET_PARAM;
7812
7813 // All other current entries will be MEMBER_OF the combined entry
7814 // (except for PTR_AND_OBJ entries which do not have a placeholder value
7815 // 0xFFFF in the MEMBER_OF field).
7816 OpenMPOffloadMappingFlags MemberOfFlag =
7817 getMemberOfFlag(BasePointers.size() - 1);
7818 for (auto &M : CurTypes)
7819 setCorrectMemberOfFlag(M, MemberOfFlag);
7820 }
7821
7822 /// Generate all the base pointers, section pointers, sizes and map
7823 /// types for the extracted mappable expressions. Also, for each item that
7824 /// relates with a device pointer, a pair of the relevant declaration and
7825 /// index where it occurs is appended to the device pointers info array.
7826 void generateAllInfo(MapBaseValuesArrayTy &BasePointers,
7827 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
7828 MapFlagsArrayTy &Types) const {
7829 // We have to process the component lists that relate with the same
7830 // declaration in a single chunk so that we can generate the map flags
7831 // correctly. Therefore, we organize all lists in a map.
7832 llvm::MapVector<const ValueDecl *, SmallVector<MapInfo, 8>> Info;
7833
7834 // Helper function to fill the information map for the different supported
7835 // clauses.
7836 auto &&InfoGen = [&Info](
7837 const ValueDecl *D,
7838 OMPClauseMappableExprCommon::MappableExprComponentListRef L,
7839 OpenMPMapClauseKind MapType,
7840 ArrayRef<OpenMPMapModifierKind> MapModifiers,
7841 bool ReturnDevicePointer, bool IsImplicit) {
7842 const ValueDecl *VD =
7843 D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
7844 Info[VD].emplace_back(L, MapType, MapModifiers, ReturnDevicePointer,
7845 IsImplicit);
7846 };
7847
7848 // FIXME: MSVC 2013 seems to require this-> to find member CurDir.
7849 for (const auto *C : this->CurDir.getClausesOfKind<OMPMapClause>())
7850 for (const auto &L : C->component_lists()) {
7851 InfoGen(L.first, L.second, C->getMapType(), C->getMapTypeModifiers(),
7852 /*ReturnDevicePointer=*/false, C->isImplicit());
7853 }
7854 for (const auto *C : this->CurDir.getClausesOfKind<OMPToClause>())
7855 for (const auto &L : C->component_lists()) {
7856 InfoGen(L.first, L.second, OMPC_MAP_to, llvm::None,
7857 /*ReturnDevicePointer=*/false, C->isImplicit());
7858 }
7859 for (const auto *C : this->CurDir.getClausesOfKind<OMPFromClause>())
7860 for (const auto &L : C->component_lists()) {
7861 InfoGen(L.first, L.second, OMPC_MAP_from, llvm::None,
7862 /*ReturnDevicePointer=*/false, C->isImplicit());
7863 }
7864
7865 // Look at the use_device_ptr clause information and mark the existing map
7866 // entries as such. If there is no map information for an entry in the
7867 // use_device_ptr list, we create one with map type 'alloc' and zero size
7868 // section. It is the user fault if that was not mapped before. If there is
7869 // no map information and the pointer is a struct member, then we defer the
7870 // emission of that entry until the whole struct has been processed.
7871 llvm::MapVector<const ValueDecl *, SmallVector<DeferredDevicePtrEntryTy, 4>>
7872 DeferredInfo;
7873
7874 // FIXME: MSVC 2013 seems to require this-> to find member CurDir.
7875 for (const auto *C :
7876 this->CurDir.getClausesOfKind<OMPUseDevicePtrClause>()) {
7877 for (const auto &L : C->component_lists()) {
7878 assert(!L.second.empty() && "Not expecting empty list of components!")((!L.second.empty() && "Not expecting empty list of components!"
) ? static_cast<void> (0) : __assert_fail ("!L.second.empty() && \"Not expecting empty list of components!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7878, __PRETTY_FUNCTION__))
;
7879 const ValueDecl *VD = L.second.back().getAssociatedDeclaration();
7880 VD = cast<ValueDecl>(VD->getCanonicalDecl());
7881 const Expr *IE = L.second.back().getAssociatedExpression();
7882 // If the first component is a member expression, we have to look into
7883 // 'this', which maps to null in the map of map information. Otherwise
7884 // look directly for the information.
7885 auto It = Info.find(isa<MemberExpr>(IE) ? nullptr : VD);
7886
7887 // We potentially have map information for this declaration already.
7888 // Look for the first set of components that refer to it.
7889 if (It != Info.end()) {
7890 auto CI = std::find_if(
7891 It->second.begin(), It->second.end(), [VD](const MapInfo &MI) {
7892 return MI.Components.back().getAssociatedDeclaration() == VD;
7893 });
7894 // If we found a map entry, signal that the pointer has to be returned
7895 // and move on to the next declaration.
7896 if (CI != It->second.end()) {
7897 CI->ReturnDevicePointer = true;
7898 continue;
7899 }
7900 }
7901
7902 // We didn't find any match in our map information - generate a zero
7903 // size array section - if the pointer is a struct member we defer this
7904 // action until the whole struct has been processed.
7905 // FIXME: MSVC 2013 seems to require this-> to find member CGF.
7906 if (isa<MemberExpr>(IE)) {
7907 // Insert the pointer into Info to be processed by
7908 // generateInfoForComponentList. Because it is a member pointer
7909 // without a pointee, no entry will be generated for it, therefore
7910 // we need to generate one after the whole struct has been processed.
7911 // Nonetheless, generateInfoForComponentList must be called to take
7912 // the pointer into account for the calculation of the range of the
7913 // partial struct.
7914 InfoGen(nullptr, L.second, OMPC_MAP_unknown, llvm::None,
7915 /*ReturnDevicePointer=*/false, C->isImplicit());
7916 DeferredInfo[nullptr].emplace_back(IE, VD);
7917 } else {
7918 llvm::Value *Ptr = this->CGF.EmitLoadOfScalar(
7919 this->CGF.EmitLValue(IE), IE->getExprLoc());
7920 BasePointers.emplace_back(Ptr, VD);
7921 Pointers.push_back(Ptr);
7922 Sizes.push_back(llvm::Constant::getNullValue(this->CGF.SizeTy));
7923 Types.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_TARGET_PARAM);
7924 }
7925 }
7926 }
7927
7928 for (const auto &M : Info) {
7929 // We need to know when we generate information for the first component
7930 // associated with a capture, because the mapping flags depend on it.
7931 bool IsFirstComponentList = true;
7932
7933 // Temporary versions of arrays
7934 MapBaseValuesArrayTy CurBasePointers;
7935 MapValuesArrayTy CurPointers;
7936 MapValuesArrayTy CurSizes;
7937 MapFlagsArrayTy CurTypes;
7938 StructRangeInfoTy PartialStruct;
7939
7940 for (const MapInfo &L : M.second) {
7941 assert(!L.Components.empty() &&((!L.Components.empty() && "Not expecting declaration with no component lists."
) ? static_cast<void> (0) : __assert_fail ("!L.Components.empty() && \"Not expecting declaration with no component lists.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7942, __PRETTY_FUNCTION__))
7942 "Not expecting declaration with no component lists.")((!L.Components.empty() && "Not expecting declaration with no component lists."
) ? static_cast<void> (0) : __assert_fail ("!L.Components.empty() && \"Not expecting declaration with no component lists.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7942, __PRETTY_FUNCTION__))
;
7943
7944 // Remember the current base pointer index.
7945 unsigned CurrentBasePointersIdx = CurBasePointers.size();
7946 // FIXME: MSVC 2013 seems to require this-> to find the member method.
7947 this->generateInfoForComponentList(
7948 L.MapType, L.MapModifiers, L.Components, CurBasePointers,
7949 CurPointers, CurSizes, CurTypes, PartialStruct,
7950 IsFirstComponentList, L.IsImplicit);
7951
7952 // If this entry relates with a device pointer, set the relevant
7953 // declaration and add the 'return pointer' flag.
7954 if (L.ReturnDevicePointer) {
7955 assert(CurBasePointers.size() > CurrentBasePointersIdx &&((CurBasePointers.size() > CurrentBasePointersIdx &&
"Unexpected number of mapped base pointers.") ? static_cast<
void> (0) : __assert_fail ("CurBasePointers.size() > CurrentBasePointersIdx && \"Unexpected number of mapped base pointers.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7956, __PRETTY_FUNCTION__))
7956 "Unexpected number of mapped base pointers.")((CurBasePointers.size() > CurrentBasePointersIdx &&
"Unexpected number of mapped base pointers.") ? static_cast<
void> (0) : __assert_fail ("CurBasePointers.size() > CurrentBasePointersIdx && \"Unexpected number of mapped base pointers.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7956, __PRETTY_FUNCTION__))
;
7957
7958 const ValueDecl *RelevantVD =
7959 L.Components.back().getAssociatedDeclaration();
7960 assert(RelevantVD &&((RelevantVD && "No relevant declaration related with device pointer??"
) ? static_cast<void> (0) : __assert_fail ("RelevantVD && \"No relevant declaration related with device pointer??\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7961, __PRETTY_FUNCTION__))
7961 "No relevant declaration related with device pointer??")((RelevantVD && "No relevant declaration related with device pointer??"
) ? static_cast<void> (0) : __assert_fail ("RelevantVD && \"No relevant declaration related with device pointer??\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 7961, __PRETTY_FUNCTION__))
;
7962
7963 CurBasePointers[CurrentBasePointersIdx].setDevicePtrDecl(RelevantVD);
7964 CurTypes[CurrentBasePointersIdx] |= OMP_MAP_RETURN_PARAM;
7965 }
7966 IsFirstComponentList = false;
7967 }
7968
7969 // Append any pending zero-length pointers which are struct members and
7970 // used with use_device_ptr.
7971 auto CI = DeferredInfo.find(M.first);
7972 if (CI != DeferredInfo.end()) {
7973 for (const DeferredDevicePtrEntryTy &L : CI->second) {
7974 llvm::Value *BasePtr = this->CGF.EmitLValue(L.IE).getPointer();
7975 llvm::Value *Ptr = this->CGF.EmitLoadOfScalar(
7976 this->CGF.EmitLValue(L.IE), L.IE->getExprLoc());
7977 CurBasePointers.emplace_back(BasePtr, L.VD);
7978 CurPointers.push_back(Ptr);
7979 CurSizes.push_back(llvm::Constant::getNullValue(this->CGF.SizeTy));
7980 // Entry is PTR_AND_OBJ and RETURN_PARAM. Also, set the placeholder
7981 // value MEMBER_OF=FFFF so that the entry is later updated with the
7982 // correct value of MEMBER_OF.
7983 CurTypes.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_RETURN_PARAM |
7984 OMP_MAP_MEMBER_OF);
7985 }
7986 }
7987
7988 // If there is an entry in PartialStruct it means we have a struct with
7989 // individual members mapped. Emit an extra combined entry.
7990 if (PartialStruct.Base.isValid())
7991 emitCombinedEntry(BasePointers, Pointers, Sizes, Types, CurTypes,
7992 PartialStruct);
7993
7994 // We need to append the results of this capture to what we already have.
7995 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
7996 Pointers.append(CurPointers.begin(), CurPointers.end());
7997 Sizes.append(CurSizes.begin(), CurSizes.end());
7998 Types.append(CurTypes.begin(), CurTypes.end());
7999 }
8000 }
8001
8002 /// Emit capture info for lambdas for variables captured by reference.
8003 void generateInfoForLambdaCaptures(
8004 const ValueDecl *VD, llvm::Value *Arg, MapBaseValuesArrayTy &BasePointers,
8005 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
8006 MapFlagsArrayTy &Types,
8007 llvm::DenseMap<llvm::Value *, llvm::Value *> &LambdaPointers) const {
8008 const auto *RD = VD->getType()
8009 .getCanonicalType()
8010 .getNonReferenceType()
8011 ->getAsCXXRecordDecl();
8012 if (!RD || !RD->isLambda())
8013 return;
8014 Address VDAddr = Address(Arg, CGF.getContext().getDeclAlign(VD));
8015 LValue VDLVal = CGF.MakeAddrLValue(
8016 VDAddr, VD->getType().getCanonicalType().getNonReferenceType());
8017 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
8018 FieldDecl *ThisCapture = nullptr;
8019 RD->getCaptureFields(Captures, ThisCapture);
8020 if (ThisCapture) {
8021 LValue ThisLVal =
8022 CGF.EmitLValueForFieldInitialization(VDLVal, ThisCapture);
8023 LValue ThisLValVal = CGF.EmitLValueForField(VDLVal, ThisCapture);
8024 LambdaPointers.try_emplace(ThisLVal.getPointer(), VDLVal.getPointer());
8025 BasePointers.push_back(ThisLVal.getPointer());
8026 Pointers.push_back(ThisLValVal.getPointer());
8027 Sizes.push_back(CGF.getTypeSize(CGF.getContext().VoidPtrTy));
8028 Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
8029 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT);
8030 }
8031 for (const LambdaCapture &LC : RD->captures()) {
8032 if (LC.getCaptureKind() != LCK_ByRef)
8033 continue;
8034 const VarDecl *VD = LC.getCapturedVar();
8035 auto It = Captures.find(VD);
8036 assert(It != Captures.end() && "Found lambda capture without field.")((It != Captures.end() && "Found lambda capture without field."
) ? static_cast<void> (0) : __assert_fail ("It != Captures.end() && \"Found lambda capture without field.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8036, __PRETTY_FUNCTION__))
;
8037 LValue VarLVal = CGF.EmitLValueForFieldInitialization(VDLVal, It->second);
8038 LValue VarLValVal = CGF.EmitLValueForField(VDLVal, It->second);
8039 LambdaPointers.try_emplace(VarLVal.getPointer(), VDLVal.getPointer());
8040 BasePointers.push_back(VarLVal.getPointer());
8041 Pointers.push_back(VarLValVal.getPointer());
8042 Sizes.push_back(CGF.getTypeSize(
8043 VD->getType().getCanonicalType().getNonReferenceType()));
8044 Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
8045 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT);
8046 }
8047 }
8048
8049 /// Set correct indices for lambdas captures.
8050 void adjustMemberOfForLambdaCaptures(
8051 const llvm::DenseMap<llvm::Value *, llvm::Value *> &LambdaPointers,
8052 MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
8053 MapFlagsArrayTy &Types) const {
8054 for (unsigned I = 0, E = Types.size(); I < E; ++I) {
8055 // Set correct member_of idx for all implicit lambda captures.
8056 if (Types[I] != (OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
8057 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT))
8058 continue;
8059 llvm::Value *BasePtr = LambdaPointers.lookup(*BasePointers[I]);
8060 assert(BasePtr && "Unable to find base lambda address.")((BasePtr && "Unable to find base lambda address.") ?
static_cast<void> (0) : __assert_fail ("BasePtr && \"Unable to find base lambda address.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8060, __PRETTY_FUNCTION__))
;
8061 int TgtIdx = -1;
8062 for (unsigned J = I; J > 0; --J) {
8063 unsigned Idx = J - 1;
8064 if (Pointers[Idx] != BasePtr)
8065 continue;
8066 TgtIdx = Idx;
8067 break;
8068 }
8069 assert(TgtIdx != -1 && "Unable to find parent lambda.")((TgtIdx != -1 && "Unable to find parent lambda.") ? static_cast
<void> (0) : __assert_fail ("TgtIdx != -1 && \"Unable to find parent lambda.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8069, __PRETTY_FUNCTION__))
;
8070 // All other current entries will be MEMBER_OF the combined entry
8071 // (except for PTR_AND_OBJ entries which do not have a placeholder value
8072 // 0xFFFF in the MEMBER_OF field).
8073 OpenMPOffloadMappingFlags MemberOfFlag = getMemberOfFlag(TgtIdx);
8074 setCorrectMemberOfFlag(Types[I], MemberOfFlag);
8075 }
8076 }
8077
8078 /// Generate the base pointers, section pointers, sizes and map types
8079 /// associated to a given capture.
8080 void generateInfoForCapture(const CapturedStmt::Capture *Cap,
8081 llvm::Value *Arg,
8082 MapBaseValuesArrayTy &BasePointers,
8083 MapValuesArrayTy &Pointers,
8084 MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
8085 StructRangeInfoTy &PartialStruct) const {
8086 assert(!Cap->capturesVariableArrayType() &&((!Cap->capturesVariableArrayType() && "Not expecting to generate map info for a variable array type!"
) ? static_cast<void> (0) : __assert_fail ("!Cap->capturesVariableArrayType() && \"Not expecting to generate map info for a variable array type!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8087, __PRETTY_FUNCTION__))
8087 "Not expecting to generate map info for a variable array type!")((!Cap->capturesVariableArrayType() && "Not expecting to generate map info for a variable array type!"
) ? static_cast<void> (0) : __assert_fail ("!Cap->capturesVariableArrayType() && \"Not expecting to generate map info for a variable array type!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8087, __PRETTY_FUNCTION__))
;
8088
8089 // We need to know when we generating information for the first component
8090 const ValueDecl *VD = Cap->capturesThis()
8091 ? nullptr
8092 : Cap->getCapturedVar()->getCanonicalDecl();
8093
8094 // If this declaration appears in a is_device_ptr clause we just have to
8095 // pass the pointer by value. If it is a reference to a declaration, we just
8096 // pass its value.
8097 if (DevPointersMap.count(VD)) {
8098 BasePointers.emplace_back(Arg, VD);
8099 Pointers.push_back(Arg);
8100 Sizes.push_back(CGF.getTypeSize(CGF.getContext().VoidPtrTy));
8101 Types.push_back(OMP_MAP_LITERAL | OMP_MAP_TARGET_PARAM);
8102 return;
8103 }
8104
8105 using MapData =
8106 std::tuple<OMPClauseMappableExprCommon::MappableExprComponentListRef,
8107 OpenMPMapClauseKind, ArrayRef<OpenMPMapModifierKind>, bool>;
8108 SmallVector<MapData, 4> DeclComponentLists;
8109 // FIXME: MSVC 2013 seems to require this-> to find member CurDir.
8110 for (const auto *C : this->CurDir.getClausesOfKind<OMPMapClause>()) {
8111 for (const auto &L : C->decl_component_lists(VD)) {
8112 assert(L.first == VD &&((L.first == VD && "We got information for the wrong declaration??"
) ? static_cast<void> (0) : __assert_fail ("L.first == VD && \"We got information for the wrong declaration??\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8113, __PRETTY_FUNCTION__))
8113 "We got information for the wrong declaration??")((L.first == VD && "We got information for the wrong declaration??"
) ? static_cast<void> (0) : __assert_fail ("L.first == VD && \"We got information for the wrong declaration??\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8113, __PRETTY_FUNCTION__))
;
8114 assert(!L.second.empty() &&((!L.second.empty() && "Not expecting declaration with no component lists."
) ? static_cast<void> (0) : __assert_fail ("!L.second.empty() && \"Not expecting declaration with no component lists.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8115, __PRETTY_FUNCTION__))
8115 "Not expecting declaration with no component lists.")((!L.second.empty() && "Not expecting declaration with no component lists."
) ? static_cast<void> (0) : __assert_fail ("!L.second.empty() && \"Not expecting declaration with no component lists.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8115, __PRETTY_FUNCTION__))
;
8116 DeclComponentLists.emplace_back(L.second, C->getMapType(),
8117 C->getMapTypeModifiers(),
8118 C->isImplicit());
8119 }
8120 }
8121
8122 // Find overlapping elements (including the offset from the base element).
8123 llvm::SmallDenseMap<
8124 const MapData *,
8125 llvm::SmallVector<
8126 OMPClauseMappableExprCommon::MappableExprComponentListRef, 4>,
8127 4>
8128 OverlappedData;
8129 size_t Count = 0;
8130 for (const MapData &L : DeclComponentLists) {
8131 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
8132 OpenMPMapClauseKind MapType;
8133 ArrayRef<OpenMPMapModifierKind> MapModifiers;
8134 bool IsImplicit;
8135 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
8136 ++Count;
8137 for (const MapData &L1 : makeArrayRef(DeclComponentLists).slice(Count)) {
8138 OMPClauseMappableExprCommon::MappableExprComponentListRef Components1;
8139 std::tie(Components1, MapType, MapModifiers, IsImplicit) = L1;
8140 auto CI = Components.rbegin();
8141 auto CE = Components.rend();
8142 auto SI = Components1.rbegin();
8143 auto SE = Components1.rend();
8144 for (; CI != CE && SI != SE; ++CI, ++SI) {
8145 if (CI->getAssociatedExpression()->getStmtClass() !=
8146 SI->getAssociatedExpression()->getStmtClass())
8147 break;
8148 // Are we dealing with different variables/fields?
8149 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
8150 break;
8151 }
8152 // Found overlapping if, at least for one component, reached the head of
8153 // the components list.
8154 if (CI == CE || SI == SE) {
8155 assert((CI != CE || SI != SE) &&(((CI != CE || SI != SE) && "Unexpected full match of the mapping components."
) ? static_cast<void> (0) : __assert_fail ("(CI != CE || SI != SE) && \"Unexpected full match of the mapping components.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8156, __PRETTY_FUNCTION__))
8156 "Unexpected full match of the mapping components.")(((CI != CE || SI != SE) && "Unexpected full match of the mapping components."
) ? static_cast<void> (0) : __assert_fail ("(CI != CE || SI != SE) && \"Unexpected full match of the mapping components.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8156, __PRETTY_FUNCTION__))
;
8157 const MapData &BaseData = CI == CE ? L : L1;
8158 OMPClauseMappableExprCommon::MappableExprComponentListRef SubData =
8159 SI == SE ? Components : Components1;
8160 auto &OverlappedElements = OverlappedData.FindAndConstruct(&BaseData);
8161 OverlappedElements.getSecond().push_back(SubData);
8162 }
8163 }
8164 }
8165 // Sort the overlapped elements for each item.
8166 llvm::SmallVector<const FieldDecl *, 4> Layout;
8167 if (!OverlappedData.empty()) {
8168 if (const auto *CRD =
8169 VD->getType().getCanonicalType()->getAsCXXRecordDecl())
8170 getPlainLayout(CRD, Layout, /*AsBase=*/false);
8171 else {
8172 const auto *RD = VD->getType().getCanonicalType()->getAsRecordDecl();
8173 Layout.append(RD->field_begin(), RD->field_end());
8174 }
8175 }
8176 for (auto &Pair : OverlappedData) {
8177 llvm::sort(
8178 Pair.getSecond(),
8179 [&Layout](
8180 OMPClauseMappableExprCommon::MappableExprComponentListRef First,
8181 OMPClauseMappableExprCommon::MappableExprComponentListRef
8182 Second) {
8183 auto CI = First.rbegin();
8184 auto CE = First.rend();
8185 auto SI = Second.rbegin();
8186 auto SE = Second.rend();
8187 for (; CI != CE && SI != SE; ++CI, ++SI) {
8188 if (CI->getAssociatedExpression()->getStmtClass() !=
8189 SI->getAssociatedExpression()->getStmtClass())
8190 break;
8191 // Are we dealing with different variables/fields?
8192 if (CI->getAssociatedDeclaration() !=
8193 SI->getAssociatedDeclaration())
8194 break;
8195 }
8196
8197 // Lists contain the same elements.
8198 if (CI == CE && SI == SE)
8199 return false;
8200
8201 // List with less elements is less than list with more elements.
8202 if (CI == CE || SI == SE)
8203 return CI == CE;
8204
8205 const auto *FD1 = cast<FieldDecl>(CI->getAssociatedDeclaration());
8206 const auto *FD2 = cast<FieldDecl>(SI->getAssociatedDeclaration());
8207 if (FD1->getParent() == FD2->getParent())
8208 return FD1->getFieldIndex() < FD2->getFieldIndex();
8209 const auto It =
8210 llvm::find_if(Layout, [FD1, FD2](const FieldDecl *FD) {
8211 return FD == FD1 || FD == FD2;
8212 });
8213 return *It == FD1;
8214 });
8215 }
8216
8217 // Associated with a capture, because the mapping flags depend on it.
8218 // Go through all of the elements with the overlapped elements.
8219 for (const auto &Pair : OverlappedData) {
8220 const MapData &L = *Pair.getFirst();
8221 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
8222 OpenMPMapClauseKind MapType;
8223 ArrayRef<OpenMPMapModifierKind> MapModifiers;
8224 bool IsImplicit;
8225 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
8226 ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
8227 OverlappedComponents = Pair.getSecond();
8228 bool IsFirstComponentList = true;
8229 generateInfoForComponentList(MapType, MapModifiers, Components,
8230 BasePointers, Pointers, Sizes, Types,
8231 PartialStruct, IsFirstComponentList,
8232 IsImplicit, OverlappedComponents);
8233 }
8234 // Go through other elements without overlapped elements.
8235 bool IsFirstComponentList = OverlappedData.empty();
8236 for (const MapData &L : DeclComponentLists) {
8237 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
8238 OpenMPMapClauseKind MapType;
8239 ArrayRef<OpenMPMapModifierKind> MapModifiers;
8240 bool IsImplicit;
8241 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
8242 auto It = OverlappedData.find(&L);
8243 if (It == OverlappedData.end())
8244 generateInfoForComponentList(MapType, MapModifiers, Components,
8245 BasePointers, Pointers, Sizes, Types,
8246 PartialStruct, IsFirstComponentList,
8247 IsImplicit);
8248 IsFirstComponentList = false;
8249 }
8250 }
8251
8252 /// Generate the base pointers, section pointers, sizes and map types
8253 /// associated with the declare target link variables.
8254 void generateInfoForDeclareTargetLink(MapBaseValuesArrayTy &BasePointers,
8255 MapValuesArrayTy &Pointers,
8256 MapValuesArrayTy &Sizes,
8257 MapFlagsArrayTy &Types) const {
8258 // Map other list items in the map clause which are not captured variables
8259 // but "declare target link" global variables.
8260 for (const auto *C : this->CurDir.getClausesOfKind<OMPMapClause>()) {
8261 for (const auto &L : C->component_lists()) {
8262 if (!L.first)
8263 continue;
8264 const auto *VD = dyn_cast<VarDecl>(L.first);
8265 if (!VD)
8266 continue;
8267 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
8268 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
8269 if (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)
8270 continue;
8271 StructRangeInfoTy PartialStruct;
8272 generateInfoForComponentList(
8273 C->getMapType(), C->getMapTypeModifiers(), L.second, BasePointers,
8274 Pointers, Sizes, Types, PartialStruct,
8275 /*IsFirstComponentList=*/true, C->isImplicit());
8276 assert(!PartialStruct.Base.isValid() &&((!PartialStruct.Base.isValid() && "No partial structs for declare target link expected."
) ? static_cast<void> (0) : __assert_fail ("!PartialStruct.Base.isValid() && \"No partial structs for declare target link expected.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8277, __PRETTY_FUNCTION__))
8277 "No partial structs for declare target link expected.")((!PartialStruct.Base.isValid() && "No partial structs for declare target link expected."
) ? static_cast<void> (0) : __assert_fail ("!PartialStruct.Base.isValid() && \"No partial structs for declare target link expected.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8277, __PRETTY_FUNCTION__))
;
8278 }
8279 }
8280 }
8281
8282 /// Generate the default map information for a given capture \a CI,
8283 /// record field declaration \a RI and captured value \a CV.
8284 void generateDefaultMapInfo(const CapturedStmt::Capture &CI,
8285 const FieldDecl &RI, llvm::Value *CV,
8286 MapBaseValuesArrayTy &CurBasePointers,
8287 MapValuesArrayTy &CurPointers,
8288 MapValuesArrayTy &CurSizes,
8289 MapFlagsArrayTy &CurMapTypes) const {
8290 // Do the default mapping.
8291 if (CI.capturesThis()) {
8292 CurBasePointers.push_back(CV);
8293 CurPointers.push_back(CV);
8294 const auto *PtrTy = cast<PointerType>(RI.getType().getTypePtr());
8295 CurSizes.push_back(CGF.getTypeSize(PtrTy->getPointeeType()));
8296 // Default map type.
8297 CurMapTypes.push_back(OMP_MAP_TO | OMP_MAP_FROM);
8298 } else if (CI.capturesVariableByCopy()) {
8299 CurBasePointers.push_back(CV);
8300 CurPointers.push_back(CV);
8301 if (!RI.getType()->isAnyPointerType()) {
8302 // We have to signal to the runtime captures passed by value that are
8303 // not pointers.
8304 CurMapTypes.push_back(OMP_MAP_LITERAL);
8305 CurSizes.push_back(CGF.getTypeSize(RI.getType()));
8306 } else {
8307 // Pointers are implicitly mapped with a zero size and no flags
8308 // (other than first map that is added for all implicit maps).
8309 CurMapTypes.push_back(OMP_MAP_NONE);
8310 CurSizes.push_back(llvm::Constant::getNullValue(CGF.SizeTy));
8311 }
8312 } else {
8313 assert(CI.capturesVariable() && "Expected captured reference.")((CI.capturesVariable() && "Expected captured reference."
) ? static_cast<void> (0) : __assert_fail ("CI.capturesVariable() && \"Expected captured reference.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8313, __PRETTY_FUNCTION__))
;
8314 const auto *PtrTy = cast<ReferenceType>(RI.getType().getTypePtr());
8315 QualType ElementType = PtrTy->getPointeeType();
8316 CurSizes.push_back(CGF.getTypeSize(ElementType));
8317 // The default map type for a scalar/complex type is 'to' because by
8318 // default the value doesn't have to be retrieved. For an aggregate
8319 // type, the default is 'tofrom'.
8320 CurMapTypes.push_back(getMapModifiersForPrivateClauses(CI));
8321 const VarDecl *VD = CI.getCapturedVar();
8322 if (FirstPrivateDecls.count(VD) &&
8323 VD->getType().isConstant(CGF.getContext())) {
8324 llvm::Constant *Addr =
8325 CGF.CGM.getOpenMPRuntime().registerTargetFirstprivateCopy(CGF, VD);
8326 // Copy the value of the original variable to the new global copy.
8327 CGF.Builder.CreateMemCpy(
8328 CGF.MakeNaturalAlignAddrLValue(Addr, ElementType).getAddress(),
8329 Address(CV, CGF.getContext().getTypeAlignInChars(ElementType)),
8330 CurSizes.back(), /*isVolatile=*/false);
8331 // Use new global variable as the base pointers.
8332 CurBasePointers.push_back(Addr);
8333 CurPointers.push_back(Addr);
8334 } else {
8335 CurBasePointers.push_back(CV);
8336 if (FirstPrivateDecls.count(VD) && ElementType->isAnyPointerType()) {
8337 Address PtrAddr = CGF.EmitLoadOfReference(CGF.MakeAddrLValue(
8338 CV, ElementType, CGF.getContext().getDeclAlign(VD),
8339 AlignmentSource::Decl));
8340 CurPointers.push_back(PtrAddr.getPointer());
8341 } else {
8342 CurPointers.push_back(CV);
8343 }
8344 }
8345 }
8346 // Every default map produces a single argument which is a target parameter.
8347 CurMapTypes.back() |= OMP_MAP_TARGET_PARAM;
8348
8349 // Add flag stating this is an implicit map.
8350 CurMapTypes.back() |= OMP_MAP_IMPLICIT;
8351 }
8352};
8353
8354enum OpenMPOffloadingReservedDeviceIDs {
8355 /// Device ID if the device was not defined, runtime should get it
8356 /// from environment variables in the spec.
8357 OMP_DEVICEID_UNDEF = -1,
8358};
8359} // anonymous namespace
8360
8361/// Emit the arrays used to pass the captures and map information to the
8362/// offloading runtime library. If there is no map or capture information,
8363/// return nullptr by reference.
8364static void
8365emitOffloadingArrays(CodeGenFunction &CGF,
8366 MappableExprsHandler::MapBaseValuesArrayTy &BasePointers,
8367 MappableExprsHandler::MapValuesArrayTy &Pointers,
8368 MappableExprsHandler::MapValuesArrayTy &Sizes,
8369 MappableExprsHandler::MapFlagsArrayTy &MapTypes,
8370 CGOpenMPRuntime::TargetDataInfo &Info) {
8371 CodeGenModule &CGM = CGF.CGM;
8372 ASTContext &Ctx = CGF.getContext();
8373
8374 // Reset the array information.
8375 Info.clearArrayInfo();
8376 Info.NumberOfPtrs = BasePointers.size();
8377
8378 if (Info.NumberOfPtrs) {
8379 // Detect if we have any capture size requiring runtime evaluation of the
8380 // size so that a constant array could be eventually used.
8381 bool hasRuntimeEvaluationCaptureSize = false;
8382 for (llvm::Value *S : Sizes)
8383 if (!isa<llvm::Constant>(S)) {
8384 hasRuntimeEvaluationCaptureSize = true;
8385 break;
8386 }
8387
8388 llvm::APInt PointerNumAP(32, Info.NumberOfPtrs, /*isSigned=*/true);
8389 QualType PointerArrayType =
8390 Ctx.getConstantArrayType(Ctx.VoidPtrTy, PointerNumAP, ArrayType::Normal,
8391 /*IndexTypeQuals=*/0);
8392
8393 Info.BasePointersArray =
8394 CGF.CreateMemTemp(PointerArrayType, ".offload_baseptrs").getPointer();
8395 Info.PointersArray =
8396 CGF.CreateMemTemp(PointerArrayType, ".offload_ptrs").getPointer();
8397
8398 // If we don't have any VLA types or other types that require runtime
8399 // evaluation, we can use a constant array for the map sizes, otherwise we
8400 // need to fill up the arrays as we do for the pointers.
8401 if (hasRuntimeEvaluationCaptureSize) {
8402 QualType SizeArrayType = Ctx.getConstantArrayType(
8403 Ctx.getSizeType(), PointerNumAP, ArrayType::Normal,
8404 /*IndexTypeQuals=*/0);
8405 Info.SizesArray =
8406 CGF.CreateMemTemp(SizeArrayType, ".offload_sizes").getPointer();
8407 } else {
8408 // We expect all the sizes to be constant, so we collect them to create
8409 // a constant array.
8410 SmallVector<llvm::Constant *, 16> ConstSizes;
8411 for (llvm::Value *S : Sizes)
8412 ConstSizes.push_back(cast<llvm::Constant>(S));
8413
8414 auto *SizesArrayInit = llvm::ConstantArray::get(
8415 llvm::ArrayType::get(CGM.SizeTy, ConstSizes.size()), ConstSizes);
8416 std::string Name = CGM.getOpenMPRuntime().getName({"offload_sizes"});
8417 auto *SizesArrayGbl = new llvm::GlobalVariable(
8418 CGM.getModule(), SizesArrayInit->getType(),
8419 /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage,
8420 SizesArrayInit, Name);
8421 SizesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
8422 Info.SizesArray = SizesArrayGbl;
8423 }
8424
8425 // The map types are always constant so we don't need to generate code to
8426 // fill arrays. Instead, we create an array constant.
8427 SmallVector<uint64_t, 4> Mapping(MapTypes.size(), 0);
8428 llvm::copy(MapTypes, Mapping.begin());
8429 llvm::Constant *MapTypesArrayInit =
8430 llvm::ConstantDataArray::get(CGF.Builder.getContext(), Mapping);
8431 std::string MaptypesName =
8432 CGM.getOpenMPRuntime().getName({"offload_maptypes"});
8433 auto *MapTypesArrayGbl = new llvm::GlobalVariable(
8434 CGM.getModule(), MapTypesArrayInit->getType(),
8435 /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage,
8436 MapTypesArrayInit, MaptypesName);
8437 MapTypesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
8438 Info.MapTypesArray = MapTypesArrayGbl;
8439
8440 for (unsigned I = 0; I < Info.NumberOfPtrs; ++I) {
8441 llvm::Value *BPVal = *BasePointers[I];
8442 llvm::Value *BP = CGF.Builder.CreateConstInBoundsGEP2_32(
8443 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
8444 Info.BasePointersArray, 0, I);
8445 BP = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
8446 BP, BPVal->getType()->getPointerTo(/*AddrSpace=*/0));
8447 Address BPAddr(BP, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
8448 CGF.Builder.CreateStore(BPVal, BPAddr);
8449
8450 if (Info.requiresDevicePointerInfo())
8451 if (const ValueDecl *DevVD = BasePointers[I].getDevicePtrDecl())
8452 Info.CaptureDeviceAddrMap.try_emplace(DevVD, BPAddr);
8453
8454 llvm::Value *PVal = Pointers[I];
8455 llvm::Value *P = CGF.Builder.CreateConstInBoundsGEP2_32(
8456 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
8457 Info.PointersArray, 0, I);
8458 P = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
8459 P, PVal->getType()->getPointerTo(/*AddrSpace=*/0));
8460 Address PAddr(P, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
8461 CGF.Builder.CreateStore(PVal, PAddr);
8462
8463 if (hasRuntimeEvaluationCaptureSize) {
8464 llvm::Value *S = CGF.Builder.CreateConstInBoundsGEP2_32(
8465 llvm::ArrayType::get(CGM.SizeTy, Info.NumberOfPtrs),
8466 Info.SizesArray,
8467 /*Idx0=*/0,
8468 /*Idx1=*/I);
8469 Address SAddr(S, Ctx.getTypeAlignInChars(Ctx.getSizeType()));
8470 CGF.Builder.CreateStore(
8471 CGF.Builder.CreateIntCast(Sizes[I], CGM.SizeTy, /*isSigned=*/true),
8472 SAddr);
8473 }
8474 }
8475 }
8476}
8477/// Emit the arguments to be passed to the runtime library based on the
8478/// arrays of pointers, sizes and map types.
8479static void emitOffloadingArraysArgument(
8480 CodeGenFunction &CGF, llvm::Value *&BasePointersArrayArg,
8481 llvm::Value *&PointersArrayArg, llvm::Value *&SizesArrayArg,
8482 llvm::Value *&MapTypesArrayArg, CGOpenMPRuntime::TargetDataInfo &Info) {
8483 CodeGenModule &CGM = CGF.CGM;
8484 if (Info.NumberOfPtrs) {
8485 BasePointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
8486 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
8487 Info.BasePointersArray,
8488 /*Idx0=*/0, /*Idx1=*/0);
8489 PointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
8490 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
8491 Info.PointersArray,
8492 /*Idx0=*/0,
8493 /*Idx1=*/0);
8494 SizesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
8495 llvm::ArrayType::get(CGM.SizeTy, Info.NumberOfPtrs), Info.SizesArray,
8496 /*Idx0=*/0, /*Idx1=*/0);
8497 MapTypesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
8498 llvm::ArrayType::get(CGM.Int64Ty, Info.NumberOfPtrs),
8499 Info.MapTypesArray,
8500 /*Idx0=*/0,
8501 /*Idx1=*/0);
8502 } else {
8503 BasePointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
8504 PointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
8505 SizesArrayArg = llvm::ConstantPointerNull::get(CGM.SizeTy->getPointerTo());
8506 MapTypesArrayArg =
8507 llvm::ConstantPointerNull::get(CGM.Int64Ty->getPointerTo());
8508 }
8509}
8510
8511/// Check for inner distribute directive.
8512static const OMPExecutableDirective *
8513getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
8514 const auto *CS = D.getInnermostCapturedStmt();
8515 const auto *Body =
8516 CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
8517 const Stmt *ChildStmt =
8518 CGOpenMPSIMDRuntime::getSingleCompoundChild(Ctx, Body);
8519
8520 if (const auto *NestedDir =
8521 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
8522 OpenMPDirectiveKind DKind = NestedDir->getDirectiveKind();
8523 switch (D.getDirectiveKind()) {
8524 case OMPD_target:
8525 if (isOpenMPDistributeDirective(DKind))
8526 return NestedDir;
8527 if (DKind == OMPD_teams) {
8528 Body = NestedDir->getInnermostCapturedStmt()->IgnoreContainers(
8529 /*IgnoreCaptured=*/true);
8530 if (!Body)
8531 return nullptr;
8532 ChildStmt = CGOpenMPSIMDRuntime::getSingleCompoundChild(Ctx, Body);
8533 if (const auto *NND =
8534 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
8535 DKind = NND->getDirectiveKind();
8536 if (isOpenMPDistributeDirective(DKind))
8537 return NND;
8538 }
8539 }
8540 return nullptr;
8541 case OMPD_target_teams:
8542 if (isOpenMPDistributeDirective(DKind))
8543 return NestedDir;
8544 return nullptr;
8545 case OMPD_target_parallel:
8546 case OMPD_target_simd:
8547 case OMPD_target_parallel_for:
8548 case OMPD_target_parallel_for_simd:
8549 return nullptr;
8550 case OMPD_target_teams_distribute:
8551 case OMPD_target_teams_distribute_simd:
8552 case OMPD_target_teams_distribute_parallel_for:
8553 case OMPD_target_teams_distribute_parallel_for_simd:
8554 case OMPD_parallel:
8555 case OMPD_for:
8556 case OMPD_parallel_for:
8557 case OMPD_parallel_sections:
8558 case OMPD_for_simd:
8559 case OMPD_parallel_for_simd:
8560 case OMPD_cancel:
8561 case OMPD_cancellation_point:
8562 case OMPD_ordered:
8563 case OMPD_threadprivate:
8564 case OMPD_allocate:
8565 case OMPD_task:
8566 case OMPD_simd:
8567 case OMPD_sections:
8568 case OMPD_section:
8569 case OMPD_single:
8570 case OMPD_master:
8571 case OMPD_critical:
8572 case OMPD_taskyield:
8573 case OMPD_barrier:
8574 case OMPD_taskwait:
8575 case OMPD_taskgroup:
8576 case OMPD_atomic:
8577 case OMPD_flush:
8578 case OMPD_teams:
8579 case OMPD_target_data:
8580 case OMPD_target_exit_data:
8581 case OMPD_target_enter_data:
8582 case OMPD_distribute:
8583 case OMPD_distribute_simd:
8584 case OMPD_distribute_parallel_for:
8585 case OMPD_distribute_parallel_for_simd:
8586 case OMPD_teams_distribute:
8587 case OMPD_teams_distribute_simd:
8588 case OMPD_teams_distribute_parallel_for:
8589 case OMPD_teams_distribute_parallel_for_simd:
8590 case OMPD_target_update:
8591 case OMPD_declare_simd:
8592 case OMPD_declare_target:
8593 case OMPD_end_declare_target:
8594 case OMPD_declare_reduction:
8595 case OMPD_declare_mapper:
8596 case OMPD_taskloop:
8597 case OMPD_taskloop_simd:
8598 case OMPD_requires:
8599 case OMPD_unknown:
8600 llvm_unreachable("Unexpected directive.")::llvm::llvm_unreachable_internal("Unexpected directive.", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8600)
;
8601 }
8602 }
8603
8604 return nullptr;
8605}
8606
8607void CGOpenMPRuntime::emitTargetNumIterationsCall(
8608 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *Device,
8609 const llvm::function_ref<llvm::Value *(
8610 CodeGenFunction &CGF, const OMPLoopDirective &D)> &SizeEmitter) {
8611 OpenMPDirectiveKind Kind = D.getDirectiveKind();
8612 const OMPExecutableDirective *TD = &D;
8613 // Get nested teams distribute kind directive, if any.
8614 if (!isOpenMPDistributeDirective(Kind) || !isOpenMPTeamsDirective(Kind))
8615 TD = getNestedDistributeDirective(CGM.getContext(), D);
8616 if (!TD)
8617 return;
8618 const auto *LD = cast<OMPLoopDirective>(TD);
8619 auto &&CodeGen = [LD, &Device, &SizeEmitter, this](CodeGenFunction &CGF,
8620 PrePostActionTy &) {
8621 llvm::Value *NumIterations = SizeEmitter(CGF, *LD);
8622
8623 // Emit device ID if any.
8624 llvm::Value *DeviceID;
8625 if (Device)
8626 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
8627 CGF.Int64Ty, /*isSigned=*/true);
8628 else
8629 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
8630
8631 llvm::Value *Args[] = {DeviceID, NumIterations};
8632 CGF.EmitRuntimeCall(
8633 createRuntimeFunction(OMPRTL__kmpc_push_target_tripcount), Args);
8634 };
8635 emitInlinedDirective(CGF, OMPD_unknown, CodeGen);
8636}
8637
8638void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF,
8639 const OMPExecutableDirective &D,
8640 llvm::Function *OutlinedFn,
8641 llvm::Value *OutlinedFnID,
8642 const Expr *IfCond, const Expr *Device) {
8643 if (!CGF.HaveInsertPoint())
8644 return;
8645
8646 assert(OutlinedFn && "Invalid outlined function!")((OutlinedFn && "Invalid outlined function!") ? static_cast
<void> (0) : __assert_fail ("OutlinedFn && \"Invalid outlined function!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8646, __PRETTY_FUNCTION__))
;
8647
8648 const bool RequiresOuterTask = D.hasClausesOfKind<OMPDependClause>();
8649 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
8650 const CapturedStmt &CS = *D.getCapturedStmt(OMPD_target);
8651 auto &&ArgsCodegen = [&CS, &CapturedVars](CodeGenFunction &CGF,
8652 PrePostActionTy &) {
8653 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
8654 };
8655 emitInlinedDirective(CGF, OMPD_unknown, ArgsCodegen);
8656
8657 CodeGenFunction::OMPTargetDataInfo InputInfo;
8658 llvm::Value *MapTypesArray = nullptr;
8659 // Fill up the pointer arrays and transfer execution to the device.
8660 auto &&ThenGen = [this, Device, OutlinedFn, OutlinedFnID, &D, &InputInfo,
8661 &MapTypesArray, &CS, RequiresOuterTask,
8662 &CapturedVars](CodeGenFunction &CGF, PrePostActionTy &) {
8663 // On top of the arrays that were filled up, the target offloading call
8664 // takes as arguments the device id as well as the host pointer. The host
8665 // pointer is used by the runtime library to identify the current target
8666 // region, so it only has to be unique and not necessarily point to
8667 // anything. It could be the pointer to the outlined function that
8668 // implements the target region, but we aren't using that so that the
8669 // compiler doesn't need to keep that, and could therefore inline the host
8670 // function if proven worthwhile during optimization.
8671
8672 // From this point on, we need to have an ID of the target region defined.
8673 assert(OutlinedFnID && "Invalid outlined function ID!")((OutlinedFnID && "Invalid outlined function ID!") ? static_cast
<void> (0) : __assert_fail ("OutlinedFnID && \"Invalid outlined function ID!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8673, __PRETTY_FUNCTION__))
;
8674
8675 // Emit device ID if any.
8676 llvm::Value *DeviceID;
8677 if (Device) {
8678 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
8679 CGF.Int64Ty, /*isSigned=*/true);
8680 } else {
8681 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
8682 }
8683
8684 // Emit the number of elements in the offloading arrays.
8685 llvm::Value *PointerNum =
8686 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
8687
8688 // Return value of the runtime offloading call.
8689 llvm::Value *Return;
8690
8691 llvm::Value *NumTeams = emitNumTeamsForTargetDirective(CGF, D);
8692 llvm::Value *NumThreads = emitNumThreadsForTargetDirective(CGF, D);
8693
8694 bool HasNowait = D.hasClausesOfKind<OMPNowaitClause>();
8695 // The target region is an outlined function launched by the runtime
8696 // via calls __tgt_target() or __tgt_target_teams().
8697 //
8698 // __tgt_target() launches a target region with one team and one thread,
8699 // executing a serial region. This master thread may in turn launch
8700 // more threads within its team upon encountering a parallel region,
8701 // however, no additional teams can be launched on the device.
8702 //
8703 // __tgt_target_teams() launches a target region with one or more teams,
8704 // each with one or more threads. This call is required for target
8705 // constructs such as:
8706 // 'target teams'
8707 // 'target' / 'teams'
8708 // 'target teams distribute parallel for'
8709 // 'target parallel'
8710 // and so on.
8711 //
8712 // Note that on the host and CPU targets, the runtime implementation of
8713 // these calls simply call the outlined function without forking threads.
8714 // The outlined functions themselves have runtime calls to
8715 // __kmpc_fork_teams() and __kmpc_fork() for this purpose, codegen'd by
8716 // the compiler in emitTeamsCall() and emitParallelCall().
8717 //
8718 // In contrast, on the NVPTX target, the implementation of
8719 // __tgt_target_teams() launches a GPU kernel with the requested number
8720 // of teams and threads so no additional calls to the runtime are required.
8721 if (NumTeams) {
8722 // If we have NumTeams defined this means that we have an enclosed teams
8723 // region. Therefore we also expect to have NumThreads defined. These two
8724 // values should be defined in the presence of a teams directive,
8725 // regardless of having any clauses associated. If the user is using teams
8726 // but no clauses, these two values will be the default that should be
8727 // passed to the runtime library - a 32-bit integer with the value zero.
8728 assert(NumThreads && "Thread limit expression should be available along "((NumThreads && "Thread limit expression should be available along "
"with number of teams.") ? static_cast<void> (0) : __assert_fail
("NumThreads && \"Thread limit expression should be available along \" \"with number of teams.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8729, __PRETTY_FUNCTION__))
8729 "with number of teams.")((NumThreads && "Thread limit expression should be available along "
"with number of teams.") ? static_cast<void> (0) : __assert_fail
("NumThreads && \"Thread limit expression should be available along \" \"with number of teams.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8729, __PRETTY_FUNCTION__))
;
8730 llvm::Value *OffloadingArgs[] = {DeviceID,
8731 OutlinedFnID,
8732 PointerNum,
8733 InputInfo.BasePointersArray.getPointer(),
8734 InputInfo.PointersArray.getPointer(),
8735 InputInfo.SizesArray.getPointer(),
8736 MapTypesArray,
8737 NumTeams,
8738 NumThreads};
8739 Return = CGF.EmitRuntimeCall(
8740 createRuntimeFunction(HasNowait ? OMPRTL__tgt_target_teams_nowait
8741 : OMPRTL__tgt_target_teams),
8742 OffloadingArgs);
8743 } else {
8744 llvm::Value *OffloadingArgs[] = {DeviceID,
8745 OutlinedFnID,
8746 PointerNum,
8747 InputInfo.BasePointersArray.getPointer(),
8748 InputInfo.PointersArray.getPointer(),
8749 InputInfo.SizesArray.getPointer(),
8750 MapTypesArray};
8751 Return = CGF.EmitRuntimeCall(
8752 createRuntimeFunction(HasNowait ? OMPRTL__tgt_target_nowait
8753 : OMPRTL__tgt_target),
8754 OffloadingArgs);
8755 }
8756
8757 // Check the error code and execute the host version if required.
8758 llvm::BasicBlock *OffloadFailedBlock =
8759 CGF.createBasicBlock("omp_offload.failed");
8760 llvm::BasicBlock *OffloadContBlock =
8761 CGF.createBasicBlock("omp_offload.cont");
8762 llvm::Value *Failed = CGF.Builder.CreateIsNotNull(Return);
8763 CGF.Builder.CreateCondBr(Failed, OffloadFailedBlock, OffloadContBlock);
8764
8765 CGF.EmitBlock(OffloadFailedBlock);
8766 if (RequiresOuterTask) {
8767 CapturedVars.clear();
8768 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
8769 }
8770 emitOutlinedFunctionCall(CGF, D.getBeginLoc(), OutlinedFn, CapturedVars);
8771 CGF.EmitBranch(OffloadContBlock);
8772
8773 CGF.EmitBlock(OffloadContBlock, /*IsFinished=*/true);
8774 };
8775
8776 // Notify that the host version must be executed.
8777 auto &&ElseGen = [this, &D, OutlinedFn, &CS, &CapturedVars,
8778 RequiresOuterTask](CodeGenFunction &CGF,
8779 PrePostActionTy &) {
8780 if (RequiresOuterTask) {
8781 CapturedVars.clear();
8782 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
8783 }
8784 emitOutlinedFunctionCall(CGF, D.getBeginLoc(), OutlinedFn, CapturedVars);
8785 };
8786
8787 auto &&TargetThenGen = [this, &ThenGen, &D, &InputInfo, &MapTypesArray,
8788 &CapturedVars, RequiresOuterTask,
8789 &CS](CodeGenFunction &CGF, PrePostActionTy &) {
8790 // Fill up the arrays with all the captured variables.
8791 MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
8792 MappableExprsHandler::MapValuesArrayTy Pointers;
8793 MappableExprsHandler::MapValuesArrayTy Sizes;
8794 MappableExprsHandler::MapFlagsArrayTy MapTypes;
8795
8796 // Get mappable expression information.
8797 MappableExprsHandler MEHandler(D, CGF);
8798 llvm::DenseMap<llvm::Value *, llvm::Value *> LambdaPointers;
8799
8800 auto RI = CS.getCapturedRecordDecl()->field_begin();
8801 auto CV = CapturedVars.begin();
8802 for (CapturedStmt::const_capture_iterator CI = CS.capture_begin(),
8803 CE = CS.capture_end();
8804 CI != CE; ++CI, ++RI, ++CV) {
8805 MappableExprsHandler::MapBaseValuesArrayTy CurBasePointers;
8806 MappableExprsHandler::MapValuesArrayTy CurPointers;
8807 MappableExprsHandler::MapValuesArrayTy CurSizes;
8808 MappableExprsHandler::MapFlagsArrayTy CurMapTypes;
8809 MappableExprsHandler::StructRangeInfoTy PartialStruct;
8810
8811 // VLA sizes are passed to the outlined region by copy and do not have map
8812 // information associated.
8813 if (CI->capturesVariableArrayType()) {
8814 CurBasePointers.push_back(*CV);
8815 CurPointers.push_back(*CV);
8816 CurSizes.push_back(CGF.getTypeSize(RI->getType()));
8817 // Copy to the device as an argument. No need to retrieve it.
8818 CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_LITERAL |
8819 MappableExprsHandler::OMP_MAP_TARGET_PARAM);
8820 } else {
8821 // If we have any information in the map clause, we use it, otherwise we
8822 // just do a default mapping.
8823 MEHandler.generateInfoForCapture(CI, *CV, CurBasePointers, CurPointers,
8824 CurSizes, CurMapTypes, PartialStruct);
8825 if (CurBasePointers.empty())
8826 MEHandler.generateDefaultMapInfo(*CI, **RI, *CV, CurBasePointers,
8827 CurPointers, CurSizes, CurMapTypes);
8828 // Generate correct mapping for variables captured by reference in
8829 // lambdas.
8830 if (CI->capturesVariable())
8831 MEHandler.generateInfoForLambdaCaptures(
8832 CI->getCapturedVar(), *CV, CurBasePointers, CurPointers, CurSizes,
8833 CurMapTypes, LambdaPointers);
8834 }
8835 // We expect to have at least an element of information for this capture.
8836 assert(!CurBasePointers.empty() &&((!CurBasePointers.empty() && "Non-existing map pointer for capture!"
) ? static_cast<void> (0) : __assert_fail ("!CurBasePointers.empty() && \"Non-existing map pointer for capture!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8837, __PRETTY_FUNCTION__))
8837 "Non-existing map pointer for capture!")((!CurBasePointers.empty() && "Non-existing map pointer for capture!"
) ? static_cast<void> (0) : __assert_fail ("!CurBasePointers.empty() && \"Non-existing map pointer for capture!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8837, __PRETTY_FUNCTION__))
;
8838 assert(CurBasePointers.size() == CurPointers.size() &&((CurBasePointers.size() == CurPointers.size() && CurBasePointers
.size() == CurSizes.size() && CurBasePointers.size() ==
CurMapTypes.size() && "Inconsistent map information sizes!"
) ? static_cast<void> (0) : __assert_fail ("CurBasePointers.size() == CurPointers.size() && CurBasePointers.size() == CurSizes.size() && CurBasePointers.size() == CurMapTypes.size() && \"Inconsistent map information sizes!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8841, __PRETTY_FUNCTION__))
8839 CurBasePointers.size() == CurSizes.size() &&((CurBasePointers.size() == CurPointers.size() && CurBasePointers
.size() == CurSizes.size() && CurBasePointers.size() ==
CurMapTypes.size() && "Inconsistent map information sizes!"
) ? static_cast<void> (0) : __assert_fail ("CurBasePointers.size() == CurPointers.size() && CurBasePointers.size() == CurSizes.size() && CurBasePointers.size() == CurMapTypes.size() && \"Inconsistent map information sizes!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8841, __PRETTY_FUNCTION__))
8840 CurBasePointers.size() == CurMapTypes.size() &&((CurBasePointers.size() == CurPointers.size() && CurBasePointers
.size() == CurSizes.size() && CurBasePointers.size() ==
CurMapTypes.size() && "Inconsistent map information sizes!"
) ? static_cast<void> (0) : __assert_fail ("CurBasePointers.size() == CurPointers.size() && CurBasePointers.size() == CurSizes.size() && CurBasePointers.size() == CurMapTypes.size() && \"Inconsistent map information sizes!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8841, __PRETTY_FUNCTION__))
8841 "Inconsistent map information sizes!")((CurBasePointers.size() == CurPointers.size() && CurBasePointers
.size() == CurSizes.size() && CurBasePointers.size() ==
CurMapTypes.size() && "Inconsistent map information sizes!"
) ? static_cast<void> (0) : __assert_fail ("CurBasePointers.size() == CurPointers.size() && CurBasePointers.size() == CurSizes.size() && CurBasePointers.size() == CurMapTypes.size() && \"Inconsistent map information sizes!\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 8841, __PRETTY_FUNCTION__))
;
8842
8843 // If there is an entry in PartialStruct it means we have a struct with
8844 // individual members mapped. Emit an extra combined entry.
8845 if (PartialStruct.Base.isValid())
8846 MEHandler.emitCombinedEntry(BasePointers, Pointers, Sizes, MapTypes,
8847 CurMapTypes, PartialStruct);
8848
8849 // We need to append the results of this capture to what we already have.
8850 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
8851 Pointers.append(CurPointers.begin(), CurPointers.end());
8852 Sizes.append(CurSizes.begin(), CurSizes.end());
8853 MapTypes.append(CurMapTypes.begin(), CurMapTypes.end());
8854 }
8855 // Adjust MEMBER_OF flags for the lambdas captures.
8856 MEHandler.adjustMemberOfForLambdaCaptures(LambdaPointers, BasePointers,
8857 Pointers, MapTypes);
8858 // Map other list items in the map clause which are not captured variables
8859 // but "declare target link" global variables.
8860 MEHandler.generateInfoForDeclareTargetLink(BasePointers, Pointers, Sizes,
8861 MapTypes);
8862
8863 TargetDataInfo Info;
8864 // Fill up the arrays and create the arguments.
8865 emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes, Info);
8866 emitOffloadingArraysArgument(CGF, Info.BasePointersArray,
8867 Info.PointersArray, Info.SizesArray,
8868 Info.MapTypesArray, Info);
8869 InputInfo.NumberOfTargetItems = Info.NumberOfPtrs;
8870 InputInfo.BasePointersArray =
8871 Address(Info.BasePointersArray, CGM.getPointerAlign());
8872 InputInfo.PointersArray =
8873 Address(Info.PointersArray, CGM.getPointerAlign());
8874 InputInfo.SizesArray = Address(Info.SizesArray, CGM.getPointerAlign());
8875 MapTypesArray = Info.MapTypesArray;
8876 if (RequiresOuterTask)
8877 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
8878 else
8879 emitInlinedDirective(CGF, D.getDirectiveKind(), ThenGen);
8880 };
8881
8882 auto &&TargetElseGen = [this, &ElseGen, &D, RequiresOuterTask](
8883 CodeGenFunction &CGF, PrePostActionTy &) {
8884 if (RequiresOuterTask) {
8885 CodeGenFunction::OMPTargetDataInfo InputInfo;
8886 CGF.EmitOMPTargetTaskBasedDirective(D, ElseGen, InputInfo);
8887 } else {
8888 emitInlinedDirective(CGF, D.getDirectiveKind(), ElseGen);
8889 }
8890 };
8891
8892 // If we have a target function ID it means that we need to support
8893 // offloading, otherwise, just execute on the host. We need to execute on host
8894 // regardless of the conditional in the if clause if, e.g., the user do not
8895 // specify target triples.
8896 if (OutlinedFnID) {
8897 if (IfCond) {
8898 emitOMPIfClause(CGF, IfCond, TargetThenGen, TargetElseGen);
8899 } else {
8900 RegionCodeGenTy ThenRCG(TargetThenGen);
8901 ThenRCG(CGF);
8902 }
8903 } else {
8904 RegionCodeGenTy ElseRCG(TargetElseGen);
8905 ElseRCG(CGF);
8906 }
8907}
8908
8909void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
8910 StringRef ParentName) {
8911 if (!S)
8912 return;
8913
8914 // Codegen OMP target directives that offload compute to the device.
8915 bool RequiresDeviceCodegen =
8916 isa<OMPExecutableDirective>(S) &&
8917 isOpenMPTargetExecutionDirective(
8918 cast<OMPExecutableDirective>(S)->getDirectiveKind());
8919
8920 if (RequiresDeviceCodegen) {
8921 const auto &E = *cast<OMPExecutableDirective>(S);
8922 unsigned DeviceID;
8923 unsigned FileID;
8924 unsigned Line;
8925 getTargetEntryUniqueInfo(CGM.getContext(), E.getBeginLoc(), DeviceID,
8926 FileID, Line);
8927
8928 // Is this a target region that should not be emitted as an entry point? If
8929 // so just signal we are done with this target region.
8930 if (!OffloadEntriesInfoManager.hasTargetRegionEntryInfo(DeviceID, FileID,
8931 ParentName, Line))
8932 return;
8933
8934 switch (E.getDirectiveKind()) {
8935 case OMPD_target:
8936 CodeGenFunction::EmitOMPTargetDeviceFunction(CGM, ParentName,
8937 cast<OMPTargetDirective>(E));
8938 break;
8939 case OMPD_target_parallel:
8940 CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
8941 CGM, ParentName, cast<OMPTargetParallelDirective>(E));
8942 break;
8943 case OMPD_target_teams:
8944 CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
8945 CGM, ParentName, cast<OMPTargetTeamsDirective>(E));
8946 break;
8947 case OMPD_target_teams_distribute:
8948 CodeGenFunction::EmitOMPTargetTeamsDistributeDeviceFunction(
8949 CGM, ParentName, cast<OMPTargetTeamsDistributeDirective>(E));
8950 break;
8951 case OMPD_target_teams_distribute_simd:
8952 CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDeviceFunction(
8953 CGM, ParentName, cast<OMPTargetTeamsDistributeSimdDirective>(E));
8954 break;
8955 case OMPD_target_parallel_for:
8956 CodeGenFunction::EmitOMPTargetParallelForDeviceFunction(
8957 CGM, ParentName, cast<OMPTargetParallelForDirective>(E));
8958 break;
8959 case OMPD_target_parallel_for_simd:
8960 CodeGenFunction::EmitOMPTargetParallelForSimdDeviceFunction(
8961 CGM, ParentName, cast<OMPTargetParallelForSimdDirective>(E));
8962 break;
8963 case OMPD_target_simd:
8964 CodeGenFunction::EmitOMPTargetSimdDeviceFunction(
8965 CGM, ParentName, cast<OMPTargetSimdDirective>(E));
8966 break;
8967 case OMPD_target_teams_distribute_parallel_for:
8968 CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
8969 CGM, ParentName,
8970 cast<OMPTargetTeamsDistributeParallelForDirective>(E));
8971 break;
8972 case OMPD_target_teams_distribute_parallel_for_simd:
8973 CodeGenFunction::
8974 EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
8975 CGM, ParentName,
8976 cast<OMPTargetTeamsDistributeParallelForSimdDirective>(E));
8977 break;
8978 case OMPD_parallel:
8979 case OMPD_for:
8980 case OMPD_parallel_for:
8981 case OMPD_parallel_sections:
8982 case OMPD_for_simd:
8983 case OMPD_parallel_for_simd:
8984 case OMPD_cancel:
8985 case OMPD_cancellation_point:
8986 case OMPD_ordered:
8987 case OMPD_threadprivate:
8988 case OMPD_allocate:
8989 case OMPD_task:
8990 case OMPD_simd:
8991 case OMPD_sections:
8992 case OMPD_section:
8993 case OMPD_single:
8994 case OMPD_master:
8995 case OMPD_critical:
8996 case OMPD_taskyield:
8997 case OMPD_barrier:
8998 case OMPD_taskwait:
8999 case OMPD_taskgroup:
9000 case OMPD_atomic:
9001 case OMPD_flush:
9002 case OMPD_teams:
9003 case OMPD_target_data:
9004 case OMPD_target_exit_data:
9005 case OMPD_target_enter_data:
9006 case OMPD_distribute:
9007 case OMPD_distribute_simd:
9008 case OMPD_distribute_parallel_for:
9009 case OMPD_distribute_parallel_for_simd:
9010 case OMPD_teams_distribute:
9011 case OMPD_teams_distribute_simd:
9012 case OMPD_teams_distribute_parallel_for:
9013 case OMPD_teams_distribute_parallel_for_simd:
9014 case OMPD_target_update:
9015 case OMPD_declare_simd:
9016 case OMPD_declare_target:
9017 case OMPD_end_declare_target:
9018 case OMPD_declare_reduction:
9019 case OMPD_declare_mapper:
9020 case OMPD_taskloop:
9021 case OMPD_taskloop_simd:
9022 case OMPD_requires:
9023 case OMPD_unknown:
9024 llvm_unreachable("Unknown target directive for OpenMP device codegen.")::llvm::llvm_unreachable_internal("Unknown target directive for OpenMP device codegen."
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9024)
;
9025 }
9026 return;
9027 }
9028
9029 if (const auto *E = dyn_cast<OMPExecutableDirective>(S)) {
9030 if (!E->hasAssociatedStmt() || !E->getAssociatedStmt())
9031 return;
9032
9033 scanForTargetRegionsFunctions(
9034 E->getInnermostCapturedStmt()->getCapturedStmt(), ParentName);
9035 return;
9036 }
9037
9038 // If this is a lambda function, look into its body.
9039 if (const auto *L = dyn_cast<LambdaExpr>(S))
9040 S = L->getBody();
9041
9042 // Keep looking for target regions recursively.
9043 for (const Stmt *II : S->children())
9044 scanForTargetRegionsFunctions(II, ParentName);
9045}
9046
9047bool CGOpenMPRuntime::emitTargetFunctions(GlobalDecl GD) {
9048 // If emitting code for the host, we do not process FD here. Instead we do
9049 // the normal code generation.
9050 if (!CGM.getLangOpts().OpenMPIsDevice)
9051 return false;
9052
9053 const ValueDecl *VD = cast<ValueDecl>(GD.getDecl());
9054 StringRef Name = CGM.getMangledName(GD);
9055 // Try to detect target regions in the function.
9056 if (const auto *FD = dyn_cast<FunctionDecl>(VD))
9057 scanForTargetRegionsFunctions(FD->getBody(), Name);
9058
9059 // Do not to emit function if it is not marked as declare target.
9060 return !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) &&
9061 AlreadyEmittedTargetFunctions.count(Name) == 0;
9062}
9063
9064bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
9065 if (!CGM.getLangOpts().OpenMPIsDevice)
9066 return false;
9067
9068 // Check if there are Ctors/Dtors in this declaration and look for target
9069 // regions in it. We use the complete variant to produce the kernel name
9070 // mangling.
9071 QualType RDTy = cast<VarDecl>(GD.getDecl())->getType();
9072 if (const auto *RD = RDTy->getBaseElementTypeUnsafe()->getAsCXXRecordDecl()) {
9073 for (const CXXConstructorDecl *Ctor : RD->ctors()) {
9074 StringRef ParentName =
9075 CGM.getMangledName(GlobalDecl(Ctor, Ctor_Complete));
9076 scanForTargetRegionsFunctions(Ctor->getBody(), ParentName);
9077 }
9078 if (const CXXDestructorDecl *Dtor = RD->getDestructor()) {
9079 StringRef ParentName =
9080 CGM.getMangledName(GlobalDecl(Dtor, Dtor_Complete));
9081 scanForTargetRegionsFunctions(Dtor->getBody(), ParentName);
9082 }
9083 }
9084
9085 // Do not to emit variable if it is not marked as declare target.
9086 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
9087 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
9088 cast<VarDecl>(GD.getDecl()));
9089 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link) {
9090 DeferredGlobalVariables.insert(cast<VarDecl>(GD.getDecl()));
9091 return true;
9092 }
9093 return false;
9094}
9095
9096llvm::Constant *
9097CGOpenMPRuntime::registerTargetFirstprivateCopy(CodeGenFunction &CGF,
9098 const VarDecl *VD) {
9099 assert(VD->getType().isConstant(CGM.getContext()) &&((VD->getType().isConstant(CGM.getContext()) && "Expected constant variable."
) ? static_cast<void> (0) : __assert_fail ("VD->getType().isConstant(CGM.getContext()) && \"Expected constant variable.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9100, __PRETTY_FUNCTION__))
9100 "Expected constant variable.")((VD->getType().isConstant(CGM.getContext()) && "Expected constant variable."
) ? static_cast<void> (0) : __assert_fail ("VD->getType().isConstant(CGM.getContext()) && \"Expected constant variable.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9100, __PRETTY_FUNCTION__))
;
9101 StringRef VarName;
9102 llvm::Constant *Addr;
9103 llvm::GlobalValue::LinkageTypes Linkage;
9104 QualType Ty = VD->getType();
9105 SmallString<128> Buffer;
9106 {
9107 unsigned DeviceID;
9108 unsigned FileID;
9109 unsigned Line;
9110 getTargetEntryUniqueInfo(CGM.getContext(), VD->getLocation(), DeviceID,
9111 FileID, Line);
9112 llvm::raw_svector_ostream OS(Buffer);
9113 OS << "__omp_offloading_firstprivate_" << llvm::format("_%x", DeviceID)
9114 << llvm::format("_%x_", FileID) << VD->getName() << "_l" << Line;
9115 VarName = OS.str();
9116 }
9117 Linkage = llvm::GlobalValue::InternalLinkage;
9118 Addr =
9119 getOrCreateInternalVariable(CGM.getTypes().ConvertTypeForMem(Ty), VarName,
9120 getDefaultFirstprivateAddressSpace());
9121 cast<llvm::GlobalValue>(Addr)->setLinkage(Linkage);
9122 CharUnits VarSize = CGM.getContext().getTypeSizeInChars(Ty);
9123 CGM.addCompilerUsedGlobal(cast<llvm::GlobalValue>(Addr));
9124 OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo(
9125 VarName, Addr, VarSize,
9126 OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo, Linkage);
9127 return Addr;
9128}
9129
9130void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD,
9131 llvm::Constant *Addr) {
9132 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
9133 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
9134 if (!Res) {
9135 if (CGM.getLangOpts().OpenMPIsDevice) {
9136 // Register non-target variables being emitted in device code (debug info
9137 // may cause this).
9138 StringRef VarName = CGM.getMangledName(VD);
9139 EmittedNonTargetVariables.try_emplace(VarName, Addr);
9140 }
9141 return;
9142 }
9143 // Register declare target variables.
9144 OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags;
9145 StringRef VarName;
9146 CharUnits VarSize;
9147 llvm::GlobalValue::LinkageTypes Linkage;
9148 switch (*Res) {
9149 case OMPDeclareTargetDeclAttr::MT_To:
9150 Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo;
9151 VarName = CGM.getMangledName(VD);
9152 if (VD->hasDefinition(CGM.getContext()) != VarDecl::DeclarationOnly) {
9153 VarSize = CGM.getContext().getTypeSizeInChars(VD->getType());
9154 assert(!VarSize.isZero() && "Expected non-zero size of the variable")((!VarSize.isZero() && "Expected non-zero size of the variable"
) ? static_cast<void> (0) : __assert_fail ("!VarSize.isZero() && \"Expected non-zero size of the variable\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9154, __PRETTY_FUNCTION__))
;
9155 } else {
9156 VarSize = CharUnits::Zero();
9157 }
9158 Linkage = CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false);
9159 // Temp solution to prevent optimizations of the internal variables.
9160 if (CGM.getLangOpts().OpenMPIsDevice && !VD->isExternallyVisible()) {
9161 std::string RefName = getName({VarName, "ref"});
9162 if (!CGM.GetGlobalValue(RefName)) {
9163 llvm::Constant *AddrRef =
9164 getOrCreateInternalVariable(Addr->getType(), RefName);
9165 auto *GVAddrRef = cast<llvm::GlobalVariable>(AddrRef);
9166 GVAddrRef->setConstant(/*Val=*/true);
9167 GVAddrRef->setLinkage(llvm::GlobalValue::InternalLinkage);
9168 GVAddrRef->setInitializer(Addr);
9169 CGM.addCompilerUsedGlobal(GVAddrRef);
9170 }
9171 }
9172 break;
9173 case OMPDeclareTargetDeclAttr::MT_Link:
9174 Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryLink;
9175 if (CGM.getLangOpts().OpenMPIsDevice) {
9176 VarName = Addr->getName();
9177 Addr = nullptr;
9178 } else {
9179 VarName = getAddrOfDeclareTargetLink(VD).getName();
9180 Addr = cast<llvm::Constant>(getAddrOfDeclareTargetLink(VD).getPointer());
9181 }
9182 VarSize = CGM.getPointerSize();
9183 Linkage = llvm::GlobalValue::WeakAnyLinkage;
9184 break;
9185 }
9186 OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo(
9187 VarName, Addr, VarSize, Flags, Linkage);
9188}
9189
9190bool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) {
9191 if (isa<FunctionDecl>(GD.getDecl()) ||
9192 isa<OMPDeclareReductionDecl>(GD.getDecl()))
9193 return emitTargetFunctions(GD);
9194
9195 return emitTargetGlobalVariable(GD);
9196}
9197
9198void CGOpenMPRuntime::emitDeferredTargetDecls() const {
9199 for (const VarDecl *VD : DeferredGlobalVariables) {
9200 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
9201 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
9202 if (!Res)
9203 continue;
9204 if (*Res == OMPDeclareTargetDeclAttr::MT_To) {
9205 CGM.EmitGlobal(VD);
9206 } else {
9207 assert(*Res == OMPDeclareTargetDeclAttr::MT_Link &&((*Res == OMPDeclareTargetDeclAttr::MT_Link && "Expected to or link clauses."
) ? static_cast<void> (0) : __assert_fail ("*Res == OMPDeclareTargetDeclAttr::MT_Link && \"Expected to or link clauses.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9208, __PRETTY_FUNCTION__))
9208 "Expected to or link clauses.")((*Res == OMPDeclareTargetDeclAttr::MT_Link && "Expected to or link clauses."
) ? static_cast<void> (0) : __assert_fail ("*Res == OMPDeclareTargetDeclAttr::MT_Link && \"Expected to or link clauses.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9208, __PRETTY_FUNCTION__))
;
9209 (void)CGM.getOpenMPRuntime().getAddrOfDeclareTargetLink(VD);
9210 }
9211 }
9212}
9213
9214void CGOpenMPRuntime::adjustTargetSpecificDataForLambdas(
9215 CodeGenFunction &CGF, const OMPExecutableDirective &D) const {
9216 assert(isOpenMPTargetExecutionDirective(D.getDirectiveKind()) &&((isOpenMPTargetExecutionDirective(D.getDirectiveKind()) &&
" Expected target-based directive.") ? static_cast<void>
(0) : __assert_fail ("isOpenMPTargetExecutionDirective(D.getDirectiveKind()) && \" Expected target-based directive.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9217, __PRETTY_FUNCTION__))
9217 " Expected target-based directive.")((isOpenMPTargetExecutionDirective(D.getDirectiveKind()) &&
" Expected target-based directive.") ? static_cast<void>
(0) : __assert_fail ("isOpenMPTargetExecutionDirective(D.getDirectiveKind()) && \" Expected target-based directive.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9217, __PRETTY_FUNCTION__))
;
9218}
9219
9220void CGOpenMPRuntime::checkArchForUnifiedAddressing(
9221 const OMPRequiresDecl *D) {
9222 for (const OMPClause *Clause : D->clauselists()) {
9223 if (Clause->getClauseKind() == OMPC_unified_shared_memory) {
9224 HasRequiresUnifiedSharedMemory = true;
9225 break;
9226 }
9227 }
9228}
9229
9230bool CGOpenMPRuntime::hasAllocateAttributeForGlobalVar(const VarDecl *VD,
9231 LangAS &AS) {
9232 if (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())
9233 return false;
9234 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
9235 switch(A->getAllocatorType()) {
9236 case OMPAllocateDeclAttr::OMPDefaultMemAlloc:
9237 // Not supported, fallback to the default mem space.
9238 case OMPAllocateDeclAttr::OMPLargeCapMemAlloc:
9239 case OMPAllocateDeclAttr::OMPCGroupMemAlloc:
9240 case OMPAllocateDeclAttr::OMPHighBWMemAlloc:
9241 case OMPAllocateDeclAttr::OMPLowLatMemAlloc:
9242 case OMPAllocateDeclAttr::OMPThreadMemAlloc:
9243 case OMPAllocateDeclAttr::OMPConstMemAlloc:
9244 case OMPAllocateDeclAttr::OMPPTeamMemAlloc:
9245 AS = LangAS::Default;
9246 return true;
9247 case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc:
9248 llvm_unreachable("Expected predefined allocator for the variables with the "::llvm::llvm_unreachable_internal("Expected predefined allocator for the variables with the "
"static storage.", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9249)
9249 "static storage.")::llvm::llvm_unreachable_internal("Expected predefined allocator for the variables with the "
"static storage.", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9249)
;
9250 }
9251 return false;
9252}
9253
9254CGOpenMPRuntime::DisableAutoDeclareTargetRAII::DisableAutoDeclareTargetRAII(
9255 CodeGenModule &CGM)
9256 : CGM(CGM) {
9257 if (CGM.getLangOpts().OpenMPIsDevice) {
9258 SavedShouldMarkAsGlobal = CGM.getOpenMPRuntime().ShouldMarkAsGlobal;
9259 CGM.getOpenMPRuntime().ShouldMarkAsGlobal = false;
9260 }
9261}
9262
9263CGOpenMPRuntime::DisableAutoDeclareTargetRAII::~DisableAutoDeclareTargetRAII() {
9264 if (CGM.getLangOpts().OpenMPIsDevice)
9265 CGM.getOpenMPRuntime().ShouldMarkAsGlobal = SavedShouldMarkAsGlobal;
9266}
9267
9268bool CGOpenMPRuntime::markAsGlobalTarget(GlobalDecl GD) {
9269 if (!CGM.getLangOpts().OpenMPIsDevice || !ShouldMarkAsGlobal)
9270 return true;
9271
9272 StringRef Name = CGM.getMangledName(GD);
9273 const auto *D = cast<FunctionDecl>(GD.getDecl());
9274 // Do not to emit function if it is marked as declare target as it was already
9275 // emitted.
9276 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(D)) {
9277 if (D->hasBody() && AlreadyEmittedTargetFunctions.count(Name) == 0) {
9278 if (auto *F = dyn_cast_or_null<llvm::Function>(CGM.GetGlobalValue(Name)))
9279 return !F->isDeclaration();
9280 return false;
9281 }
9282 return true;
9283 }
9284
9285 return !AlreadyEmittedTargetFunctions.insert(Name).second;
9286}
9287
9288llvm::Function *CGOpenMPRuntime::emitRequiresDirectiveRegFun() {
9289 // If we don't have entries or if we are emitting code for the device, we
9290 // don't need to do anything.
9291 if (CGM.getLangOpts().OMPTargetTriples.empty() ||
9292 CGM.getLangOpts().OpenMPSimd || CGM.getLangOpts().OpenMPIsDevice ||
9293 (OffloadEntriesInfoManager.empty() &&
9294 !HasEmittedDeclareTargetRegion &&
9295 !HasEmittedTargetRegion))
9296 return nullptr;
9297
9298 // Create and register the function that handles the requires directives.
9299 ASTContext &C = CGM.getContext();
9300
9301 llvm::Function *RequiresRegFn;
9302 {
9303 CodeGenFunction CGF(CGM);
9304 const auto &FI = CGM.getTypes().arrangeNullaryFunction();
9305 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
9306 std::string ReqName = getName({"omp_offloading", "requires_reg"});
9307 RequiresRegFn = CGM.CreateGlobalInitOrDestructFunction(FTy, ReqName, FI);
9308 CGF.StartFunction(GlobalDecl(), C.VoidTy, RequiresRegFn, FI, {});
9309 OpenMPOffloadingRequiresDirFlags Flags = OMP_REQ_NONE;
9310 // TODO: check for other requires clauses.
9311 // The requires directive takes effect only when a target region is
9312 // present in the compilation unit. Otherwise it is ignored and not
9313 // passed to the runtime. This avoids the runtime from throwing an error
9314 // for mismatching requires clauses across compilation units that don't
9315 // contain at least 1 target region.
9316 assert((HasEmittedTargetRegion ||(((HasEmittedTargetRegion || HasEmittedDeclareTargetRegion ||
!OffloadEntriesInfoManager.empty()) && "Target or declare target region expected."
) ? static_cast<void> (0) : __assert_fail ("(HasEmittedTargetRegion || HasEmittedDeclareTargetRegion || !OffloadEntriesInfoManager.empty()) && \"Target or declare target region expected.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9319, __PRETTY_FUNCTION__))
9317 HasEmittedDeclareTargetRegion ||(((HasEmittedTargetRegion || HasEmittedDeclareTargetRegion ||
!OffloadEntriesInfoManager.empty()) && "Target or declare target region expected."
) ? static_cast<void> (0) : __assert_fail ("(HasEmittedTargetRegion || HasEmittedDeclareTargetRegion || !OffloadEntriesInfoManager.empty()) && \"Target or declare target region expected.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9319, __PRETTY_FUNCTION__))
9318 !OffloadEntriesInfoManager.empty()) &&(((HasEmittedTargetRegion || HasEmittedDeclareTargetRegion ||
!OffloadEntriesInfoManager.empty()) && "Target or declare target region expected."
) ? static_cast<void> (0) : __assert_fail ("(HasEmittedTargetRegion || HasEmittedDeclareTargetRegion || !OffloadEntriesInfoManager.empty()) && \"Target or declare target region expected.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9319, __PRETTY_FUNCTION__))
9319 "Target or declare target region expected.")(((HasEmittedTargetRegion || HasEmittedDeclareTargetRegion ||
!OffloadEntriesInfoManager.empty()) && "Target or declare target region expected."
) ? static_cast<void> (0) : __assert_fail ("(HasEmittedTargetRegion || HasEmittedDeclareTargetRegion || !OffloadEntriesInfoManager.empty()) && \"Target or declare target region expected.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9319, __PRETTY_FUNCTION__))
;
9320 if (HasRequiresUnifiedSharedMemory)
9321 Flags = OMP_REQ_UNIFIED_SHARED_MEMORY;
9322 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_register_requires),
9323 llvm::ConstantInt::get(CGM.Int64Ty, Flags));
9324 CGF.FinishFunction();
9325 }
9326 return RequiresRegFn;
9327}
9328
9329llvm::Function *CGOpenMPRuntime::emitRegistrationFunction() {
9330 // If we have offloading in the current module, we need to emit the entries
9331 // now and register the offloading descriptor.
9332 createOffloadEntriesAndInfoMetadata();
9333
9334 // Create and register the offloading binary descriptors. This is the main
9335 // entity that captures all the information about offloading in the current
9336 // compilation unit.
9337 return createOffloadingBinaryDescriptorRegistration();
1
Calling 'CGOpenMPRuntime::createOffloadingBinaryDescriptorRegistration'
9338}
9339
9340void CGOpenMPRuntime::emitTeamsCall(CodeGenFunction &CGF,
9341 const OMPExecutableDirective &D,
9342 SourceLocation Loc,
9343 llvm::Function *OutlinedFn,
9344 ArrayRef<llvm::Value *> CapturedVars) {
9345 if (!CGF.HaveInsertPoint())
9346 return;
9347
9348 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
9349 CodeGenFunction::RunCleanupsScope Scope(CGF);
9350
9351 // Build call __kmpc_fork_teams(loc, n, microtask, var1, .., varn);
9352 llvm::Value *Args[] = {
9353 RTLoc,
9354 CGF.Builder.getInt32(CapturedVars.size()), // Number of captured vars
9355 CGF.Builder.CreateBitCast(OutlinedFn, getKmpc_MicroPointerTy())};
9356 llvm::SmallVector<llvm::Value *, 16> RealArgs;
9357 RealArgs.append(std::begin(Args), std::end(Args));
9358 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
9359
9360 llvm::FunctionCallee RTLFn = createRuntimeFunction(OMPRTL__kmpc_fork_teams);
9361 CGF.EmitRuntimeCall(RTLFn, RealArgs);
9362}
9363
9364void CGOpenMPRuntime::emitNumTeamsClause(CodeGenFunction &CGF,
9365 const Expr *NumTeams,
9366 const Expr *ThreadLimit,
9367 SourceLocation Loc) {
9368 if (!CGF.HaveInsertPoint())
9369 return;
9370
9371 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
9372
9373 llvm::Value *NumTeamsVal =
9374 NumTeams
9375 ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(NumTeams),
9376 CGF.CGM.Int32Ty, /* isSigned = */ true)
9377 : CGF.Builder.getInt32(0);
9378
9379 llvm::Value *ThreadLimitVal =
9380 ThreadLimit
9381 ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(ThreadLimit),
9382 CGF.CGM.Int32Ty, /* isSigned = */ true)
9383 : CGF.Builder.getInt32(0);
9384
9385 // Build call __kmpc_push_num_teamss(&loc, global_tid, num_teams, thread_limit)
9386 llvm::Value *PushNumTeamsArgs[] = {RTLoc, getThreadID(CGF, Loc), NumTeamsVal,
9387 ThreadLimitVal};
9388 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_num_teams),
9389 PushNumTeamsArgs);
9390}
9391
9392void CGOpenMPRuntime::emitTargetDataCalls(
9393 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
9394 const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) {
9395 if (!CGF.HaveInsertPoint())
9396 return;
9397
9398 // Action used to replace the default codegen action and turn privatization
9399 // off.
9400 PrePostActionTy NoPrivAction;
9401
9402 // Generate the code for the opening of the data environment. Capture all the
9403 // arguments of the runtime call by reference because they are used in the
9404 // closing of the region.
9405 auto &&BeginThenGen = [this, &D, Device, &Info,
9406 &CodeGen](CodeGenFunction &CGF, PrePostActionTy &) {
9407 // Fill up the arrays with all the mapped variables.
9408 MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
9409 MappableExprsHandler::MapValuesArrayTy Pointers;
9410 MappableExprsHandler::MapValuesArrayTy Sizes;
9411 MappableExprsHandler::MapFlagsArrayTy MapTypes;
9412
9413 // Get map clause information.
9414 MappableExprsHandler MCHandler(D, CGF);
9415 MCHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
9416
9417 // Fill up the arrays and create the arguments.
9418 emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes, Info);
9419
9420 llvm::Value *BasePointersArrayArg = nullptr;
9421 llvm::Value *PointersArrayArg = nullptr;
9422 llvm::Value *SizesArrayArg = nullptr;
9423 llvm::Value *MapTypesArrayArg = nullptr;
9424 emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg,
9425 SizesArrayArg, MapTypesArrayArg, Info);
9426
9427 // Emit device ID if any.
9428 llvm::Value *DeviceID = nullptr;
9429 if (Device) {
9430 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
9431 CGF.Int64Ty, /*isSigned=*/true);
9432 } else {
9433 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
9434 }
9435
9436 // Emit the number of elements in the offloading arrays.
9437 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
9438
9439 llvm::Value *OffloadingArgs[] = {
9440 DeviceID, PointerNum, BasePointersArrayArg,
9441 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
9442 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_target_data_begin),
9443 OffloadingArgs);
9444
9445 // If device pointer privatization is required, emit the body of the region
9446 // here. It will have to be duplicated: with and without privatization.
9447 if (!Info.CaptureDeviceAddrMap.empty())
9448 CodeGen(CGF);
9449 };
9450
9451 // Generate code for the closing of the data region.
9452 auto &&EndThenGen = [this, Device, &Info](CodeGenFunction &CGF,
9453 PrePostActionTy &) {
9454 assert(Info.isValid() && "Invalid data environment closing arguments.")((Info.isValid() && "Invalid data environment closing arguments."
) ? static_cast<void> (0) : __assert_fail ("Info.isValid() && \"Invalid data environment closing arguments.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9454, __PRETTY_FUNCTION__))
;
9455
9456 llvm::Value *BasePointersArrayArg = nullptr;
9457 llvm::Value *PointersArrayArg = nullptr;
9458 llvm::Value *SizesArrayArg = nullptr;
9459 llvm::Value *MapTypesArrayArg = nullptr;
9460 emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg,
9461 SizesArrayArg, MapTypesArrayArg, Info);
9462
9463 // Emit device ID if any.
9464 llvm::Value *DeviceID = nullptr;
9465 if (Device) {
9466 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
9467 CGF.Int64Ty, /*isSigned=*/true);
9468 } else {
9469 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
9470 }
9471
9472 // Emit the number of elements in the offloading arrays.
9473 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
9474
9475 llvm::Value *OffloadingArgs[] = {
9476 DeviceID, PointerNum, BasePointersArrayArg,
9477 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
9478 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_target_data_end),
9479 OffloadingArgs);
9480 };
9481
9482 // If we need device pointer privatization, we need to emit the body of the
9483 // region with no privatization in the 'else' branch of the conditional.
9484 // Otherwise, we don't have to do anything.
9485 auto &&BeginElseGen = [&Info, &CodeGen, &NoPrivAction](CodeGenFunction &CGF,
9486 PrePostActionTy &) {
9487 if (!Info.CaptureDeviceAddrMap.empty()) {
9488 CodeGen.setAction(NoPrivAction);
9489 CodeGen(CGF);
9490 }
9491 };
9492
9493 // We don't have to do anything to close the region if the if clause evaluates
9494 // to false.
9495 auto &&EndElseGen = [](CodeGenFunction &CGF, PrePostActionTy &) {};
9496
9497 if (IfCond) {
9498 emitOMPIfClause(CGF, IfCond, BeginThenGen, BeginElseGen);
9499 } else {
9500 RegionCodeGenTy RCG(BeginThenGen);
9501 RCG(CGF);
9502 }
9503
9504 // If we don't require privatization of device pointers, we emit the body in
9505 // between the runtime calls. This avoids duplicating the body code.
9506 if (Info.CaptureDeviceAddrMap.empty()) {
9507 CodeGen.setAction(NoPrivAction);
9508 CodeGen(CGF);
9509 }
9510
9511 if (IfCond) {
9512 emitOMPIfClause(CGF, IfCond, EndThenGen, EndElseGen);
9513 } else {
9514 RegionCodeGenTy RCG(EndThenGen);
9515 RCG(CGF);
9516 }
9517}
9518
9519void CGOpenMPRuntime::emitTargetDataStandAloneCall(
9520 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
9521 const Expr *Device) {
9522 if (!CGF.HaveInsertPoint())
9523 return;
9524
9525 assert((isa<OMPTargetEnterDataDirective>(D) ||(((isa<OMPTargetEnterDataDirective>(D) || isa<OMPTargetExitDataDirective
>(D) || isa<OMPTargetUpdateDirective>(D)) &&
"Expecting either target enter, exit data, or update directives."
) ? static_cast<void> (0) : __assert_fail ("(isa<OMPTargetEnterDataDirective>(D) || isa<OMPTargetExitDataDirective>(D) || isa<OMPTargetUpdateDirective>(D)) && \"Expecting either target enter, exit data, or update directives.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9528, __PRETTY_FUNCTION__))
9526 isa<OMPTargetExitDataDirective>(D) ||(((isa<OMPTargetEnterDataDirective>(D) || isa<OMPTargetExitDataDirective
>(D) || isa<OMPTargetUpdateDirective>(D)) &&
"Expecting either target enter, exit data, or update directives."
) ? static_cast<void> (0) : __assert_fail ("(isa<OMPTargetEnterDataDirective>(D) || isa<OMPTargetExitDataDirective>(D) || isa<OMPTargetUpdateDirective>(D)) && \"Expecting either target enter, exit data, or update directives.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9528, __PRETTY_FUNCTION__))
9527 isa<OMPTargetUpdateDirective>(D)) &&(((isa<OMPTargetEnterDataDirective>(D) || isa<OMPTargetExitDataDirective
>(D) || isa<OMPTargetUpdateDirective>(D)) &&
"Expecting either target enter, exit data, or update directives."
) ? static_cast<void> (0) : __assert_fail ("(isa<OMPTargetEnterDataDirective>(D) || isa<OMPTargetExitDataDirective>(D) || isa<OMPTargetUpdateDirective>(D)) && \"Expecting either target enter, exit data, or update directives.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9528, __PRETTY_FUNCTION__))
9528 "Expecting either target enter, exit data, or update directives.")(((isa<OMPTargetEnterDataDirective>(D) || isa<OMPTargetExitDataDirective
>(D) || isa<OMPTargetUpdateDirective>(D)) &&
"Expecting either target enter, exit data, or update directives."
) ? static_cast<void> (0) : __assert_fail ("(isa<OMPTargetEnterDataDirective>(D) || isa<OMPTargetExitDataDirective>(D) || isa<OMPTargetUpdateDirective>(D)) && \"Expecting either target enter, exit data, or update directives.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9528, __PRETTY_FUNCTION__))
;
9529
9530 CodeGenFunction::OMPTargetDataInfo InputInfo;
9531 llvm::Value *MapTypesArray = nullptr;
9532 // Generate the code for the opening of the data environment.
9533 auto &&ThenGen = [this, &D, Device, &InputInfo,
9534 &MapTypesArray](CodeGenFunction &CGF, PrePostActionTy &) {
9535 // Emit device ID if any.
9536 llvm::Value *DeviceID = nullptr;
9537 if (Device) {
9538 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
9539 CGF.Int64Ty, /*isSigned=*/true);
9540 } else {
9541 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
9542 }
9543
9544 // Emit the number of elements in the offloading arrays.
9545 llvm::Constant *PointerNum =
9546 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
9547
9548 llvm::Value *OffloadingArgs[] = {DeviceID,
9549 PointerNum,
9550 InputInfo.BasePointersArray.getPointer(),
9551 InputInfo.PointersArray.getPointer(),
9552 InputInfo.SizesArray.getPointer(),
9553 MapTypesArray};
9554
9555 // Select the right runtime function call for each expected standalone
9556 // directive.
9557 const bool HasNowait = D.hasClausesOfKind<OMPNowaitClause>();
9558 OpenMPRTLFunction RTLFn;
9559 switch (D.getDirectiveKind()) {
9560 case OMPD_target_enter_data:
9561 RTLFn = HasNowait ? OMPRTL__tgt_target_data_begin_nowait
9562 : OMPRTL__tgt_target_data_begin;
9563 break;
9564 case OMPD_target_exit_data:
9565 RTLFn = HasNowait ? OMPRTL__tgt_target_data_end_nowait
9566 : OMPRTL__tgt_target_data_end;
9567 break;
9568 case OMPD_target_update:
9569 RTLFn = HasNowait ? OMPRTL__tgt_target_data_update_nowait
9570 : OMPRTL__tgt_target_data_update;
9571 break;
9572 case OMPD_parallel:
9573 case OMPD_for:
9574 case OMPD_parallel_for:
9575 case OMPD_parallel_sections:
9576 case OMPD_for_simd:
9577 case OMPD_parallel_for_simd:
9578 case OMPD_cancel:
9579 case OMPD_cancellation_point:
9580 case OMPD_ordered:
9581 case OMPD_threadprivate:
9582 case OMPD_allocate:
9583 case OMPD_task:
9584 case OMPD_simd:
9585 case OMPD_sections:
9586 case OMPD_section:
9587 case OMPD_single:
9588 case OMPD_master:
9589 case OMPD_critical:
9590 case OMPD_taskyield:
9591 case OMPD_barrier:
9592 case OMPD_taskwait:
9593 case OMPD_taskgroup:
9594 case OMPD_atomic:
9595 case OMPD_flush:
9596 case OMPD_teams:
9597 case OMPD_target_data:
9598 case OMPD_distribute:
9599 case OMPD_distribute_simd:
9600 case OMPD_distribute_parallel_for:
9601 case OMPD_distribute_parallel_for_simd:
9602 case OMPD_teams_distribute:
9603 case OMPD_teams_distribute_simd:
9604 case OMPD_teams_distribute_parallel_for:
9605 case OMPD_teams_distribute_parallel_for_simd:
9606 case OMPD_declare_simd:
9607 case OMPD_declare_target:
9608 case OMPD_end_declare_target:
9609 case OMPD_declare_reduction:
9610 case OMPD_declare_mapper:
9611 case OMPD_taskloop:
9612 case OMPD_taskloop_simd:
9613 case OMPD_target:
9614 case OMPD_target_simd:
9615 case OMPD_target_teams_distribute:
9616 case OMPD_target_teams_distribute_simd:
9617 case OMPD_target_teams_distribute_parallel_for:
9618 case OMPD_target_teams_distribute_parallel_for_simd:
9619 case OMPD_target_teams:
9620 case OMPD_target_parallel:
9621 case OMPD_target_parallel_for:
9622 case OMPD_target_parallel_for_simd:
9623 case OMPD_requires:
9624 case OMPD_unknown:
9625 llvm_unreachable("Unexpected standalone target data directive.")::llvm::llvm_unreachable_internal("Unexpected standalone target data directive."
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9625)
;
9626 break;
9627 }
9628 CGF.EmitRuntimeCall(createRuntimeFunction(RTLFn), OffloadingArgs);
9629 };
9630
9631 auto &&TargetThenGen = [this, &ThenGen, &D, &InputInfo, &MapTypesArray](
9632 CodeGenFunction &CGF, PrePostActionTy &) {
9633 // Fill up the arrays with all the mapped variables.
9634 MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
9635 MappableExprsHandler::MapValuesArrayTy Pointers;
9636 MappableExprsHandler::MapValuesArrayTy Sizes;
9637 MappableExprsHandler::MapFlagsArrayTy MapTypes;
9638
9639 // Get map clause information.
9640 MappableExprsHandler MEHandler(D, CGF);
9641 MEHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
9642
9643 TargetDataInfo Info;
9644 // Fill up the arrays and create the arguments.
9645 emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes, Info);
9646 emitOffloadingArraysArgument(CGF, Info.BasePointersArray,
9647 Info.PointersArray, Info.SizesArray,
9648 Info.MapTypesArray, Info);
9649 InputInfo.NumberOfTargetItems = Info.NumberOfPtrs;
9650 InputInfo.BasePointersArray =
9651 Address(Info.BasePointersArray, CGM.getPointerAlign());
9652 InputInfo.PointersArray =
9653 Address(Info.PointersArray, CGM.getPointerAlign());
9654 InputInfo.SizesArray =
9655 Address(Info.SizesArray, CGM.getPointerAlign());
9656 MapTypesArray = Info.MapTypesArray;
9657 if (D.hasClausesOfKind<OMPDependClause>())
9658 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
9659 else
9660 emitInlinedDirective(CGF, D.getDirectiveKind(), ThenGen);
9661 };
9662
9663 if (IfCond) {
9664 emitOMPIfClause(CGF, IfCond, TargetThenGen,
9665 [](CodeGenFunction &CGF, PrePostActionTy &) {});
9666 } else {
9667 RegionCodeGenTy ThenRCG(TargetThenGen);
9668 ThenRCG(CGF);
9669 }
9670}
9671
9672namespace {
9673 /// Kind of parameter in a function with 'declare simd' directive.
9674 enum ParamKindTy { LinearWithVarStride, Linear, Uniform, Vector };
9675 /// Attribute set of the parameter.
9676 struct ParamAttrTy {
9677 ParamKindTy Kind = Vector;
9678 llvm::APSInt StrideOrArg;
9679 llvm::APSInt Alignment;
9680 };
9681} // namespace
9682
9683static unsigned evaluateCDTSize(const FunctionDecl *FD,
9684 ArrayRef<ParamAttrTy> ParamAttrs) {
9685 // Every vector variant of a SIMD-enabled function has a vector length (VLEN).
9686 // If OpenMP clause "simdlen" is used, the VLEN is the value of the argument
9687 // of that clause. The VLEN value must be power of 2.
9688 // In other case the notion of the function`s "characteristic data type" (CDT)
9689 // is used to compute the vector length.
9690 // CDT is defined in the following order:
9691 // a) For non-void function, the CDT is the return type.
9692 // b) If the function has any non-uniform, non-linear parameters, then the
9693 // CDT is the type of the first such parameter.
9694 // c) If the CDT determined by a) or b) above is struct, union, or class
9695 // type which is pass-by-value (except for the type that maps to the
9696 // built-in complex data type), the characteristic data type is int.
9697 // d) If none of the above three cases is applicable, the CDT is int.
9698 // The VLEN is then determined based on the CDT and the size of vector
9699 // register of that ISA for which current vector version is generated. The
9700 // VLEN is computed using the formula below:
9701 // VLEN = sizeof(vector_register) / sizeof(CDT),
9702 // where vector register size specified in section 3.2.1 Registers and the
9703 // Stack Frame of original AMD64 ABI document.
9704 QualType RetType = FD->getReturnType();
9705 if (RetType.isNull())
9706 return 0;
9707 ASTContext &C = FD->getASTContext();
9708 QualType CDT;
9709 if (!RetType.isNull() && !RetType->isVoidType()) {
9710 CDT = RetType;
9711 } else {
9712 unsigned Offset = 0;
9713 if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
9714 if (ParamAttrs[Offset].Kind == Vector)
9715 CDT = C.getPointerType(C.getRecordType(MD->getParent()));
9716 ++Offset;
9717 }
9718 if (CDT.isNull()) {
9719 for (unsigned I = 0, E = FD->getNumParams(); I < E; ++I) {
9720 if (ParamAttrs[I + Offset].Kind == Vector) {
9721 CDT = FD->getParamDecl(I)->getType();
9722 break;
9723 }
9724 }
9725 }
9726 }
9727 if (CDT.isNull())
9728 CDT = C.IntTy;
9729 CDT = CDT->getCanonicalTypeUnqualified();
9730 if (CDT->isRecordType() || CDT->isUnionType())
9731 CDT = C.IntTy;
9732 return C.getTypeSize(CDT);
9733}
9734
9735static void
9736emitX86DeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn,
9737 const llvm::APSInt &VLENVal,
9738 ArrayRef<ParamAttrTy> ParamAttrs,
9739 OMPDeclareSimdDeclAttr::BranchStateTy State) {
9740 struct ISADataTy {
9741 char ISA;
9742 unsigned VecRegSize;
9743 };
9744 ISADataTy ISAData[] = {
9745 {
9746 'b', 128
9747 }, // SSE
9748 {
9749 'c', 256
9750 }, // AVX
9751 {
9752 'd', 256
9753 }, // AVX2
9754 {
9755 'e', 512
9756 }, // AVX512
9757 };
9758 llvm::SmallVector<char, 2> Masked;
9759 switch (State) {
9760 case OMPDeclareSimdDeclAttr::BS_Undefined:
9761 Masked.push_back('N');
9762 Masked.push_back('M');
9763 break;
9764 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
9765 Masked.push_back('N');
9766 break;
9767 case OMPDeclareSimdDeclAttr::BS_Inbranch:
9768 Masked.push_back('M');
9769 break;
9770 }
9771 for (char Mask : Masked) {
9772 for (const ISADataTy &Data : ISAData) {
9773 SmallString<256> Buffer;
9774 llvm::raw_svector_ostream Out(Buffer);
9775 Out << "_ZGV" << Data.ISA << Mask;
9776 if (!VLENVal) {
9777 unsigned NumElts = evaluateCDTSize(FD, ParamAttrs);
9778 assert(NumElts && "Non-zero simdlen/cdtsize expected")((NumElts && "Non-zero simdlen/cdtsize expected") ? static_cast
<void> (0) : __assert_fail ("NumElts && \"Non-zero simdlen/cdtsize expected\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9778, __PRETTY_FUNCTION__))
;
9779 Out << llvm::APSInt::getUnsigned(Data.VecRegSize / NumElts);
9780 } else {
9781 Out << VLENVal;
9782 }
9783 for (const ParamAttrTy &ParamAttr : ParamAttrs) {
9784 switch (ParamAttr.Kind){
9785 case LinearWithVarStride:
9786 Out << 's' << ParamAttr.StrideOrArg;
9787 break;
9788 case Linear:
9789 Out << 'l';
9790 if (!!ParamAttr.StrideOrArg)
9791 Out << ParamAttr.StrideOrArg;
9792 break;
9793 case Uniform:
9794 Out << 'u';
9795 break;
9796 case Vector:
9797 Out << 'v';
9798 break;
9799 }
9800 if (!!ParamAttr.Alignment)
9801 Out << 'a' << ParamAttr.Alignment;
9802 }
9803 Out << '_' << Fn->getName();
9804 Fn->addFnAttr(Out.str());
9805 }
9806 }
9807}
9808
9809// This are the Functions that are needed to mangle the name of the
9810// vector functions generated by the compiler, according to the rules
9811// defined in the "Vector Function ABI specifications for AArch64",
9812// available at
9813// https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi.
9814
9815/// Maps To Vector (MTV), as defined in 3.1.1 of the AAVFABI.
9816///
9817/// TODO: Need to implement the behavior for reference marked with a
9818/// var or no linear modifiers (1.b in the section). For this, we
9819/// need to extend ParamKindTy to support the linear modifiers.
9820static bool getAArch64MTV(QualType QT, ParamKindTy Kind) {
9821 QT = QT.getCanonicalType();
9822
9823 if (QT->isVoidType())
9824 return false;
9825
9826 if (Kind == ParamKindTy::Uniform)
9827 return false;
9828
9829 if (Kind == ParamKindTy::Linear)
9830 return false;
9831
9832 // TODO: Handle linear references with modifiers
9833
9834 if (Kind == ParamKindTy::LinearWithVarStride)
9835 return false;
9836
9837 return true;
9838}
9839
9840/// Pass By Value (PBV), as defined in 3.1.2 of the AAVFABI.
9841static bool getAArch64PBV(QualType QT, ASTContext &C) {
9842 QT = QT.getCanonicalType();
9843 unsigned Size = C.getTypeSize(QT);
9844
9845 // Only scalars and complex within 16 bytes wide set PVB to true.
9846 if (Size != 8 && Size != 16 && Size != 32 && Size != 64 && Size != 128)
9847 return false;
9848
9849 if (QT->isFloatingType())
9850 return true;
9851
9852 if (QT->isIntegerType())
9853 return true;
9854
9855 if (QT->isPointerType())
9856 return true;
9857
9858 // TODO: Add support for complex types (section 3.1.2, item 2).
9859
9860 return false;
9861}
9862
9863/// Computes the lane size (LS) of a return type or of an input parameter,
9864/// as defined by `LS(P)` in 3.2.1 of the AAVFABI.
9865/// TODO: Add support for references, section 3.2.1, item 1.
9866static unsigned getAArch64LS(QualType QT, ParamKindTy Kind, ASTContext &C) {
9867 if (getAArch64MTV(QT, Kind) && QT.getCanonicalType()->isPointerType()) {
9868 QualType PTy = QT.getCanonicalType()->getPointeeType();
9869 if (getAArch64PBV(PTy, C))
9870 return C.getTypeSize(PTy);
9871 }
9872 if (getAArch64PBV(QT, C))
9873 return C.getTypeSize(QT);
9874
9875 return C.getTypeSize(C.getUIntPtrType());
9876}
9877
9878// Get Narrowest Data Size (NDS) and Widest Data Size (WDS) from the
9879// signature of the scalar function, as defined in 3.2.2 of the
9880// AAVFABI.
9881static std::tuple<unsigned, unsigned, bool>
9882getNDSWDS(const FunctionDecl *FD, ArrayRef<ParamAttrTy> ParamAttrs) {
9883 QualType RetType = FD->getReturnType().getCanonicalType();
9884
9885 ASTContext &C = FD->getASTContext();
9886
9887 bool OutputBecomesInput = false;
9888
9889 llvm::SmallVector<unsigned, 8> Sizes;
9890 if (!RetType->isVoidType()) {
9891 Sizes.push_back(getAArch64LS(RetType, ParamKindTy::Vector, C));
9892 if (!getAArch64PBV(RetType, C) && getAArch64MTV(RetType, {}))
9893 OutputBecomesInput = true;
9894 }
9895 for (unsigned I = 0, E = FD->getNumParams(); I < E; ++I) {
9896 QualType QT = FD->getParamDecl(I)->getType().getCanonicalType();
9897 Sizes.push_back(getAArch64LS(QT, ParamAttrs[I].Kind, C));
9898 }
9899
9900 assert(!Sizes.empty() && "Unable to determine NDS and WDS.")((!Sizes.empty() && "Unable to determine NDS and WDS."
) ? static_cast<void> (0) : __assert_fail ("!Sizes.empty() && \"Unable to determine NDS and WDS.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9900, __PRETTY_FUNCTION__))
;
9901 // The LS of a function parameter / return value can only be a power
9902 // of 2, starting from 8 bits, up to 128.
9903 assert(std::all_of(Sizes.begin(), Sizes.end(),((std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) {
return Size == 8 || Size == 16 || Size == 32 || Size == 64 ||
Size == 128; }) && "Invalid size") ? static_cast<
void> (0) : __assert_fail ("std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) { return Size == 8 || Size == 16 || Size == 32 || Size == 64 || Size == 128; }) && \"Invalid size\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9908, __PRETTY_FUNCTION__))
9904 [](unsigned Size) {((std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) {
return Size == 8 || Size == 16 || Size == 32 || Size == 64 ||
Size == 128; }) && "Invalid size") ? static_cast<
void> (0) : __assert_fail ("std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) { return Size == 8 || Size == 16 || Size == 32 || Size == 64 || Size == 128; }) && \"Invalid size\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9908, __PRETTY_FUNCTION__))
9905 return Size == 8 || Size == 16 || Size == 32 ||((std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) {
return Size == 8 || Size == 16 || Size == 32 || Size == 64 ||
Size == 128; }) && "Invalid size") ? static_cast<
void> (0) : __assert_fail ("std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) { return Size == 8 || Size == 16 || Size == 32 || Size == 64 || Size == 128; }) && \"Invalid size\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9908, __PRETTY_FUNCTION__))
9906 Size == 64 || Size == 128;((std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) {
return Size == 8 || Size == 16 || Size == 32 || Size == 64 ||
Size == 128; }) && "Invalid size") ? static_cast<
void> (0) : __assert_fail ("std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) { return Size == 8 || Size == 16 || Size == 32 || Size == 64 || Size == 128; }) && \"Invalid size\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9908, __PRETTY_FUNCTION__))
9907 }) &&((std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) {
return Size == 8 || Size == 16 || Size == 32 || Size == 64 ||
Size == 128; }) && "Invalid size") ? static_cast<
void> (0) : __assert_fail ("std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) { return Size == 8 || Size == 16 || Size == 32 || Size == 64 || Size == 128; }) && \"Invalid size\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9908, __PRETTY_FUNCTION__))
9908 "Invalid size")((std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) {
return Size == 8 || Size == 16 || Size == 32 || Size == 64 ||
Size == 128; }) && "Invalid size") ? static_cast<
void> (0) : __assert_fail ("std::all_of(Sizes.begin(), Sizes.end(), [](unsigned Size) { return Size == 8 || Size == 16 || Size == 32 || Size == 64 || Size == 128; }) && \"Invalid size\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9908, __PRETTY_FUNCTION__))
;
9909
9910 return std::make_tuple(*std::min_element(std::begin(Sizes), std::end(Sizes)),
9911 *std::max_element(std::begin(Sizes), std::end(Sizes)),
9912 OutputBecomesInput);
9913}
9914
9915/// Mangle the parameter part of the vector function name according to
9916/// their OpenMP classification. The mangling function is defined in
9917/// section 3.5 of the AAVFABI.
9918static std::string mangleVectorParameters(ArrayRef<ParamAttrTy> ParamAttrs) {
9919 SmallString<256> Buffer;
9920 llvm::raw_svector_ostream Out(Buffer);
9921 for (const auto &ParamAttr : ParamAttrs) {
9922 switch (ParamAttr.Kind) {
9923 case LinearWithVarStride:
9924 Out << "ls" << ParamAttr.StrideOrArg;
9925 break;
9926 case Linear:
9927 Out << 'l';
9928 // Don't print the step value if it is not present or if it is
9929 // equal to 1.
9930 if (!!ParamAttr.StrideOrArg && ParamAttr.StrideOrArg != 1)
9931 Out << ParamAttr.StrideOrArg;
9932 break;
9933 case Uniform:
9934 Out << 'u';
9935 break;
9936 case Vector:
9937 Out << 'v';
9938 break;
9939 }
9940
9941 if (!!ParamAttr.Alignment)
9942 Out << 'a' << ParamAttr.Alignment;
9943 }
9944
9945 return Out.str();
9946}
9947
9948// Function used to add the attribute. The parameter `VLEN` is
9949// templated to allow the use of "x" when targeting scalable functions
9950// for SVE.
9951template <typename T>
9952static void addAArch64VectorName(T VLEN, StringRef LMask, StringRef Prefix,
9953 char ISA, StringRef ParSeq,
9954 StringRef MangledName, bool OutputBecomesInput,
9955 llvm::Function *Fn) {
9956 SmallString<256> Buffer;
9957 llvm::raw_svector_ostream Out(Buffer);
9958 Out << Prefix << ISA << LMask << VLEN;
9959 if (OutputBecomesInput)
9960 Out << "v";
9961 Out << ParSeq << "_" << MangledName;
9962 Fn->addFnAttr(Out.str());
9963}
9964
9965// Helper function to generate the Advanced SIMD names depending on
9966// the value of the NDS when simdlen is not present.
9967static void addAArch64AdvSIMDNDSNames(unsigned NDS, StringRef Mask,
9968 StringRef Prefix, char ISA,
9969 StringRef ParSeq, StringRef MangledName,
9970 bool OutputBecomesInput,
9971 llvm::Function *Fn) {
9972 switch (NDS) {
9973 case 8:
9974 addAArch64VectorName(8, Mask, Prefix, ISA, ParSeq, MangledName,
9975 OutputBecomesInput, Fn);
9976 addAArch64VectorName(16, Mask, Prefix, ISA, ParSeq, MangledName,
9977 OutputBecomesInput, Fn);
9978 break;
9979 case 16:
9980 addAArch64VectorName(4, Mask, Prefix, ISA, ParSeq, MangledName,
9981 OutputBecomesInput, Fn);
9982 addAArch64VectorName(8, Mask, Prefix, ISA, ParSeq, MangledName,
9983 OutputBecomesInput, Fn);
9984 break;
9985 case 32:
9986 addAArch64VectorName(2, Mask, Prefix, ISA, ParSeq, MangledName,
9987 OutputBecomesInput, Fn);
9988 addAArch64VectorName(4, Mask, Prefix, ISA, ParSeq, MangledName,
9989 OutputBecomesInput, Fn);
9990 break;
9991 case 64:
9992 case 128:
9993 addAArch64VectorName(2, Mask, Prefix, ISA, ParSeq, MangledName,
9994 OutputBecomesInput, Fn);
9995 break;
9996 default:
9997 llvm_unreachable("Scalar type is too wide.")::llvm::llvm_unreachable_internal("Scalar type is too wide.",
"/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 9997)
;
9998 }
9999}
10000
10001/// Emit vector function attributes for AArch64, as defined in the AAVFABI.
10002static void emitAArch64DeclareSimdFunction(
10003 CodeGenModule &CGM, const FunctionDecl *FD, unsigned UserVLEN,
10004 ArrayRef<ParamAttrTy> ParamAttrs,
10005 OMPDeclareSimdDeclAttr::BranchStateTy State, StringRef MangledName,
10006 char ISA, unsigned VecRegSize, llvm::Function *Fn, SourceLocation SLoc) {
10007
10008 // Get basic data for building the vector signature.
10009 const auto Data = getNDSWDS(FD, ParamAttrs);
10010 const unsigned NDS = std::get<0>(Data);
10011 const unsigned WDS = std::get<1>(Data);
10012 const bool OutputBecomesInput = std::get<2>(Data);
10013
10014 // Check the values provided via `simdlen` by the user.
10015 // 1. A `simdlen(1)` doesn't produce vector signatures,
10016 if (UserVLEN == 1) {
10017 unsigned DiagID = CGM.getDiags().getCustomDiagID(
10018 DiagnosticsEngine::Warning,
10019 "The clause simdlen(1) has no effect when targeting aarch64.");
10020 CGM.getDiags().Report(SLoc, DiagID);
10021 return;
10022 }
10023
10024 // 2. Section 3.3.1, item 1: user input must be a power of 2 for
10025 // Advanced SIMD output.
10026 if (ISA == 'n' && UserVLEN && !llvm::isPowerOf2_32(UserVLEN)) {
10027 unsigned DiagID = CGM.getDiags().getCustomDiagID(
10028 DiagnosticsEngine::Warning, "The value specified in simdlen must be a "
10029 "power of 2 when targeting Advanced SIMD.");
10030 CGM.getDiags().Report(SLoc, DiagID);
10031 return;
10032 }
10033
10034 // 3. Section 3.4.1. SVE fixed lengh must obey the architectural
10035 // limits.
10036 if (ISA == 's' && UserVLEN != 0) {
10037 if ((UserVLEN * WDS > 2048) || (UserVLEN * WDS % 128 != 0)) {
10038 unsigned DiagID = CGM.getDiags().getCustomDiagID(
10039 DiagnosticsEngine::Warning, "The clause simdlen must fit the %0-bit "
10040 "lanes in the architectural constraints "
10041 "for SVE (min is 128-bit, max is "
10042 "2048-bit, by steps of 128-bit)");
10043 CGM.getDiags().Report(SLoc, DiagID) << WDS;
10044 return;
10045 }
10046 }
10047
10048 // Sort out parameter sequence.
10049 const std::string ParSeq = mangleVectorParameters(ParamAttrs);
10050 StringRef Prefix = "_ZGV";
10051 // Generate simdlen from user input (if any).
10052 if (UserVLEN) {
10053 if (ISA == 's') {
10054 // SVE generates only a masked function.
10055 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
10056 OutputBecomesInput, Fn);
10057 } else {
10058 assert(ISA == 'n' && "Expected ISA either 's' or 'n'.")((ISA == 'n' && "Expected ISA either 's' or 'n'.") ? static_cast
<void> (0) : __assert_fail ("ISA == 'n' && \"Expected ISA either 's' or 'n'.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10058, __PRETTY_FUNCTION__))
;
10059 // Advanced SIMD generates one or two functions, depending on
10060 // the `[not]inbranch` clause.
10061 switch (State) {
10062 case OMPDeclareSimdDeclAttr::BS_Undefined:
10063 addAArch64VectorName(UserVLEN, "N", Prefix, ISA, ParSeq, MangledName,
10064 OutputBecomesInput, Fn);
10065 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
10066 OutputBecomesInput, Fn);
10067 break;
10068 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
10069 addAArch64VectorName(UserVLEN, "N", Prefix, ISA, ParSeq, MangledName,
10070 OutputBecomesInput, Fn);
10071 break;
10072 case OMPDeclareSimdDeclAttr::BS_Inbranch:
10073 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
10074 OutputBecomesInput, Fn);
10075 break;
10076 }
10077 }
10078 } else {
10079 // If no user simdlen is provided, follow the AAVFABI rules for
10080 // generating the vector length.
10081 if (ISA == 's') {
10082 // SVE, section 3.4.1, item 1.
10083 addAArch64VectorName("x", "M", Prefix, ISA, ParSeq, MangledName,
10084 OutputBecomesInput, Fn);
10085 } else {
10086 assert(ISA == 'n' && "Expected ISA either 's' or 'n'.")((ISA == 'n' && "Expected ISA either 's' or 'n'.") ? static_cast
<void> (0) : __assert_fail ("ISA == 'n' && \"Expected ISA either 's' or 'n'.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10086, __PRETTY_FUNCTION__))
;
10087 // Advanced SIMD, Section 3.3.1 of the AAVFABI, generates one or
10088 // two vector names depending on the use of the clause
10089 // `[not]inbranch`.
10090 switch (State) {
10091 case OMPDeclareSimdDeclAttr::BS_Undefined:
10092 addAArch64AdvSIMDNDSNames(NDS, "N", Prefix, ISA, ParSeq, MangledName,
10093 OutputBecomesInput, Fn);
10094 addAArch64AdvSIMDNDSNames(NDS, "M", Prefix, ISA, ParSeq, MangledName,
10095 OutputBecomesInput, Fn);
10096 break;
10097 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
10098 addAArch64AdvSIMDNDSNames(NDS, "N", Prefix, ISA, ParSeq, MangledName,
10099 OutputBecomesInput, Fn);
10100 break;
10101 case OMPDeclareSimdDeclAttr::BS_Inbranch:
10102 addAArch64AdvSIMDNDSNames(NDS, "M", Prefix, ISA, ParSeq, MangledName,
10103 OutputBecomesInput, Fn);
10104 break;
10105 }
10106 }
10107 }
10108}
10109
10110void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
10111 llvm::Function *Fn) {
10112 ASTContext &C = CGM.getContext();
10113 FD = FD->getMostRecentDecl();
10114 // Map params to their positions in function decl.
10115 llvm::DenseMap<const Decl *, unsigned> ParamPositions;
10116 if (isa<CXXMethodDecl>(FD))
10117 ParamPositions.try_emplace(FD, 0);
10118 unsigned ParamPos = ParamPositions.size();
10119 for (const ParmVarDecl *P : FD->parameters()) {
10120 ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
10121 ++ParamPos;
10122 }
10123 while (FD) {
10124 for (const auto *Attr : FD->specific_attrs<OMPDeclareSimdDeclAttr>()) {
10125 llvm::SmallVector<ParamAttrTy, 8> ParamAttrs(ParamPositions.size());
10126 // Mark uniform parameters.
10127 for (const Expr *E : Attr->uniforms()) {
10128 E = E->IgnoreParenImpCasts();
10129 unsigned Pos;
10130 if (isa<CXXThisExpr>(E)) {
10131 Pos = ParamPositions[FD];
10132 } else {
10133 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
10134 ->getCanonicalDecl();
10135 Pos = ParamPositions[PVD];
10136 }
10137 ParamAttrs[Pos].Kind = Uniform;
10138 }
10139 // Get alignment info.
10140 auto NI = Attr->alignments_begin();
10141 for (const Expr *E : Attr->aligneds()) {
10142 E = E->IgnoreParenImpCasts();
10143 unsigned Pos;
10144 QualType ParmTy;
10145 if (isa<CXXThisExpr>(E)) {
10146 Pos = ParamPositions[FD];
10147 ParmTy = E->getType();
10148 } else {
10149 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
10150 ->getCanonicalDecl();
10151 Pos = ParamPositions[PVD];
10152 ParmTy = PVD->getType();
10153 }
10154 ParamAttrs[Pos].Alignment =
10155 (*NI)
10156 ? (*NI)->EvaluateKnownConstInt(C)
10157 : llvm::APSInt::getUnsigned(
10158 C.toCharUnitsFromBits(C.getOpenMPDefaultSimdAlign(ParmTy))
10159 .getQuantity());
10160 ++NI;
10161 }
10162 // Mark linear parameters.
10163 auto SI = Attr->steps_begin();
10164 auto MI = Attr->modifiers_begin();
10165 for (const Expr *E : Attr->linears()) {
10166 E = E->IgnoreParenImpCasts();
10167 unsigned Pos;
10168 if (isa<CXXThisExpr>(E)) {
10169 Pos = ParamPositions[FD];
10170 } else {
10171 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
10172 ->getCanonicalDecl();
10173 Pos = ParamPositions[PVD];
10174 }
10175 ParamAttrTy &ParamAttr = ParamAttrs[Pos];
10176 ParamAttr.Kind = Linear;
10177 if (*SI) {
10178 Expr::EvalResult Result;
10179 if (!(*SI)->EvaluateAsInt(Result, C, Expr::SE_AllowSideEffects)) {
10180 if (const auto *DRE =
10181 cast<DeclRefExpr>((*SI)->IgnoreParenImpCasts())) {
10182 if (const auto *StridePVD = cast<ParmVarDecl>(DRE->getDecl())) {
10183 ParamAttr.Kind = LinearWithVarStride;
10184 ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(
10185 ParamPositions[StridePVD->getCanonicalDecl()]);
10186 }
10187 }
10188 } else {
10189 ParamAttr.StrideOrArg = Result.Val.getInt();
10190 }
10191 }
10192 ++SI;
10193 ++MI;
10194 }
10195 llvm::APSInt VLENVal;
10196 SourceLocation ExprLoc;
10197 const Expr *VLENExpr = Attr->getSimdlen();
10198 if (VLENExpr) {
10199 VLENVal = VLENExpr->EvaluateKnownConstInt(C);
10200 ExprLoc = VLENExpr->getExprLoc();
10201 }
10202 OMPDeclareSimdDeclAttr::BranchStateTy State = Attr->getBranchState();
10203 if (CGM.getTriple().getArch() == llvm::Triple::x86 ||
10204 CGM.getTriple().getArch() == llvm::Triple::x86_64) {
10205 emitX86DeclareSimdFunction(FD, Fn, VLENVal, ParamAttrs, State);
10206 } else if (CGM.getTriple().getArch() == llvm::Triple::aarch64) {
10207 unsigned VLEN = VLENVal.getExtValue();
10208 StringRef MangledName = Fn->getName();
10209 if (CGM.getTarget().hasFeature("sve"))
10210 emitAArch64DeclareSimdFunction(CGM, FD, VLEN, ParamAttrs, State,
10211 MangledName, 's', 128, Fn, ExprLoc);
10212 if (CGM.getTarget().hasFeature("neon"))
10213 emitAArch64DeclareSimdFunction(CGM, FD, VLEN, ParamAttrs, State,
10214 MangledName, 'n', 128, Fn, ExprLoc);
10215 }
10216 }
10217 FD = FD->getPreviousDecl();
10218 }
10219}
10220
10221namespace {
10222/// Cleanup action for doacross support.
10223class DoacrossCleanupTy final : public EHScopeStack::Cleanup {
10224public:
10225 static const int DoacrossFinArgs = 2;
10226
10227private:
10228 llvm::FunctionCallee RTLFn;
10229 llvm::Value *Args[DoacrossFinArgs];
10230
10231public:
10232 DoacrossCleanupTy(llvm::FunctionCallee RTLFn,
10233 ArrayRef<llvm::Value *> CallArgs)
10234 : RTLFn(RTLFn) {
10235 assert(CallArgs.size() == DoacrossFinArgs)((CallArgs.size() == DoacrossFinArgs) ? static_cast<void>
(0) : __assert_fail ("CallArgs.size() == DoacrossFinArgs", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10235, __PRETTY_FUNCTION__))
;
10236 std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
10237 }
10238 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
10239 if (!CGF.HaveInsertPoint())
10240 return;
10241 CGF.EmitRuntimeCall(RTLFn, Args);
10242 }
10243};
10244} // namespace
10245
10246void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF,
10247 const OMPLoopDirective &D,
10248 ArrayRef<Expr *> NumIterations) {
10249 if (!CGF.HaveInsertPoint())
10250 return;
10251
10252 ASTContext &C = CGM.getContext();
10253 QualType Int64Ty = C.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/true);
10254 RecordDecl *RD;
10255 if (KmpDimTy.isNull()) {
10256 // Build struct kmp_dim { // loop bounds info casted to kmp_int64
10257 // kmp_int64 lo; // lower
10258 // kmp_int64 up; // upper
10259 // kmp_int64 st; // stride
10260 // };
10261 RD = C.buildImplicitRecord("kmp_dim");
10262 RD->startDefinition();
10263 addFieldToRecordDecl(C, RD, Int64Ty);
10264 addFieldToRecordDecl(C, RD, Int64Ty);
10265 addFieldToRecordDecl(C, RD, Int64Ty);
10266 RD->completeDefinition();
10267 KmpDimTy = C.getRecordType(RD);
10268 } else {
10269 RD = cast<RecordDecl>(KmpDimTy->getAsTagDecl());
10270 }
10271 llvm::APInt Size(/*numBits=*/32, NumIterations.size());
10272 QualType ArrayTy =
10273 C.getConstantArrayType(KmpDimTy, Size, ArrayType::Normal, 0);
10274
10275 Address DimsAddr = CGF.CreateMemTemp(ArrayTy, "dims");
10276 CGF.EmitNullInitialization(DimsAddr, ArrayTy);
10277 enum { LowerFD = 0, UpperFD, StrideFD };
10278 // Fill dims with data.
10279 for (unsigned I = 0, E = NumIterations.size(); I < E; ++I) {
10280 LValue DimsLVal = CGF.MakeAddrLValue(
10281 CGF.Builder.CreateConstArrayGEP(DimsAddr, I), KmpDimTy);
10282 // dims.upper = num_iterations;
10283 LValue UpperLVal = CGF.EmitLValueForField(
10284 DimsLVal, *std::next(RD->field_begin(), UpperFD));
10285 llvm::Value *NumIterVal =
10286 CGF.EmitScalarConversion(CGF.EmitScalarExpr(NumIterations[I]),
10287 D.getNumIterations()->getType(), Int64Ty,
10288 D.getNumIterations()->getExprLoc());
10289 CGF.EmitStoreOfScalar(NumIterVal, UpperLVal);
10290 // dims.stride = 1;
10291 LValue StrideLVal = CGF.EmitLValueForField(
10292 DimsLVal, *std::next(RD->field_begin(), StrideFD));
10293 CGF.EmitStoreOfScalar(llvm::ConstantInt::getSigned(CGM.Int64Ty, /*V=*/1),
10294 StrideLVal);
10295 }
10296
10297 // Build call void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid,
10298 // kmp_int32 num_dims, struct kmp_dim * dims);
10299 llvm::Value *Args[] = {
10300 emitUpdateLocation(CGF, D.getBeginLoc()),
10301 getThreadID(CGF, D.getBeginLoc()),
10302 llvm::ConstantInt::getSigned(CGM.Int32Ty, NumIterations.size()),
10303 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
10304 CGF.Builder.CreateConstArrayGEP(DimsAddr, 0).getPointer(),
10305 CGM.VoidPtrTy)};
10306
10307 llvm::FunctionCallee RTLFn =
10308 createRuntimeFunction(OMPRTL__kmpc_doacross_init);
10309 CGF.EmitRuntimeCall(RTLFn, Args);
10310 llvm::Value *FiniArgs[DoacrossCleanupTy::DoacrossFinArgs] = {
10311 emitUpdateLocation(CGF, D.getEndLoc()), getThreadID(CGF, D.getEndLoc())};
10312 llvm::FunctionCallee FiniRTLFn =
10313 createRuntimeFunction(OMPRTL__kmpc_doacross_fini);
10314 CGF.EHStack.pushCleanup<DoacrossCleanupTy>(NormalAndEHCleanup, FiniRTLFn,
10315 llvm::makeArrayRef(FiniArgs));
10316}
10317
10318void CGOpenMPRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
10319 const OMPDependClause *C) {
10320 QualType Int64Ty =
10321 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
10322 llvm::APInt Size(/*numBits=*/32, C->getNumLoops());
10323 QualType ArrayTy = CGM.getContext().getConstantArrayType(
10324 Int64Ty, Size, ArrayType::Normal, 0);
10325 Address CntAddr = CGF.CreateMemTemp(ArrayTy, ".cnt.addr");
10326 for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I) {
10327 const Expr *CounterVal = C->getLoopData(I);
10328 assert(CounterVal)((CounterVal) ? static_cast<void> (0) : __assert_fail (
"CounterVal", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10328, __PRETTY_FUNCTION__))
;
10329 llvm::Value *CntVal = CGF.EmitScalarConversion(
10330 CGF.EmitScalarExpr(CounterVal), CounterVal->getType(), Int64Ty,
10331 CounterVal->getExprLoc());
10332 CGF.EmitStoreOfScalar(CntVal, CGF.Builder.CreateConstArrayGEP(CntAddr, I),
10333 /*Volatile=*/false, Int64Ty);
10334 }
10335 llvm::Value *Args[] = {
10336 emitUpdateLocation(CGF, C->getBeginLoc()),
10337 getThreadID(CGF, C->getBeginLoc()),
10338 CGF.Builder.CreateConstArrayGEP(CntAddr, 0).getPointer()};
10339 llvm::FunctionCallee RTLFn;
10340 if (C->getDependencyKind() == OMPC_DEPEND_source) {
10341 RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_post);
10342 } else {
10343 assert(C->getDependencyKind() == OMPC_DEPEND_sink)((C->getDependencyKind() == OMPC_DEPEND_sink) ? static_cast
<void> (0) : __assert_fail ("C->getDependencyKind() == OMPC_DEPEND_sink"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10343, __PRETTY_FUNCTION__))
;
10344 RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_wait);
10345 }
10346 CGF.EmitRuntimeCall(RTLFn, Args);
10347}
10348
10349void CGOpenMPRuntime::emitCall(CodeGenFunction &CGF, SourceLocation Loc,
10350 llvm::FunctionCallee Callee,
10351 ArrayRef<llvm::Value *> Args) const {
10352 assert(Loc.isValid() && "Outlined function call location must be valid.")((Loc.isValid() && "Outlined function call location must be valid."
) ? static_cast<void> (0) : __assert_fail ("Loc.isValid() && \"Outlined function call location must be valid.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10352, __PRETTY_FUNCTION__))
;
10353 auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
10354
10355 if (auto *Fn = dyn_cast<llvm::Function>(Callee.getCallee())) {
10356 if (Fn->doesNotThrow()) {
10357 CGF.EmitNounwindRuntimeCall(Fn, Args);
10358 return;
10359 }
10360 }
10361 CGF.EmitRuntimeCall(Callee, Args);
10362}
10363
10364void CGOpenMPRuntime::emitOutlinedFunctionCall(
10365 CodeGenFunction &CGF, SourceLocation Loc, llvm::FunctionCallee OutlinedFn,
10366 ArrayRef<llvm::Value *> Args) const {
10367 emitCall(CGF, Loc, OutlinedFn, Args);
10368}
10369
10370void CGOpenMPRuntime::emitFunctionProlog(CodeGenFunction &CGF, const Decl *D) {
10371 if (const auto *FD = dyn_cast<FunctionDecl>(D))
10372 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD))
10373 HasEmittedDeclareTargetRegion = true;
10374}
10375
10376Address CGOpenMPRuntime::getParameterAddress(CodeGenFunction &CGF,
10377 const VarDecl *NativeParam,
10378 const VarDecl *TargetParam) const {
10379 return CGF.GetAddrOfLocalVar(NativeParam);
10380}
10381
10382namespace {
10383/// Cleanup action for allocate support.
10384class OMPAllocateCleanupTy final : public EHScopeStack::Cleanup {
10385public:
10386 static const int CleanupArgs = 3;
10387
10388private:
10389 llvm::FunctionCallee RTLFn;
10390 llvm::Value *Args[CleanupArgs];
10391
10392public:
10393 OMPAllocateCleanupTy(llvm::FunctionCallee RTLFn,
10394 ArrayRef<llvm::Value *> CallArgs)
10395 : RTLFn(RTLFn) {
10396 assert(CallArgs.size() == CleanupArgs &&((CallArgs.size() == CleanupArgs && "Size of arguments does not match."
) ? static_cast<void> (0) : __assert_fail ("CallArgs.size() == CleanupArgs && \"Size of arguments does not match.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10397, __PRETTY_FUNCTION__))
10397 "Size of arguments does not match.")((CallArgs.size() == CleanupArgs && "Size of arguments does not match."
) ? static_cast<void> (0) : __assert_fail ("CallArgs.size() == CleanupArgs && \"Size of arguments does not match.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10397, __PRETTY_FUNCTION__))
;
10398 std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
10399 }
10400 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
10401 if (!CGF.HaveInsertPoint())
10402 return;
10403 CGF.EmitRuntimeCall(RTLFn, Args);
10404 }
10405};
10406} // namespace
10407
10408Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF,
10409 const VarDecl *VD) {
10410 if (!VD)
10411 return Address::invalid();
10412 const VarDecl *CVD = VD->getCanonicalDecl();
10413 if (!CVD->hasAttr<OMPAllocateDeclAttr>())
10414 return Address::invalid();
10415 const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>();
10416 // Use the default allocation.
10417 if (AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc &&
10418 !AA->getAllocator())
10419 return Address::invalid();
10420 llvm::Value *Size;
10421 CharUnits Align = CGM.getContext().getDeclAlign(CVD);
10422 if (CVD->getType()->isVariablyModifiedType()) {
10423 Size = CGF.getTypeSize(CVD->getType());
10424 // Align the size: ((size + align - 1) / align) * align
10425 Size = CGF.Builder.CreateNUWAdd(
10426 Size, CGM.getSize(Align - CharUnits::fromQuantity(1)));
10427 Size = CGF.Builder.CreateUDiv(Size, CGM.getSize(Align));
10428 Size = CGF.Builder.CreateNUWMul(Size, CGM.getSize(Align));
10429 } else {
10430 CharUnits Sz = CGM.getContext().getTypeSizeInChars(CVD->getType());
10431 Size = CGM.getSize(Sz.alignTo(Align));
10432 }
10433 llvm::Value *ThreadID = getThreadID(CGF, CVD->getBeginLoc());
10434 assert(AA->getAllocator() &&((AA->getAllocator() && "Expected allocator expression for non-default allocator."
) ? static_cast<void> (0) : __assert_fail ("AA->getAllocator() && \"Expected allocator expression for non-default allocator.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10435, __PRETTY_FUNCTION__))
10435 "Expected allocator expression for non-default allocator.")((AA->getAllocator() && "Expected allocator expression for non-default allocator."
) ? static_cast<void> (0) : __assert_fail ("AA->getAllocator() && \"Expected allocator expression for non-default allocator.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10435, __PRETTY_FUNCTION__))
;
10436 llvm::Value *Allocator = CGF.EmitScalarExpr(AA->getAllocator());
10437 // According to the standard, the original allocator type is a enum (integer).
10438 // Convert to pointer type, if required.
10439 if (Allocator->getType()->isIntegerTy())
10440 Allocator = CGF.Builder.CreateIntToPtr(Allocator, CGM.VoidPtrTy);
10441 else if (Allocator->getType()->isPointerTy())
10442 Allocator = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Allocator,
10443 CGM.VoidPtrTy);
10444 llvm::Value *Args[] = {ThreadID, Size, Allocator};
10445
10446 llvm::Value *Addr =
10447 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_alloc), Args,
10448 CVD->getName() + ".void.addr");
10449 llvm::Value *FiniArgs[OMPAllocateCleanupTy::CleanupArgs] = {ThreadID, Addr,
10450 Allocator};
10451 llvm::FunctionCallee FiniRTLFn = createRuntimeFunction(OMPRTL__kmpc_free);
10452
10453 CGF.EHStack.pushCleanup<OMPAllocateCleanupTy>(NormalAndEHCleanup, FiniRTLFn,
10454 llvm::makeArrayRef(FiniArgs));
10455 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
10456 Addr,
10457 CGF.ConvertTypeForMem(CGM.getContext().getPointerType(CVD->getType())),
10458 CVD->getName() + ".addr");
10459 return Address(Addr, Align);
10460}
10461
10462llvm::Function *CGOpenMPSIMDRuntime::emitParallelOutlinedFunction(
10463 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
10464 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
10465 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10465)
;
10466}
10467
10468llvm::Function *CGOpenMPSIMDRuntime::emitTeamsOutlinedFunction(
10469 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
10470 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
10471 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10471)
;
10472}
10473
10474llvm::Function *CGOpenMPSIMDRuntime::emitTaskOutlinedFunction(
10475 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
10476 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
10477 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
10478 bool Tied, unsigned &NumberOfParts) {
10479 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10479)
;
10480}
10481
10482void CGOpenMPSIMDRuntime::emitParallelCall(CodeGenFunction &CGF,
10483 SourceLocation Loc,
10484 llvm::Function *OutlinedFn,
10485 ArrayRef<llvm::Value *> CapturedVars,
10486 const Expr *IfCond) {
10487 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10487)
;
10488}
10489
10490void CGOpenMPSIMDRuntime::emitCriticalRegion(
10491 CodeGenFunction &CGF, StringRef CriticalName,
10492 const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc,
10493 const Expr *Hint) {
10494 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10494)
;
10495}
10496
10497void CGOpenMPSIMDRuntime::emitMasterRegion(CodeGenFunction &CGF,
10498 const RegionCodeGenTy &MasterOpGen,
10499 SourceLocation Loc) {
10500 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10500)
;
10501}
10502
10503void CGOpenMPSIMDRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
10504 SourceLocation Loc) {
10505 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10505)
;
10506}
10507
10508void CGOpenMPSIMDRuntime::emitTaskgroupRegion(
10509 CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen,
10510 SourceLocation Loc) {
10511 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10511)
;
10512}
10513
10514void CGOpenMPSIMDRuntime::emitSingleRegion(
10515 CodeGenFunction &CGF, const RegionCodeGenTy &SingleOpGen,
10516 SourceLocation Loc, ArrayRef<const Expr *> CopyprivateVars,
10517 ArrayRef<const Expr *> DestExprs, ArrayRef<const Expr *> SrcExprs,
10518 ArrayRef<const Expr *> AssignmentOps) {
10519 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10519)
;
10520}
10521
10522void CGOpenMPSIMDRuntime::emitOrderedRegion(CodeGenFunction &CGF,
10523 const RegionCodeGenTy &OrderedOpGen,
10524 SourceLocation Loc,
10525 bool IsThreads) {
10526 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10526)
;
10527}
10528
10529void CGOpenMPSIMDRuntime::emitBarrierCall(CodeGenFunction &CGF,
10530 SourceLocation Loc,
10531 OpenMPDirectiveKind Kind,
10532 bool EmitChecks,
10533 bool ForceSimpleCall) {
10534 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10534)
;
10535}
10536
10537void CGOpenMPSIMDRuntime::emitForDispatchInit(
10538 CodeGenFunction &CGF, SourceLocation Loc,
10539 const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned,
10540 bool Ordered, const DispatchRTInput &DispatchValues) {
10541 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10541)
;
10542}
10543
10544void CGOpenMPSIMDRuntime::emitForStaticInit(
10545 CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind,
10546 const OpenMPScheduleTy &ScheduleKind, const StaticRTInput &Values) {
10547 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10547)
;
10548}
10549
10550void CGOpenMPSIMDRuntime::emitDistributeStaticInit(
10551 CodeGenFunction &CGF, SourceLocation Loc,
10552 OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values) {
10553 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10553)
;
10554}
10555
10556void CGOpenMPSIMDRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF,
10557 SourceLocation Loc,
10558 unsigned IVSize,
10559 bool IVSigned) {
10560 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10560)
;
10561}
10562
10563void CGOpenMPSIMDRuntime::emitForStaticFinish(CodeGenFunction &CGF,
10564 SourceLocation Loc,
10565 OpenMPDirectiveKind DKind) {
10566 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10566)
;
10567}
10568
10569llvm::Value *CGOpenMPSIMDRuntime::emitForNext(CodeGenFunction &CGF,
10570 SourceLocation Loc,
10571 unsigned IVSize, bool IVSigned,
10572 Address IL, Address LB,
10573 Address UB, Address ST) {
10574 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10574)
;
10575}
10576
10577void CGOpenMPSIMDRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
10578 llvm::Value *NumThreads,
10579 SourceLocation Loc) {
10580 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10580)
;
10581}
10582
10583void CGOpenMPSIMDRuntime::emitProcBindClause(CodeGenFunction &CGF,
10584 OpenMPProcBindClauseKind ProcBind,
10585 SourceLocation Loc) {
10586 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10586)
;
10587}
10588
10589Address CGOpenMPSIMDRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
10590 const VarDecl *VD,
10591 Address VDAddr,
10592 SourceLocation Loc) {
10593 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10593)
;
10594}
10595
10596llvm::Function *CGOpenMPSIMDRuntime::emitThreadPrivateVarDefinition(
10597 const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit,
10598 CodeGenFunction *CGF) {
10599 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10599)
;
10600}
10601
10602Address CGOpenMPSIMDRuntime::getAddrOfArtificialThreadPrivate(
10603 CodeGenFunction &CGF, QualType VarType, StringRef Name) {
10604 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10604)
;
10605}
10606
10607void CGOpenMPSIMDRuntime::emitFlush(CodeGenFunction &CGF,
10608 ArrayRef<const Expr *> Vars,
10609 SourceLocation Loc) {
10610 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10610)
;
10611}
10612
10613void CGOpenMPSIMDRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
10614 const OMPExecutableDirective &D,
10615 llvm::Function *TaskFunction,
10616 QualType SharedsTy, Address Shareds,
10617 const Expr *IfCond,
10618 const OMPTaskDataTy &Data) {
10619 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10619)
;
10620}
10621
10622void CGOpenMPSIMDRuntime::emitTaskLoopCall(
10623 CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
10624 llvm::Function *TaskFunction, QualType SharedsTy, Address Shareds,
10625 const Expr *IfCond, const OMPTaskDataTy &Data) {
10626 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10626)
;
10627}
10628
10629void CGOpenMPSIMDRuntime::emitReduction(
10630 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> Privates,
10631 ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
10632 ArrayRef<const Expr *> ReductionOps, ReductionOptionsTy Options) {
10633 assert(Options.SimpleReduction && "Only simple reduction is expected.")((Options.SimpleReduction && "Only simple reduction is expected."
) ? static_cast<void> (0) : __assert_fail ("Options.SimpleReduction && \"Only simple reduction is expected.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10633, __PRETTY_FUNCTION__))
;
10634 CGOpenMPRuntime::emitReduction(CGF, Loc, Privates, LHSExprs, RHSExprs,
10635 ReductionOps, Options);
10636}
10637
10638llvm::Value *CGOpenMPSIMDRuntime::emitTaskReductionInit(
10639 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> LHSExprs,
10640 ArrayRef<const Expr *> RHSExprs, const OMPTaskDataTy &Data) {
10641 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10641)
;
10642}
10643
10644void CGOpenMPSIMDRuntime::emitTaskReductionFixups(CodeGenFunction &CGF,
10645 SourceLocation Loc,
10646 ReductionCodeGen &RCG,
10647 unsigned N) {
10648 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10648)
;
10649}
10650
10651Address CGOpenMPSIMDRuntime::getTaskReductionItem(CodeGenFunction &CGF,
10652 SourceLocation Loc,
10653 llvm::Value *ReductionsPtr,
10654 LValue SharedLVal) {
10655 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10655)
;
10656}
10657
10658void CGOpenMPSIMDRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
10659 SourceLocation Loc) {
10660 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10660)
;
10661}
10662
10663void CGOpenMPSIMDRuntime::emitCancellationPointCall(
10664 CodeGenFunction &CGF, SourceLocation Loc,
10665 OpenMPDirectiveKind CancelRegion) {
10666 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10666)
;
10667}
10668
10669void CGOpenMPSIMDRuntime::emitCancelCall(CodeGenFunction &CGF,
10670 SourceLocation Loc, const Expr *IfCond,
10671 OpenMPDirectiveKind CancelRegion) {
10672 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10672)
;
10673}
10674
10675void CGOpenMPSIMDRuntime::emitTargetOutlinedFunction(
10676 const OMPExecutableDirective &D, StringRef ParentName,
10677 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
10678 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
10679 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10679)
;
10680}
10681
10682void CGOpenMPSIMDRuntime::emitTargetCall(CodeGenFunction &CGF,
10683 const OMPExecutableDirective &D,
10684 llvm::Function *OutlinedFn,
10685 llvm::Value *OutlinedFnID,
10686 const Expr *IfCond,
10687 const Expr *Device) {
10688 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10688)
;
10689}
10690
10691bool CGOpenMPSIMDRuntime::emitTargetFunctions(GlobalDecl GD) {
10692 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10692)
;
10693}
10694
10695bool CGOpenMPSIMDRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
10696 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10696)
;
10697}
10698
10699bool CGOpenMPSIMDRuntime::emitTargetGlobal(GlobalDecl GD) {
10700 return false;
10701}
10702
10703llvm::Function *CGOpenMPSIMDRuntime::emitRegistrationFunction() {
10704 return nullptr;
10705}
10706
10707void CGOpenMPSIMDRuntime::emitTeamsCall(CodeGenFunction &CGF,
10708 const OMPExecutableDirective &D,
10709 SourceLocation Loc,
10710 llvm::Function *OutlinedFn,
10711 ArrayRef<llvm::Value *> CapturedVars) {
10712 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10712)
;
10713}
10714
10715void CGOpenMPSIMDRuntime::emitNumTeamsClause(CodeGenFunction &CGF,
10716 const Expr *NumTeams,
10717 const Expr *ThreadLimit,
10718 SourceLocation Loc) {
10719 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10719)
;
10720}
10721
10722void CGOpenMPSIMDRuntime::emitTargetDataCalls(
10723 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
10724 const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) {
10725 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10725)
;
10726}
10727
10728void CGOpenMPSIMDRuntime::emitTargetDataStandAloneCall(
10729 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
10730 const Expr *Device) {
10731 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10731)
;
10732}
10733
10734void CGOpenMPSIMDRuntime::emitDoacrossInit(CodeGenFunction &CGF,
10735 const OMPLoopDirective &D,
10736 ArrayRef<Expr *> NumIterations) {
10737 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10737)
;
10738}
10739
10740void CGOpenMPSIMDRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
10741 const OMPDependClause *C) {
10742 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10742)
;
10743}
10744
10745const VarDecl *
10746CGOpenMPSIMDRuntime::translateParameter(const FieldDecl *FD,
10747 const VarDecl *NativeParam) const {
10748 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10748)
;
10749}
10750
10751Address
10752CGOpenMPSIMDRuntime::getParameterAddress(CodeGenFunction &CGF,
10753 const VarDecl *NativeParam,
10754 const VarDecl *TargetParam) const {
10755 llvm_unreachable("Not supported in SIMD-only mode")::llvm::llvm_unreachable_internal("Not supported in SIMD-only mode"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp"
, 10755)
;
10756}

/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc

1/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
2|* *|
3|* Attribute classes' definitions *|
4|* *|
5|* Automatically generated file, do not edit! *|
6|* *|
7\*===----------------------------------------------------------------------===*/
8
9#ifndef LLVM_CLANG_ATTR_CLASSES_INC
10#define LLVM_CLANG_ATTR_CLASSES_INC
11
12class AArch64VectorPcsAttr : public InheritableAttr {
13public:
14 static AArch64VectorPcsAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
15 auto *A = new (Ctx) AArch64VectorPcsAttr(Loc, Ctx, 0);
16 A->setImplicit(true);
17 return A;
18 }
19
20 AArch64VectorPcsAttr(SourceRange R, ASTContext &Ctx
21 , unsigned SI
22 )
23 : InheritableAttr(attr::AArch64VectorPcs, R, SI, false, false)
24 {
25 }
26
27 AArch64VectorPcsAttr *clone(ASTContext &C) const;
28 void printPretty(raw_ostream &OS,
29 const PrintingPolicy &Policy) const;
30 const char *getSpelling() const;
31
32
33 static bool classof(const Attr *A) { return A->getKind() == attr::AArch64VectorPcs; }
34};
35
36class AMDGPUFlatWorkGroupSizeAttr : public InheritableAttr {
37Expr * min;
38
39Expr * max;
40
41public:
42 static AMDGPUFlatWorkGroupSizeAttr *CreateImplicit(ASTContext &Ctx, Expr * Min, Expr * Max, SourceRange Loc = SourceRange()) {
43 auto *A = new (Ctx) AMDGPUFlatWorkGroupSizeAttr(Loc, Ctx, Min, Max, 0);
44 A->setImplicit(true);
45 return A;
46 }
47
48 AMDGPUFlatWorkGroupSizeAttr(SourceRange R, ASTContext &Ctx
49 , Expr * Min
50 , Expr * Max
51 , unsigned SI
52 )
53 : InheritableAttr(attr::AMDGPUFlatWorkGroupSize, R, SI, false, false)
54 , min(Min)
55 , max(Max)
56 {
57 }
58
59 AMDGPUFlatWorkGroupSizeAttr *clone(ASTContext &C) const;
60 void printPretty(raw_ostream &OS,
61 const PrintingPolicy &Policy) const;
62 const char *getSpelling() const;
63 Expr * getMin() const {
64 return min;
65 }
66
67 Expr * getMax() const {
68 return max;
69 }
70
71
72
73 static bool classof(const Attr *A) { return A->getKind() == attr::AMDGPUFlatWorkGroupSize; }
74};
75
76class AMDGPUNumSGPRAttr : public InheritableAttr {
77unsigned numSGPR;
78
79public:
80 static AMDGPUNumSGPRAttr *CreateImplicit(ASTContext &Ctx, unsigned NumSGPR, SourceRange Loc = SourceRange()) {
81 auto *A = new (Ctx) AMDGPUNumSGPRAttr(Loc, Ctx, NumSGPR, 0);
82 A->setImplicit(true);
83 return A;
84 }
85
86 AMDGPUNumSGPRAttr(SourceRange R, ASTContext &Ctx
87 , unsigned NumSGPR
88 , unsigned SI
89 )
90 : InheritableAttr(attr::AMDGPUNumSGPR, R, SI, false, false)
91 , numSGPR(NumSGPR)
92 {
93 }
94
95 AMDGPUNumSGPRAttr *clone(ASTContext &C) const;
96 void printPretty(raw_ostream &OS,
97 const PrintingPolicy &Policy) const;
98 const char *getSpelling() const;
99 unsigned getNumSGPR() const {
100 return numSGPR;
101 }
102
103
104
105 static bool classof(const Attr *A) { return A->getKind() == attr::AMDGPUNumSGPR; }
106};
107
108class AMDGPUNumVGPRAttr : public InheritableAttr {
109unsigned numVGPR;
110
111public:
112 static AMDGPUNumVGPRAttr *CreateImplicit(ASTContext &Ctx, unsigned NumVGPR, SourceRange Loc = SourceRange()) {
113 auto *A = new (Ctx) AMDGPUNumVGPRAttr(Loc, Ctx, NumVGPR, 0);
114 A->setImplicit(true);
115 return A;
116 }
117
118 AMDGPUNumVGPRAttr(SourceRange R, ASTContext &Ctx
119 , unsigned NumVGPR
120 , unsigned SI
121 )
122 : InheritableAttr(attr::AMDGPUNumVGPR, R, SI, false, false)
123 , numVGPR(NumVGPR)
124 {
125 }
126
127 AMDGPUNumVGPRAttr *clone(ASTContext &C) const;
128 void printPretty(raw_ostream &OS,
129 const PrintingPolicy &Policy) const;
130 const char *getSpelling() const;
131 unsigned getNumVGPR() const {
132 return numVGPR;
133 }
134
135
136
137 static bool classof(const Attr *A) { return A->getKind() == attr::AMDGPUNumVGPR; }
138};
139
140class AMDGPUWavesPerEUAttr : public InheritableAttr {
141Expr * min;
142
143Expr * max;
144
145public:
146 static AMDGPUWavesPerEUAttr *CreateImplicit(ASTContext &Ctx, Expr * Min, Expr * Max, SourceRange Loc = SourceRange()) {
147 auto *A = new (Ctx) AMDGPUWavesPerEUAttr(Loc, Ctx, Min, Max, 0);
148 A->setImplicit(true);
149 return A;
150 }
151
152 AMDGPUWavesPerEUAttr(SourceRange R, ASTContext &Ctx
153 , Expr * Min
154 , Expr * Max
155 , unsigned SI
156 )
157 : InheritableAttr(attr::AMDGPUWavesPerEU, R, SI, false, false)
158 , min(Min)
159 , max(Max)
160 {
161 }
162
163 AMDGPUWavesPerEUAttr(SourceRange R, ASTContext &Ctx
164 , Expr * Min
165 , unsigned SI
166 )
167 : InheritableAttr(attr::AMDGPUWavesPerEU, R, SI, false, false)
168 , min(Min)
169 , max()
170 {
171 }
172
173 AMDGPUWavesPerEUAttr *clone(ASTContext &C) const;
174 void printPretty(raw_ostream &OS,
175 const PrintingPolicy &Policy) const;
176 const char *getSpelling() const;
177 Expr * getMin() const {
178 return min;
179 }
180
181 Expr * getMax() const {
182 return max;
183 }
184
185
186
187 static bool classof(const Attr *A) { return A->getKind() == attr::AMDGPUWavesPerEU; }
188};
189
190class ARMInterruptAttr : public InheritableAttr {
191public:
192 enum InterruptType {
193 IRQ,
194 FIQ,
195 SWI,
196 ABORT,
197 UNDEF,
198 Generic
199 };
200private:
201 InterruptType interrupt;
202
203public:
204 static ARMInterruptAttr *CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, SourceRange Loc = SourceRange()) {
205 auto *A = new (Ctx) ARMInterruptAttr(Loc, Ctx, Interrupt, 0);
206 A->setImplicit(true);
207 return A;
208 }
209
210 ARMInterruptAttr(SourceRange R, ASTContext &Ctx
211 , InterruptType Interrupt
212 , unsigned SI
213 )
214 : InheritableAttr(attr::ARMInterrupt, R, SI, false, false)
215 , interrupt(Interrupt)
216 {
217 }
218
219 ARMInterruptAttr(SourceRange R, ASTContext &Ctx
220 , unsigned SI
221 )
222 : InheritableAttr(attr::ARMInterrupt, R, SI, false, false)
223 , interrupt(InterruptType(0))
224 {
225 }
226
227 ARMInterruptAttr *clone(ASTContext &C) const;
228 void printPretty(raw_ostream &OS,
229 const PrintingPolicy &Policy) const;
230 const char *getSpelling() const;
231 InterruptType getInterrupt() const {
232 return interrupt;
233 }
234
235 static bool ConvertStrToInterruptType(StringRef Val, InterruptType &Out) {
236 Optional<InterruptType> R = llvm::StringSwitch<Optional<InterruptType>>(Val)
237 .Case("IRQ", ARMInterruptAttr::IRQ)
238 .Case("FIQ", ARMInterruptAttr::FIQ)
239 .Case("SWI", ARMInterruptAttr::SWI)
240 .Case("ABORT", ARMInterruptAttr::ABORT)
241 .Case("UNDEF", ARMInterruptAttr::UNDEF)
242 .Case("", ARMInterruptAttr::Generic)
243 .Default(Optional<InterruptType>());
244 if (R) {
245 Out = *R;
246 return true;
247 }
248 return false;
249 }
250
251 static const char *ConvertInterruptTypeToStr(InterruptType Val) {
252 switch(Val) {
253 case ARMInterruptAttr::IRQ: return "IRQ";
254 case ARMInterruptAttr::FIQ: return "FIQ";
255 case ARMInterruptAttr::SWI: return "SWI";
256 case ARMInterruptAttr::ABORT: return "ABORT";
257 case ARMInterruptAttr::UNDEF: return "UNDEF";
258 case ARMInterruptAttr::Generic: return "";
259 }
260 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 260)
;
261 }
262
263
264 static bool classof(const Attr *A) { return A->getKind() == attr::ARMInterrupt; }
265};
266
267class AVRInterruptAttr : public InheritableAttr {
268public:
269 static AVRInterruptAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
270 auto *A = new (Ctx) AVRInterruptAttr(Loc, Ctx, 0);
271 A->setImplicit(true);
272 return A;
273 }
274
275 AVRInterruptAttr(SourceRange R, ASTContext &Ctx
276 , unsigned SI
277 )
278 : InheritableAttr(attr::AVRInterrupt, R, SI, false, false)
279 {
280 }
281
282 AVRInterruptAttr *clone(ASTContext &C) const;
283 void printPretty(raw_ostream &OS,
284 const PrintingPolicy &Policy) const;
285 const char *getSpelling() const;
286
287
288 static bool classof(const Attr *A) { return A->getKind() == attr::AVRInterrupt; }
289};
290
291class AVRSignalAttr : public InheritableAttr {
292public:
293 static AVRSignalAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
294 auto *A = new (Ctx) AVRSignalAttr(Loc, Ctx, 0);
295 A->setImplicit(true);
296 return A;
297 }
298
299 AVRSignalAttr(SourceRange R, ASTContext &Ctx
300 , unsigned SI
301 )
302 : InheritableAttr(attr::AVRSignal, R, SI, false, false)
303 {
304 }
305
306 AVRSignalAttr *clone(ASTContext &C) const;
307 void printPretty(raw_ostream &OS,
308 const PrintingPolicy &Policy) const;
309 const char *getSpelling() const;
310
311
312 static bool classof(const Attr *A) { return A->getKind() == attr::AVRSignal; }
313};
314
315class AbiTagAttr : public Attr {
316 unsigned tags_Size;
317 StringRef *tags_;
318
319public:
320 static AbiTagAttr *CreateImplicit(ASTContext &Ctx, StringRef *Tags, unsigned TagsSize, SourceRange Loc = SourceRange()) {
321 auto *A = new (Ctx) AbiTagAttr(Loc, Ctx, Tags, TagsSize, 0);
322 A->setImplicit(true);
323 return A;
324 }
325
326 AbiTagAttr(SourceRange R, ASTContext &Ctx
327 , StringRef *Tags, unsigned TagsSize
328 , unsigned SI
329 )
330 : Attr(attr::AbiTag, R, SI, false)
331 , tags_Size(TagsSize), tags_(new (Ctx, 16) StringRef[tags_Size])
332 {
333 for (size_t I = 0, E = tags_Size; I != E;
334 ++I) {
335 StringRef Ref = Tags[I];
336 if (!Ref.empty()) {
337 char *Mem = new (Ctx, 1) char[Ref.size()];
338 std::memcpy(Mem, Ref.data(), Ref.size());
339 tags_[I] = StringRef(Mem, Ref.size());
340 }
341 }
342 }
343
344 AbiTagAttr(SourceRange R, ASTContext &Ctx
345 , unsigned SI
346 )
347 : Attr(attr::AbiTag, R, SI, false)
348 , tags_Size(0), tags_(nullptr)
349 {
350 }
351
352 AbiTagAttr *clone(ASTContext &C) const;
353 void printPretty(raw_ostream &OS,
354 const PrintingPolicy &Policy) const;
355 const char *getSpelling() const;
356 typedef StringRef* tags_iterator;
357 tags_iterator tags_begin() const { return tags_; }
358 tags_iterator tags_end() const { return tags_ + tags_Size; }
359 unsigned tags_size() const { return tags_Size; }
360 llvm::iterator_range<tags_iterator> tags() const { return llvm::make_range(tags_begin(), tags_end()); }
361
362
363
364
365 static bool classof(const Attr *A) { return A->getKind() == attr::AbiTag; }
366};
367
368class AcquireCapabilityAttr : public InheritableAttr {
369 unsigned args_Size;
370 Expr * *args_;
371
372public:
373 enum Spelling {
374 GNU_acquire_capability = 0,
375 CXX11_clang_acquire_capability = 1,
376 GNU_acquire_shared_capability = 2,
377 CXX11_clang_acquire_shared_capability = 3,
378 GNU_exclusive_lock_function = 4,
379 GNU_shared_lock_function = 5
380 };
381
382 static AcquireCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
383 auto *A = new (Ctx) AcquireCapabilityAttr(Loc, Ctx, Args, ArgsSize, S);
384 A->setImplicit(true);
385 return A;
386 }
387
388 AcquireCapabilityAttr(SourceRange R, ASTContext &Ctx
389 , Expr * *Args, unsigned ArgsSize
390 , unsigned SI
391 )
392 : InheritableAttr(attr::AcquireCapability, R, SI, true, true)
393 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
394 {
395 std::copy(Args, Args + args_Size, args_);
396 }
397
398 AcquireCapabilityAttr(SourceRange R, ASTContext &Ctx
399 , unsigned SI
400 )
401 : InheritableAttr(attr::AcquireCapability, R, SI, true, true)
402 , args_Size(0), args_(nullptr)
403 {
404 }
405
406 AcquireCapabilityAttr *clone(ASTContext &C) const;
407 void printPretty(raw_ostream &OS,
408 const PrintingPolicy &Policy) const;
409 const char *getSpelling() const;
410 Spelling getSemanticSpelling() const {
411 switch (SpellingListIndex) {
412 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 412)
;
413 case 0: return GNU_acquire_capability;
414 case 1: return CXX11_clang_acquire_capability;
415 case 2: return GNU_acquire_shared_capability;
416 case 3: return CXX11_clang_acquire_shared_capability;
417 case 4: return GNU_exclusive_lock_function;
418 case 5: return GNU_shared_lock_function;
419 }
420 }
421 bool isShared() const { return SpellingListIndex == 2 ||
422 SpellingListIndex == 3 ||
423 SpellingListIndex == 5; }
424 typedef Expr ** args_iterator;
425 args_iterator args_begin() const { return args_; }
426 args_iterator args_end() const { return args_ + args_Size; }
427 unsigned args_size() const { return args_Size; }
428 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
429
430
431
432
433 static bool classof(const Attr *A) { return A->getKind() == attr::AcquireCapability; }
434};
435
436class AcquiredAfterAttr : public InheritableAttr {
437 unsigned args_Size;
438 Expr * *args_;
439
440public:
441 static AcquiredAfterAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
442 auto *A = new (Ctx) AcquiredAfterAttr(Loc, Ctx, Args, ArgsSize, 0);
443 A->setImplicit(true);
444 return A;
445 }
446
447 AcquiredAfterAttr(SourceRange R, ASTContext &Ctx
448 , Expr * *Args, unsigned ArgsSize
449 , unsigned SI
450 )
451 : InheritableAttr(attr::AcquiredAfter, R, SI, true, true)
452 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
453 {
454 std::copy(Args, Args + args_Size, args_);
455 }
456
457 AcquiredAfterAttr(SourceRange R, ASTContext &Ctx
458 , unsigned SI
459 )
460 : InheritableAttr(attr::AcquiredAfter, R, SI, true, true)
461 , args_Size(0), args_(nullptr)
462 {
463 }
464
465 AcquiredAfterAttr *clone(ASTContext &C) const;
466 void printPretty(raw_ostream &OS,
467 const PrintingPolicy &Policy) const;
468 const char *getSpelling() const;
469 typedef Expr ** args_iterator;
470 args_iterator args_begin() const { return args_; }
471 args_iterator args_end() const { return args_ + args_Size; }
472 unsigned args_size() const { return args_Size; }
473 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
474
475
476
477
478 static bool classof(const Attr *A) { return A->getKind() == attr::AcquiredAfter; }
479};
480
481class AcquiredBeforeAttr : public InheritableAttr {
482 unsigned args_Size;
483 Expr * *args_;
484
485public:
486 static AcquiredBeforeAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
487 auto *A = new (Ctx) AcquiredBeforeAttr(Loc, Ctx, Args, ArgsSize, 0);
488 A->setImplicit(true);
489 return A;
490 }
491
492 AcquiredBeforeAttr(SourceRange R, ASTContext &Ctx
493 , Expr * *Args, unsigned ArgsSize
494 , unsigned SI
495 )
496 : InheritableAttr(attr::AcquiredBefore, R, SI, true, true)
497 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
498 {
499 std::copy(Args, Args + args_Size, args_);
500 }
501
502 AcquiredBeforeAttr(SourceRange R, ASTContext &Ctx
503 , unsigned SI
504 )
505 : InheritableAttr(attr::AcquiredBefore, R, SI, true, true)
506 , args_Size(0), args_(nullptr)
507 {
508 }
509
510 AcquiredBeforeAttr *clone(ASTContext &C) const;
511 void printPretty(raw_ostream &OS,
512 const PrintingPolicy &Policy) const;
513 const char *getSpelling() const;
514 typedef Expr ** args_iterator;
515 args_iterator args_begin() const { return args_; }
516 args_iterator args_end() const { return args_ + args_Size; }
517 unsigned args_size() const { return args_Size; }
518 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
519
520
521
522
523 static bool classof(const Attr *A) { return A->getKind() == attr::AcquiredBefore; }
524};
525
526class AddressSpaceAttr : public TypeAttr {
527int addressSpace;
528
529public:
530 static AddressSpaceAttr *CreateImplicit(ASTContext &Ctx, int AddressSpace, SourceRange Loc = SourceRange()) {
531 auto *A = new (Ctx) AddressSpaceAttr(Loc, Ctx, AddressSpace, 0);
532 A->setImplicit(true);
533 return A;
534 }
535
536 AddressSpaceAttr(SourceRange R, ASTContext &Ctx
537 , int AddressSpace
538 , unsigned SI
539 )
540 : TypeAttr(attr::AddressSpace, R, SI, false)
541 , addressSpace(AddressSpace)
542 {
543 }
544
545 AddressSpaceAttr *clone(ASTContext &C) const;
546 void printPretty(raw_ostream &OS,
547 const PrintingPolicy &Policy) const;
548 const char *getSpelling() const;
549 int getAddressSpace() const {
550 return addressSpace;
551 }
552
553
554
555 static bool classof(const Attr *A) { return A->getKind() == attr::AddressSpace; }
556};
557
558class AliasAttr : public Attr {
559unsigned aliaseeLength;
560char *aliasee;
561
562public:
563 static AliasAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Loc = SourceRange()) {
564 auto *A = new (Ctx) AliasAttr(Loc, Ctx, Aliasee, 0);
565 A->setImplicit(true);
566 return A;
567 }
568
569 AliasAttr(SourceRange R, ASTContext &Ctx
570 , llvm::StringRef Aliasee
571 , unsigned SI
572 )
573 : Attr(attr::Alias, R, SI, false)
574 , aliaseeLength(Aliasee.size()),aliasee(new (Ctx, 1) char[aliaseeLength])
575 {
576 if (!Aliasee.empty())
577 std::memcpy(aliasee, Aliasee.data(), aliaseeLength);
578 }
579
580 AliasAttr *clone(ASTContext &C) const;
581 void printPretty(raw_ostream &OS,
582 const PrintingPolicy &Policy) const;
583 const char *getSpelling() const;
584 llvm::StringRef getAliasee() const {
585 return llvm::StringRef(aliasee, aliaseeLength);
586 }
587 unsigned getAliaseeLength() const {
588 return aliaseeLength;
589 }
590 void setAliasee(ASTContext &C, llvm::StringRef S) {
591 aliaseeLength = S.size();
592 this->aliasee = new (C, 1) char [aliaseeLength];
593 if (!S.empty())
594 std::memcpy(this->aliasee, S.data(), aliaseeLength);
595 }
596
597
598
599 static bool classof(const Attr *A) { return A->getKind() == attr::Alias; }
600};
601
602class AlignMac68kAttr : public InheritableAttr {
603public:
604 static AlignMac68kAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
605 auto *A = new (Ctx) AlignMac68kAttr(Loc, Ctx, 0);
606 A->setImplicit(true);
607 return A;
608 }
609
610 AlignMac68kAttr(SourceRange R, ASTContext &Ctx
611 , unsigned SI
612 )
613 : InheritableAttr(attr::AlignMac68k, R, SI, false, false)
614 {
615 }
616
617 AlignMac68kAttr *clone(ASTContext &C) const;
618 void printPretty(raw_ostream &OS,
619 const PrintingPolicy &Policy) const;
620 const char *getSpelling() const;
621
622
623 static bool classof(const Attr *A) { return A->getKind() == attr::AlignMac68k; }
624};
625
626class AlignValueAttr : public Attr {
627Expr * alignment;
628
629public:
630 static AlignValueAttr *CreateImplicit(ASTContext &Ctx, Expr * Alignment, SourceRange Loc = SourceRange()) {
631 auto *A = new (Ctx) AlignValueAttr(Loc, Ctx, Alignment, 0);
632 A->setImplicit(true);
633 return A;
634 }
635
636 AlignValueAttr(SourceRange R, ASTContext &Ctx
637 , Expr * Alignment
638 , unsigned SI
639 )
640 : Attr(attr::AlignValue, R, SI, false)
641 , alignment(Alignment)
642 {
643 }
644
645 AlignValueAttr *clone(ASTContext &C) const;
646 void printPretty(raw_ostream &OS,
647 const PrintingPolicy &Policy) const;
648 const char *getSpelling() const;
649 Expr * getAlignment() const {
650 return alignment;
651 }
652
653
654
655 static bool classof(const Attr *A) { return A->getKind() == attr::AlignValue; }
656};
657
658class AlignedAttr : public InheritableAttr {
659bool isalignmentExpr;
660union {
661Expr *alignmentExpr;
662TypeSourceInfo *alignmentType;
663};
664
665public:
666 enum Spelling {
667 GNU_aligned = 0,
668 CXX11_gnu_aligned = 1,
669 Declspec_align = 2,
670 Keyword_alignas = 3,
671 Keyword_Alignas = 4
672 };
673
674 static AlignedAttr *CreateImplicit(ASTContext &Ctx, Spelling S, bool IsAlignmentExpr, void *Alignment, SourceRange Loc = SourceRange()) {
675 auto *A = new (Ctx) AlignedAttr(Loc, Ctx, IsAlignmentExpr, Alignment, S);
676 A->setImplicit(true);
677 return A;
678 }
679
680 AlignedAttr(SourceRange R, ASTContext &Ctx
681 , bool IsAlignmentExpr, void *Alignment
682 , unsigned SI
683 )
684 : InheritableAttr(attr::Aligned, R, SI, false, false)
685 , isalignmentExpr(IsAlignmentExpr)
686 {
687 if (isalignmentExpr)
688 alignmentExpr = reinterpret_cast<Expr *>(Alignment);
689 else
690 alignmentType = reinterpret_cast<TypeSourceInfo *>(Alignment);
691 }
692
693 AlignedAttr(SourceRange R, ASTContext &Ctx
694 , unsigned SI
695 )
696 : InheritableAttr(attr::Aligned, R, SI, false, false)
697 , isalignmentExpr(false)
698 {
699 }
700
701 AlignedAttr *clone(ASTContext &C) const;
702 void printPretty(raw_ostream &OS,
703 const PrintingPolicy &Policy) const;
704 const char *getSpelling() const;
705 Spelling getSemanticSpelling() const {
706 switch (SpellingListIndex) {
707 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 707)
;
708 case 0: return GNU_aligned;
709 case 1: return CXX11_gnu_aligned;
710 case 2: return Declspec_align;
711 case 3: return Keyword_alignas;
712 case 4: return Keyword_Alignas;
713 }
714 }
715 bool isGNU() const { return SpellingListIndex == 0 ||
716 SpellingListIndex == 1; }
717 bool isC11() const { return SpellingListIndex == 4; }
718 bool isAlignas() const { return SpellingListIndex == 3 ||
719 SpellingListIndex == 4; }
720 bool isDeclspec() const { return SpellingListIndex == 2; }
721 bool isAlignmentDependent() const;
722 unsigned getAlignment(ASTContext &Ctx) const;
723 bool isAlignmentExpr() const {
724 return isalignmentExpr;
725 }
726 Expr *getAlignmentExpr() const {
727 assert(isalignmentExpr)((isalignmentExpr) ? static_cast<void> (0) : __assert_fail
("isalignmentExpr", "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 727, __PRETTY_FUNCTION__))
;
728 return alignmentExpr;
729 }
730 TypeSourceInfo *getAlignmentType() const {
731 assert(!isalignmentExpr)((!isalignmentExpr) ? static_cast<void> (0) : __assert_fail
("!isalignmentExpr", "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 731, __PRETTY_FUNCTION__))
;
732 return alignmentType;
733 }
734
735
736
737 static bool classof(const Attr *A) { return A->getKind() == attr::Aligned; }
738};
739
740class AllocAlignAttr : public InheritableAttr {
741ParamIdx paramIndex;
742
743public:
744 static AllocAlignAttr *CreateImplicit(ASTContext &Ctx, ParamIdx ParamIndex, SourceRange Loc = SourceRange()) {
745 auto *A = new (Ctx) AllocAlignAttr(Loc, Ctx, ParamIndex, 0);
746 A->setImplicit(true);
747 return A;
748 }
749
750 AllocAlignAttr(SourceRange R, ASTContext &Ctx
751 , ParamIdx ParamIndex
752 , unsigned SI
753 )
754 : InheritableAttr(attr::AllocAlign, R, SI, false, false)
755 , paramIndex(ParamIndex)
756 {
757 }
758
759 AllocAlignAttr *clone(ASTContext &C) const;
760 void printPretty(raw_ostream &OS,
761 const PrintingPolicy &Policy) const;
762 const char *getSpelling() const;
763 ParamIdx getParamIndex() const {
764 return paramIndex;
765 }
766
767
768
769 static bool classof(const Attr *A) { return A->getKind() == attr::AllocAlign; }
770};
771
772class AllocSizeAttr : public InheritableAttr {
773ParamIdx elemSizeParam;
774
775ParamIdx numElemsParam;
776
777public:
778 static AllocSizeAttr *CreateImplicit(ASTContext &Ctx, ParamIdx ElemSizeParam, ParamIdx NumElemsParam, SourceRange Loc = SourceRange()) {
779 auto *A = new (Ctx) AllocSizeAttr(Loc, Ctx, ElemSizeParam, NumElemsParam, 0);
780 A->setImplicit(true);
781 return A;
782 }
783
784 AllocSizeAttr(SourceRange R, ASTContext &Ctx
785 , ParamIdx ElemSizeParam
786 , ParamIdx NumElemsParam
787 , unsigned SI
788 )
789 : InheritableAttr(attr::AllocSize, R, SI, false, false)
790 , elemSizeParam(ElemSizeParam)
791 , numElemsParam(NumElemsParam)
792 {
793 }
794
795 AllocSizeAttr(SourceRange R, ASTContext &Ctx
796 , ParamIdx ElemSizeParam
797 , unsigned SI
798 )
799 : InheritableAttr(attr::AllocSize, R, SI, false, false)
800 , elemSizeParam(ElemSizeParam)
801 , numElemsParam()
802 {
803 }
804
805 AllocSizeAttr *clone(ASTContext &C) const;
806 void printPretty(raw_ostream &OS,
807 const PrintingPolicy &Policy) const;
808 const char *getSpelling() const;
809 ParamIdx getElemSizeParam() const {
810 return elemSizeParam;
811 }
812
813 ParamIdx getNumElemsParam() const {
814 return numElemsParam;
815 }
816
817
818
819 static bool classof(const Attr *A) { return A->getKind() == attr::AllocSize; }
820};
821
822class AlwaysDestroyAttr : public InheritableAttr {
823public:
824 static AlwaysDestroyAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
825 auto *A = new (Ctx) AlwaysDestroyAttr(Loc, Ctx, 0);
826 A->setImplicit(true);
827 return A;
828 }
829
830 AlwaysDestroyAttr(SourceRange R, ASTContext &Ctx
831 , unsigned SI
832 )
833 : InheritableAttr(attr::AlwaysDestroy, R, SI, false, false)
834 {
835 }
836
837 AlwaysDestroyAttr *clone(ASTContext &C) const;
838 void printPretty(raw_ostream &OS,
839 const PrintingPolicy &Policy) const;
840 const char *getSpelling() const;
841
842
843 static bool classof(const Attr *A) { return A->getKind() == attr::AlwaysDestroy; }
844};
845
846class AlwaysInlineAttr : public InheritableAttr {
847public:
848 enum Spelling {
849 GNU_always_inline = 0,
850 CXX11_gnu_always_inline = 1,
851 Keyword_forceinline = 2
852 };
853
854 static AlwaysInlineAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
855 auto *A = new (Ctx) AlwaysInlineAttr(Loc, Ctx, S);
856 A->setImplicit(true);
857 return A;
858 }
859
860 AlwaysInlineAttr(SourceRange R, ASTContext &Ctx
861 , unsigned SI
862 )
863 : InheritableAttr(attr::AlwaysInline, R, SI, false, false)
864 {
865 }
866
867 AlwaysInlineAttr *clone(ASTContext &C) const;
868 void printPretty(raw_ostream &OS,
869 const PrintingPolicy &Policy) const;
870 const char *getSpelling() const;
871 Spelling getSemanticSpelling() const {
872 switch (SpellingListIndex) {
873 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 873)
;
874 case 0: return GNU_always_inline;
875 case 1: return CXX11_gnu_always_inline;
876 case 2: return Keyword_forceinline;
877 }
878 }
879
880
881 static bool classof(const Attr *A) { return A->getKind() == attr::AlwaysInline; }
882};
883
884class AnalyzerNoReturnAttr : public InheritableAttr {
885public:
886 static AnalyzerNoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
887 auto *A = new (Ctx) AnalyzerNoReturnAttr(Loc, Ctx, 0);
888 A->setImplicit(true);
889 return A;
890 }
891
892 AnalyzerNoReturnAttr(SourceRange R, ASTContext &Ctx
893 , unsigned SI
894 )
895 : InheritableAttr(attr::AnalyzerNoReturn, R, SI, false, false)
896 {
897 }
898
899 AnalyzerNoReturnAttr *clone(ASTContext &C) const;
900 void printPretty(raw_ostream &OS,
901 const PrintingPolicy &Policy) const;
902 const char *getSpelling() const;
903
904
905 static bool classof(const Attr *A) { return A->getKind() == attr::AnalyzerNoReturn; }
906};
907
908class AnnotateAttr : public InheritableParamAttr {
909unsigned annotationLength;
910char *annotation;
911
912public:
913 static AnnotateAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Annotation, SourceRange Loc = SourceRange()) {
914 auto *A = new (Ctx) AnnotateAttr(Loc, Ctx, Annotation, 0);
915 A->setImplicit(true);
916 return A;
917 }
918
919 AnnotateAttr(SourceRange R, ASTContext &Ctx
920 , llvm::StringRef Annotation
921 , unsigned SI
922 )
923 : InheritableParamAttr(attr::Annotate, R, SI, false, false)
924 , annotationLength(Annotation.size()),annotation(new (Ctx, 1) char[annotationLength])
925 {
926 if (!Annotation.empty())
927 std::memcpy(annotation, Annotation.data(), annotationLength);
928 }
929
930 AnnotateAttr *clone(ASTContext &C) const;
931 void printPretty(raw_ostream &OS,
932 const PrintingPolicy &Policy) const;
933 const char *getSpelling() const;
934 llvm::StringRef getAnnotation() const {
935 return llvm::StringRef(annotation, annotationLength);
936 }
937 unsigned getAnnotationLength() const {
938 return annotationLength;
939 }
940 void setAnnotation(ASTContext &C, llvm::StringRef S) {
941 annotationLength = S.size();
942 this->annotation = new (C, 1) char [annotationLength];
943 if (!S.empty())
944 std::memcpy(this->annotation, S.data(), annotationLength);
945 }
946
947
948
949 static bool classof(const Attr *A) { return A->getKind() == attr::Annotate; }
950};
951
952class AnyX86InterruptAttr : public InheritableAttr {
953public:
954 static AnyX86InterruptAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
955 auto *A = new (Ctx) AnyX86InterruptAttr(Loc, Ctx, 0);
956 A->setImplicit(true);
957 return A;
958 }
959
960 AnyX86InterruptAttr(SourceRange R, ASTContext &Ctx
961 , unsigned SI
962 )
963 : InheritableAttr(attr::AnyX86Interrupt, R, SI, false, false)
964 {
965 }
966
967 AnyX86InterruptAttr *clone(ASTContext &C) const;
968 void printPretty(raw_ostream &OS,
969 const PrintingPolicy &Policy) const;
970 const char *getSpelling() const;
971
972
973 static bool classof(const Attr *A) { return A->getKind() == attr::AnyX86Interrupt; }
974};
975
976class AnyX86NoCallerSavedRegistersAttr : public InheritableAttr {
977public:
978 static AnyX86NoCallerSavedRegistersAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
979 auto *A = new (Ctx) AnyX86NoCallerSavedRegistersAttr(Loc, Ctx, 0);
980 A->setImplicit(true);
981 return A;
982 }
983
984 AnyX86NoCallerSavedRegistersAttr(SourceRange R, ASTContext &Ctx
985 , unsigned SI
986 )
987 : InheritableAttr(attr::AnyX86NoCallerSavedRegisters, R, SI, false, false)
988 {
989 }
990
991 AnyX86NoCallerSavedRegistersAttr *clone(ASTContext &C) const;
992 void printPretty(raw_ostream &OS,
993 const PrintingPolicy &Policy) const;
994 const char *getSpelling() const;
995
996
997 static bool classof(const Attr *A) { return A->getKind() == attr::AnyX86NoCallerSavedRegisters; }
998};
999
1000class AnyX86NoCfCheckAttr : public InheritableAttr {
1001public:
1002 static AnyX86NoCfCheckAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1003 auto *A = new (Ctx) AnyX86NoCfCheckAttr(Loc, Ctx, 0);
1004 A->setImplicit(true);
1005 return A;
1006 }
1007
1008 AnyX86NoCfCheckAttr(SourceRange R, ASTContext &Ctx
1009 , unsigned SI
1010 )
1011 : InheritableAttr(attr::AnyX86NoCfCheck, R, SI, false, false)
1012 {
1013 }
1014
1015 AnyX86NoCfCheckAttr *clone(ASTContext &C) const;
1016 void printPretty(raw_ostream &OS,
1017 const PrintingPolicy &Policy) const;
1018 const char *getSpelling() const;
1019
1020
1021 static bool classof(const Attr *A) { return A->getKind() == attr::AnyX86NoCfCheck; }
1022};
1023
1024class ArcWeakrefUnavailableAttr : public InheritableAttr {
1025public:
1026 static ArcWeakrefUnavailableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1027 auto *A = new (Ctx) ArcWeakrefUnavailableAttr(Loc, Ctx, 0);
1028 A->setImplicit(true);
1029 return A;
1030 }
1031
1032 ArcWeakrefUnavailableAttr(SourceRange R, ASTContext &Ctx
1033 , unsigned SI
1034 )
1035 : InheritableAttr(attr::ArcWeakrefUnavailable, R, SI, false, false)
1036 {
1037 }
1038
1039 ArcWeakrefUnavailableAttr *clone(ASTContext &C) const;
1040 void printPretty(raw_ostream &OS,
1041 const PrintingPolicy &Policy) const;
1042 const char *getSpelling() const;
1043
1044
1045 static bool classof(const Attr *A) { return A->getKind() == attr::ArcWeakrefUnavailable; }
1046};
1047
1048class ArgumentWithTypeTagAttr : public InheritableAttr {
1049IdentifierInfo * argumentKind;
1050
1051ParamIdx argumentIdx;
1052
1053ParamIdx typeTagIdx;
1054
1055bool isPointer;
1056
1057public:
1058 enum Spelling {
1059 GNU_argument_with_type_tag = 0,
1060 CXX11_clang_argument_with_type_tag = 1,
1061 C2x_clang_argument_with_type_tag = 2,
1062 GNU_pointer_with_type_tag = 3,
1063 CXX11_clang_pointer_with_type_tag = 4,
1064 C2x_clang_pointer_with_type_tag = 5
1065 };
1066
1067 static ArgumentWithTypeTagAttr *CreateImplicit(ASTContext &Ctx, Spelling S, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, bool IsPointer, SourceRange Loc = SourceRange()) {
1068 auto *A = new (Ctx) ArgumentWithTypeTagAttr(Loc, Ctx, ArgumentKind, ArgumentIdx, TypeTagIdx, IsPointer, S);
1069 A->setImplicit(true);
1070 return A;
1071 }
1072
1073 static ArgumentWithTypeTagAttr *CreateImplicit(ASTContext &Ctx, Spelling S, IdentifierInfo * ArgumentKind, ParamIdx ArgumentIdx, ParamIdx TypeTagIdx, SourceRange Loc = SourceRange()) {
1074 auto *A = new (Ctx) ArgumentWithTypeTagAttr(Loc, Ctx, ArgumentKind, ArgumentIdx, TypeTagIdx, S);
1075 A->setImplicit(true);
1076 return A;
1077 }
1078
1079 ArgumentWithTypeTagAttr(SourceRange R, ASTContext &Ctx
1080 , IdentifierInfo * ArgumentKind
1081 , ParamIdx ArgumentIdx
1082 , ParamIdx TypeTagIdx
1083 , bool IsPointer
1084 , unsigned SI
1085 )
1086 : InheritableAttr(attr::ArgumentWithTypeTag, R, SI, false, false)
1087 , argumentKind(ArgumentKind)
1088 , argumentIdx(ArgumentIdx)
1089 , typeTagIdx(TypeTagIdx)
1090 , isPointer(IsPointer)
1091 {
1092 }
1093
1094 ArgumentWithTypeTagAttr(SourceRange R, ASTContext &Ctx
1095 , IdentifierInfo * ArgumentKind
1096 , ParamIdx ArgumentIdx
1097 , ParamIdx TypeTagIdx
1098 , unsigned SI
1099 )
1100 : InheritableAttr(attr::ArgumentWithTypeTag, R, SI, false, false)
1101 , argumentKind(ArgumentKind)
1102 , argumentIdx(ArgumentIdx)
1103 , typeTagIdx(TypeTagIdx)
1104 , isPointer()
1105 {
1106 }
1107
1108 ArgumentWithTypeTagAttr *clone(ASTContext &C) const;
1109 void printPretty(raw_ostream &OS,
1110 const PrintingPolicy &Policy) const;
1111 const char *getSpelling() const;
1112 Spelling getSemanticSpelling() const {
1113 switch (SpellingListIndex) {
1114 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 1114)
;
1115 case 0: return GNU_argument_with_type_tag;
1116 case 1: return CXX11_clang_argument_with_type_tag;
1117 case 2: return C2x_clang_argument_with_type_tag;
1118 case 3: return GNU_pointer_with_type_tag;
1119 case 4: return CXX11_clang_pointer_with_type_tag;
1120 case 5: return C2x_clang_pointer_with_type_tag;
1121 }
1122 }
1123 IdentifierInfo * getArgumentKind() const {
1124 return argumentKind;
1125 }
1126
1127 ParamIdx getArgumentIdx() const {
1128 return argumentIdx;
1129 }
1130
1131 ParamIdx getTypeTagIdx() const {
1132 return typeTagIdx;
1133 }
1134
1135 bool getIsPointer() const {
1136 return isPointer;
1137 }
1138
1139
1140
1141 static bool classof(const Attr *A) { return A->getKind() == attr::ArgumentWithTypeTag; }
1142};
1143
1144class ArtificialAttr : public InheritableAttr {
1145public:
1146 static ArtificialAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1147 auto *A = new (Ctx) ArtificialAttr(Loc, Ctx, 0);
1148 A->setImplicit(true);
1149 return A;
1150 }
1151
1152 ArtificialAttr(SourceRange R, ASTContext &Ctx
1153 , unsigned SI
1154 )
1155 : InheritableAttr(attr::Artificial, R, SI, false, false)
1156 {
1157 }
1158
1159 ArtificialAttr *clone(ASTContext &C) const;
1160 void printPretty(raw_ostream &OS,
1161 const PrintingPolicy &Policy) const;
1162 const char *getSpelling() const;
1163
1164
1165 static bool classof(const Attr *A) { return A->getKind() == attr::Artificial; }
1166};
1167
1168class AsmLabelAttr : public InheritableAttr {
1169unsigned labelLength;
1170char *label;
1171
1172public:
1173 static AsmLabelAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Label, SourceRange Loc = SourceRange()) {
1174 auto *A = new (Ctx) AsmLabelAttr(Loc, Ctx, Label, 0);
1175 A->setImplicit(true);
1176 return A;
1177 }
1178
1179 AsmLabelAttr(SourceRange R, ASTContext &Ctx
1180 , llvm::StringRef Label
1181 , unsigned SI
1182 )
1183 : InheritableAttr(attr::AsmLabel, R, SI, false, false)
1184 , labelLength(Label.size()),label(new (Ctx, 1) char[labelLength])
1185 {
1186 if (!Label.empty())
1187 std::memcpy(label, Label.data(), labelLength);
1188 }
1189
1190 AsmLabelAttr *clone(ASTContext &C) const;
1191 void printPretty(raw_ostream &OS,
1192 const PrintingPolicy &Policy) const;
1193 const char *getSpelling() const;
1194 llvm::StringRef getLabel() const {
1195 return llvm::StringRef(label, labelLength);
1196 }
1197 unsigned getLabelLength() const {
1198 return labelLength;
1199 }
1200 void setLabel(ASTContext &C, llvm::StringRef S) {
1201 labelLength = S.size();
1202 this->label = new (C, 1) char [labelLength];
1203 if (!S.empty())
1204 std::memcpy(this->label, S.data(), labelLength);
1205 }
1206
1207
1208
1209 static bool classof(const Attr *A) { return A->getKind() == attr::AsmLabel; }
1210};
1211
1212class AssertCapabilityAttr : public InheritableAttr {
1213 unsigned args_Size;
1214 Expr * *args_;
1215
1216public:
1217 enum Spelling {
1218 GNU_assert_capability = 0,
1219 CXX11_clang_assert_capability = 1,
1220 GNU_assert_shared_capability = 2,
1221 CXX11_clang_assert_shared_capability = 3
1222 };
1223
1224 static AssertCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
1225 auto *A = new (Ctx) AssertCapabilityAttr(Loc, Ctx, Args, ArgsSize, S);
1226 A->setImplicit(true);
1227 return A;
1228 }
1229
1230 AssertCapabilityAttr(SourceRange R, ASTContext &Ctx
1231 , Expr * *Args, unsigned ArgsSize
1232 , unsigned SI
1233 )
1234 : InheritableAttr(attr::AssertCapability, R, SI, true, true)
1235 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
1236 {
1237 std::copy(Args, Args + args_Size, args_);
1238 }
1239
1240 AssertCapabilityAttr(SourceRange R, ASTContext &Ctx
1241 , unsigned SI
1242 )
1243 : InheritableAttr(attr::AssertCapability, R, SI, true, true)
1244 , args_Size(0), args_(nullptr)
1245 {
1246 }
1247
1248 AssertCapabilityAttr *clone(ASTContext &C) const;
1249 void printPretty(raw_ostream &OS,
1250 const PrintingPolicy &Policy) const;
1251 const char *getSpelling() const;
1252 Spelling getSemanticSpelling() const {
1253 switch (SpellingListIndex) {
1254 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 1254)
;
1255 case 0: return GNU_assert_capability;
1256 case 1: return CXX11_clang_assert_capability;
1257 case 2: return GNU_assert_shared_capability;
1258 case 3: return CXX11_clang_assert_shared_capability;
1259 }
1260 }
1261 bool isShared() const { return SpellingListIndex == 2 ||
1262 SpellingListIndex == 3; }
1263 typedef Expr ** args_iterator;
1264 args_iterator args_begin() const { return args_; }
1265 args_iterator args_end() const { return args_ + args_Size; }
1266 unsigned args_size() const { return args_Size; }
1267 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
1268
1269
1270
1271
1272 static bool classof(const Attr *A) { return A->getKind() == attr::AssertCapability; }
1273};
1274
1275class AssertExclusiveLockAttr : public InheritableAttr {
1276 unsigned args_Size;
1277 Expr * *args_;
1278
1279public:
1280 static AssertExclusiveLockAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
1281 auto *A = new (Ctx) AssertExclusiveLockAttr(Loc, Ctx, Args, ArgsSize, 0);
1282 A->setImplicit(true);
1283 return A;
1284 }
1285
1286 AssertExclusiveLockAttr(SourceRange R, ASTContext &Ctx
1287 , Expr * *Args, unsigned ArgsSize
1288 , unsigned SI
1289 )
1290 : InheritableAttr(attr::AssertExclusiveLock, R, SI, true, true)
1291 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
1292 {
1293 std::copy(Args, Args + args_Size, args_);
1294 }
1295
1296 AssertExclusiveLockAttr(SourceRange R, ASTContext &Ctx
1297 , unsigned SI
1298 )
1299 : InheritableAttr(attr::AssertExclusiveLock, R, SI, true, true)
1300 , args_Size(0), args_(nullptr)
1301 {
1302 }
1303
1304 AssertExclusiveLockAttr *clone(ASTContext &C) const;
1305 void printPretty(raw_ostream &OS,
1306 const PrintingPolicy &Policy) const;
1307 const char *getSpelling() const;
1308 typedef Expr ** args_iterator;
1309 args_iterator args_begin() const { return args_; }
1310 args_iterator args_end() const { return args_ + args_Size; }
1311 unsigned args_size() const { return args_Size; }
1312 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
1313
1314
1315
1316
1317 static bool classof(const Attr *A) { return A->getKind() == attr::AssertExclusiveLock; }
1318};
1319
1320class AssertSharedLockAttr : public InheritableAttr {
1321 unsigned args_Size;
1322 Expr * *args_;
1323
1324public:
1325 static AssertSharedLockAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
1326 auto *A = new (Ctx) AssertSharedLockAttr(Loc, Ctx, Args, ArgsSize, 0);
1327 A->setImplicit(true);
1328 return A;
1329 }
1330
1331 AssertSharedLockAttr(SourceRange R, ASTContext &Ctx
1332 , Expr * *Args, unsigned ArgsSize
1333 , unsigned SI
1334 )
1335 : InheritableAttr(attr::AssertSharedLock, R, SI, true, true)
1336 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
1337 {
1338 std::copy(Args, Args + args_Size, args_);
1339 }
1340
1341 AssertSharedLockAttr(SourceRange R, ASTContext &Ctx
1342 , unsigned SI
1343 )
1344 : InheritableAttr(attr::AssertSharedLock, R, SI, true, true)
1345 , args_Size(0), args_(nullptr)
1346 {
1347 }
1348
1349 AssertSharedLockAttr *clone(ASTContext &C) const;
1350 void printPretty(raw_ostream &OS,
1351 const PrintingPolicy &Policy) const;
1352 const char *getSpelling() const;
1353 typedef Expr ** args_iterator;
1354 args_iterator args_begin() const { return args_; }
1355 args_iterator args_end() const { return args_ + args_Size; }
1356 unsigned args_size() const { return args_Size; }
1357 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
1358
1359
1360
1361
1362 static bool classof(const Attr *A) { return A->getKind() == attr::AssertSharedLock; }
1363};
1364
1365class AssumeAlignedAttr : public InheritableAttr {
1366Expr * alignment;
1367
1368Expr * offset;
1369
1370public:
1371 static AssumeAlignedAttr *CreateImplicit(ASTContext &Ctx, Expr * Alignment, Expr * Offset, SourceRange Loc = SourceRange()) {
1372 auto *A = new (Ctx) AssumeAlignedAttr(Loc, Ctx, Alignment, Offset, 0);
1373 A->setImplicit(true);
1374 return A;
1375 }
1376
1377 AssumeAlignedAttr(SourceRange R, ASTContext &Ctx
1378 , Expr * Alignment
1379 , Expr * Offset
1380 , unsigned SI
1381 )
1382 : InheritableAttr(attr::AssumeAligned, R, SI, false, false)
1383 , alignment(Alignment)
1384 , offset(Offset)
1385 {
1386 }
1387
1388 AssumeAlignedAttr(SourceRange R, ASTContext &Ctx
1389 , Expr * Alignment
1390 , unsigned SI
1391 )
1392 : InheritableAttr(attr::AssumeAligned, R, SI, false, false)
1393 , alignment(Alignment)
1394 , offset()
1395 {
1396 }
1397
1398 AssumeAlignedAttr *clone(ASTContext &C) const;
1399 void printPretty(raw_ostream &OS,
1400 const PrintingPolicy &Policy) const;
1401 const char *getSpelling() const;
1402 Expr * getAlignment() const {
1403 return alignment;
1404 }
1405
1406 Expr * getOffset() const {
1407 return offset;
1408 }
1409
1410
1411
1412 static bool classof(const Attr *A) { return A->getKind() == attr::AssumeAligned; }
1413};
1414
1415class AvailabilityAttr : public InheritableAttr {
1416IdentifierInfo * platform;
1417
1418VersionTuple introduced;
1419
1420
1421VersionTuple deprecated;
1422
1423
1424VersionTuple obsoleted;
1425
1426
1427bool unavailable;
1428
1429unsigned messageLength;
1430char *message;
1431
1432bool strict;
1433
1434unsigned replacementLength;
1435char *replacement;
1436
1437int priority;
1438
1439public:
1440 static AvailabilityAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * Platform, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool Unavailable, llvm::StringRef Message, bool Strict, llvm::StringRef Replacement, int Priority, SourceRange Loc = SourceRange()) {
1441 auto *A = new (Ctx) AvailabilityAttr(Loc, Ctx, Platform, Introduced, Deprecated, Obsoleted, Unavailable, Message, Strict, Replacement, Priority, 0);
1442 A->setImplicit(true);
1443 return A;
1444 }
1445
1446 AvailabilityAttr(SourceRange R, ASTContext &Ctx
1447 , IdentifierInfo * Platform
1448 , VersionTuple Introduced
1449 , VersionTuple Deprecated
1450 , VersionTuple Obsoleted
1451 , bool Unavailable
1452 , llvm::StringRef Message
1453 , bool Strict
1454 , llvm::StringRef Replacement
1455 , int Priority
1456 , unsigned SI
1457 )
1458 : InheritableAttr(attr::Availability, R, SI, false, true)
1459 , platform(Platform)
1460 , introduced(Introduced)
1461 , deprecated(Deprecated)
1462 , obsoleted(Obsoleted)
1463 , unavailable(Unavailable)
1464 , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
1465 , strict(Strict)
1466 , replacementLength(Replacement.size()),replacement(new (Ctx, 1) char[replacementLength])
1467 , priority(Priority)
1468 {
1469 if (!Message.empty())
1470 std::memcpy(message, Message.data(), messageLength);
1471 if (!Replacement.empty())
1472 std::memcpy(replacement, Replacement.data(), replacementLength);
1473 }
1474
1475 AvailabilityAttr *clone(ASTContext &C) const;
1476 void printPretty(raw_ostream &OS,
1477 const PrintingPolicy &Policy) const;
1478 const char *getSpelling() const;
1479 IdentifierInfo * getPlatform() const {
1480 return platform;
1481 }
1482
1483 VersionTuple getIntroduced() const {
1484 return introduced;
1485 }
1486 void setIntroduced(ASTContext &C, VersionTuple V) {
1487 introduced = V;
1488 }
1489
1490 VersionTuple getDeprecated() const {
1491 return deprecated;
1492 }
1493 void setDeprecated(ASTContext &C, VersionTuple V) {
1494 deprecated = V;
1495 }
1496
1497 VersionTuple getObsoleted() const {
1498 return obsoleted;
1499 }
1500 void setObsoleted(ASTContext &C, VersionTuple V) {
1501 obsoleted = V;
1502 }
1503
1504 bool getUnavailable() const {
1505 return unavailable;
1506 }
1507
1508 llvm::StringRef getMessage() const {
1509 return llvm::StringRef(message, messageLength);
1510 }
1511 unsigned getMessageLength() const {
1512 return messageLength;
1513 }
1514 void setMessage(ASTContext &C, llvm::StringRef S) {
1515 messageLength = S.size();
1516 this->message = new (C, 1) char [messageLength];
1517 if (!S.empty())
1518 std::memcpy(this->message, S.data(), messageLength);
1519 }
1520
1521 bool getStrict() const {
1522 return strict;
1523 }
1524
1525 llvm::StringRef getReplacement() const {
1526 return llvm::StringRef(replacement, replacementLength);
1527 }
1528 unsigned getReplacementLength() const {
1529 return replacementLength;
1530 }
1531 void setReplacement(ASTContext &C, llvm::StringRef S) {
1532 replacementLength = S.size();
1533 this->replacement = new (C, 1) char [replacementLength];
1534 if (!S.empty())
1535 std::memcpy(this->replacement, S.data(), replacementLength);
1536 }
1537
1538 int getPriority() const {
1539 return priority;
1540 }
1541
1542static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {
1543 return llvm::StringSwitch<llvm::StringRef>(Platform)
1544 .Case("android", "Android")
1545 .Case("ios", "iOS")
1546 .Case("macos", "macOS")
1547 .Case("tvos", "tvOS")
1548 .Case("watchos", "watchOS")
1549 .Case("ios_app_extension", "iOS (App Extension)")
1550 .Case("macos_app_extension", "macOS (App Extension)")
1551 .Case("tvos_app_extension", "tvOS (App Extension)")
1552 .Case("watchos_app_extension", "watchOS (App Extension)")
1553 .Case("swift", "Swift")
1554 .Default(llvm::StringRef());
1555}
1556static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
1557 return llvm::StringSwitch<llvm::StringRef>(Platform)
1558 .Case("ios", "iOS")
1559 .Case("macos", "macOS")
1560 .Case("tvos", "tvOS")
1561 .Case("watchos", "watchOS")
1562 .Case("ios_app_extension", "iOSApplicationExtension")
1563 .Case("macos_app_extension", "macOSApplicationExtension")
1564 .Case("tvos_app_extension", "tvOSApplicationExtension")
1565 .Case("watchos_app_extension", "watchOSApplicationExtension")
1566 .Default(Platform);
1567}
1568static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
1569 return llvm::StringSwitch<llvm::StringRef>(Platform)
1570 .Case("iOS", "ios")
1571 .Case("macOS", "macos")
1572 .Case("tvOS", "tvos")
1573 .Case("watchOS", "watchos")
1574 .Case("iOSApplicationExtension", "ios_app_extension")
1575 .Case("macOSApplicationExtension", "macos_app_extension")
1576 .Case("tvOSApplicationExtension", "tvos_app_extension")
1577 .Case("watchOSApplicationExtension", "watchos_app_extension")
1578 .Default(Platform);
1579}
1580
1581 static bool classof(const Attr *A) { return A->getKind() == attr::Availability; }
1582};
1583
1584class BlocksAttr : public InheritableAttr {
1585public:
1586 enum BlockType {
1587 ByRef
1588 };
1589private:
1590 BlockType type;
1591
1592public:
1593 static BlocksAttr *CreateImplicit(ASTContext &Ctx, BlockType Type, SourceRange Loc = SourceRange()) {
1594 auto *A = new (Ctx) BlocksAttr(Loc, Ctx, Type, 0);
1595 A->setImplicit(true);
1596 return A;
1597 }
1598
1599 BlocksAttr(SourceRange R, ASTContext &Ctx
1600 , BlockType Type
1601 , unsigned SI
1602 )
1603 : InheritableAttr(attr::Blocks, R, SI, false, false)
1604 , type(Type)
1605 {
1606 }
1607
1608 BlocksAttr *clone(ASTContext &C) const;
1609 void printPretty(raw_ostream &OS,
1610 const PrintingPolicy &Policy) const;
1611 const char *getSpelling() const;
1612 BlockType getType() const {
1613 return type;
1614 }
1615
1616 static bool ConvertStrToBlockType(StringRef Val, BlockType &Out) {
1617 Optional<BlockType> R = llvm::StringSwitch<Optional<BlockType>>(Val)
1618 .Case("byref", BlocksAttr::ByRef)
1619 .Default(Optional<BlockType>());
1620 if (R) {
1621 Out = *R;
1622 return true;
1623 }
1624 return false;
1625 }
1626
1627 static const char *ConvertBlockTypeToStr(BlockType Val) {
1628 switch(Val) {
1629 case BlocksAttr::ByRef: return "byref";
1630 }
1631 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 1631)
;
1632 }
1633
1634
1635 static bool classof(const Attr *A) { return A->getKind() == attr::Blocks; }
1636};
1637
1638class C11NoReturnAttr : public InheritableAttr {
1639public:
1640 static C11NoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1641 auto *A = new (Ctx) C11NoReturnAttr(Loc, Ctx, 0);
1642 A->setImplicit(true);
1643 return A;
1644 }
1645
1646 C11NoReturnAttr(SourceRange R, ASTContext &Ctx
1647 , unsigned SI
1648 )
1649 : InheritableAttr(attr::C11NoReturn, R, SI, false, false)
1650 {
1651 }
1652
1653 C11NoReturnAttr *clone(ASTContext &C) const;
1654 void printPretty(raw_ostream &OS,
1655 const PrintingPolicy &Policy) const;
1656 const char *getSpelling() const;
1657
1658
1659 static bool classof(const Attr *A) { return A->getKind() == attr::C11NoReturn; }
1660};
1661
1662class CDeclAttr : public InheritableAttr {
1663public:
1664 static CDeclAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1665 auto *A = new (Ctx) CDeclAttr(Loc, Ctx, 0);
1666 A->setImplicit(true);
1667 return A;
1668 }
1669
1670 CDeclAttr(SourceRange R, ASTContext &Ctx
1671 , unsigned SI
1672 )
1673 : InheritableAttr(attr::CDecl, R, SI, false, false)
1674 {
1675 }
1676
1677 CDeclAttr *clone(ASTContext &C) const;
1678 void printPretty(raw_ostream &OS,
1679 const PrintingPolicy &Policy) const;
1680 const char *getSpelling() const;
1681
1682
1683 static bool classof(const Attr *A) { return A->getKind() == attr::CDecl; }
1684};
1685
1686class CFAuditedTransferAttr : public InheritableAttr {
1687public:
1688 static CFAuditedTransferAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1689 auto *A = new (Ctx) CFAuditedTransferAttr(Loc, Ctx, 0);
1690 A->setImplicit(true);
1691 return A;
1692 }
1693
1694 CFAuditedTransferAttr(SourceRange R, ASTContext &Ctx
1695 , unsigned SI
1696 )
1697 : InheritableAttr(attr::CFAuditedTransfer, R, SI, false, false)
1698 {
1699 }
1700
1701 CFAuditedTransferAttr *clone(ASTContext &C) const;
1702 void printPretty(raw_ostream &OS,
1703 const PrintingPolicy &Policy) const;
1704 const char *getSpelling() const;
1705
1706
1707 static bool classof(const Attr *A) { return A->getKind() == attr::CFAuditedTransfer; }
1708};
1709
1710class CFConsumedAttr : public InheritableParamAttr {
1711public:
1712 static CFConsumedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1713 auto *A = new (Ctx) CFConsumedAttr(Loc, Ctx, 0);
1714 A->setImplicit(true);
1715 return A;
1716 }
1717
1718 CFConsumedAttr(SourceRange R, ASTContext &Ctx
1719 , unsigned SI
1720 )
1721 : InheritableParamAttr(attr::CFConsumed, R, SI, false, false)
1722 {
1723 }
1724
1725 CFConsumedAttr *clone(ASTContext &C) const;
1726 void printPretty(raw_ostream &OS,
1727 const PrintingPolicy &Policy) const;
1728 const char *getSpelling() const;
1729
1730
1731 static bool classof(const Attr *A) { return A->getKind() == attr::CFConsumed; }
1732};
1733
1734class CFReturnsNotRetainedAttr : public InheritableAttr {
1735public:
1736 static CFReturnsNotRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1737 auto *A = new (Ctx) CFReturnsNotRetainedAttr(Loc, Ctx, 0);
1738 A->setImplicit(true);
1739 return A;
1740 }
1741
1742 CFReturnsNotRetainedAttr(SourceRange R, ASTContext &Ctx
1743 , unsigned SI
1744 )
1745 : InheritableAttr(attr::CFReturnsNotRetained, R, SI, false, false)
1746 {
1747 }
1748
1749 CFReturnsNotRetainedAttr *clone(ASTContext &C) const;
1750 void printPretty(raw_ostream &OS,
1751 const PrintingPolicy &Policy) const;
1752 const char *getSpelling() const;
1753
1754
1755 static bool classof(const Attr *A) { return A->getKind() == attr::CFReturnsNotRetained; }
1756};
1757
1758class CFReturnsRetainedAttr : public InheritableAttr {
1759public:
1760 static CFReturnsRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1761 auto *A = new (Ctx) CFReturnsRetainedAttr(Loc, Ctx, 0);
1762 A->setImplicit(true);
1763 return A;
1764 }
1765
1766 CFReturnsRetainedAttr(SourceRange R, ASTContext &Ctx
1767 , unsigned SI
1768 )
1769 : InheritableAttr(attr::CFReturnsRetained, R, SI, false, false)
1770 {
1771 }
1772
1773 CFReturnsRetainedAttr *clone(ASTContext &C) const;
1774 void printPretty(raw_ostream &OS,
1775 const PrintingPolicy &Policy) const;
1776 const char *getSpelling() const;
1777
1778
1779 static bool classof(const Attr *A) { return A->getKind() == attr::CFReturnsRetained; }
1780};
1781
1782class CFUnknownTransferAttr : public InheritableAttr {
1783public:
1784 static CFUnknownTransferAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1785 auto *A = new (Ctx) CFUnknownTransferAttr(Loc, Ctx, 0);
1786 A->setImplicit(true);
1787 return A;
1788 }
1789
1790 CFUnknownTransferAttr(SourceRange R, ASTContext &Ctx
1791 , unsigned SI
1792 )
1793 : InheritableAttr(attr::CFUnknownTransfer, R, SI, false, false)
1794 {
1795 }
1796
1797 CFUnknownTransferAttr *clone(ASTContext &C) const;
1798 void printPretty(raw_ostream &OS,
1799 const PrintingPolicy &Policy) const;
1800 const char *getSpelling() const;
1801
1802
1803 static bool classof(const Attr *A) { return A->getKind() == attr::CFUnknownTransfer; }
1804};
1805
1806class CPUDispatchAttr : public InheritableAttr {
1807 unsigned cpus_Size;
1808 IdentifierInfo * *cpus_;
1809
1810public:
1811 static CPUDispatchAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, SourceRange Loc = SourceRange()) {
1812 auto *A = new (Ctx) CPUDispatchAttr(Loc, Ctx, Cpus, CpusSize, 0);
1813 A->setImplicit(true);
1814 return A;
1815 }
1816
1817 CPUDispatchAttr(SourceRange R, ASTContext &Ctx
1818 , IdentifierInfo * *Cpus, unsigned CpusSize
1819 , unsigned SI
1820 )
1821 : InheritableAttr(attr::CPUDispatch, R, SI, false, false)
1822 , cpus_Size(CpusSize), cpus_(new (Ctx, 16) IdentifierInfo *[cpus_Size])
1823 {
1824 std::copy(Cpus, Cpus + cpus_Size, cpus_);
1825 }
1826
1827 CPUDispatchAttr(SourceRange R, ASTContext &Ctx
1828 , unsigned SI
1829 )
1830 : InheritableAttr(attr::CPUDispatch, R, SI, false, false)
1831 , cpus_Size(0), cpus_(nullptr)
1832 {
1833 }
1834
1835 CPUDispatchAttr *clone(ASTContext &C) const;
1836 void printPretty(raw_ostream &OS,
1837 const PrintingPolicy &Policy) const;
1838 const char *getSpelling() const;
1839 typedef IdentifierInfo ** cpus_iterator;
1840 cpus_iterator cpus_begin() const { return cpus_; }
1841 cpus_iterator cpus_end() const { return cpus_ + cpus_Size; }
1842 unsigned cpus_size() const { return cpus_Size; }
1843 llvm::iterator_range<cpus_iterator> cpus() const { return llvm::make_range(cpus_begin(), cpus_end()); }
1844
1845
1846
1847
1848 static bool classof(const Attr *A) { return A->getKind() == attr::CPUDispatch; }
1849};
1850
1851class CPUSpecificAttr : public InheritableAttr {
1852 unsigned cpus_Size;
1853 IdentifierInfo * *cpus_;
1854
1855public:
1856 static CPUSpecificAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * *Cpus, unsigned CpusSize, SourceRange Loc = SourceRange()) {
1857 auto *A = new (Ctx) CPUSpecificAttr(Loc, Ctx, Cpus, CpusSize, 0);
1858 A->setImplicit(true);
1859 return A;
1860 }
1861
1862 CPUSpecificAttr(SourceRange R, ASTContext &Ctx
1863 , IdentifierInfo * *Cpus, unsigned CpusSize
1864 , unsigned SI
1865 )
1866 : InheritableAttr(attr::CPUSpecific, R, SI, false, false)
1867 , cpus_Size(CpusSize), cpus_(new (Ctx, 16) IdentifierInfo *[cpus_Size])
1868 {
1869 std::copy(Cpus, Cpus + cpus_Size, cpus_);
1870 }
1871
1872 CPUSpecificAttr(SourceRange R, ASTContext &Ctx
1873 , unsigned SI
1874 )
1875 : InheritableAttr(attr::CPUSpecific, R, SI, false, false)
1876 , cpus_Size(0), cpus_(nullptr)
1877 {
1878 }
1879
1880 CPUSpecificAttr *clone(ASTContext &C) const;
1881 void printPretty(raw_ostream &OS,
1882 const PrintingPolicy &Policy) const;
1883 const char *getSpelling() const;
1884 typedef IdentifierInfo ** cpus_iterator;
1885 cpus_iterator cpus_begin() const { return cpus_; }
1886 cpus_iterator cpus_end() const { return cpus_ + cpus_Size; }
1887 unsigned cpus_size() const { return cpus_Size; }
1888 llvm::iterator_range<cpus_iterator> cpus() const { return llvm::make_range(cpus_begin(), cpus_end()); }
1889
1890
1891
1892 IdentifierInfo *getCPUName(unsigned Index) const {
1893 return *(cpus_begin() + Index);
1894 }
1895
1896
1897 static bool classof(const Attr *A) { return A->getKind() == attr::CPUSpecific; }
1898};
1899
1900class CUDAConstantAttr : public InheritableAttr {
1901public:
1902 static CUDAConstantAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1903 auto *A = new (Ctx) CUDAConstantAttr(Loc, Ctx, 0);
1904 A->setImplicit(true);
1905 return A;
1906 }
1907
1908 CUDAConstantAttr(SourceRange R, ASTContext &Ctx
1909 , unsigned SI
1910 )
1911 : InheritableAttr(attr::CUDAConstant, R, SI, false, false)
1912 {
1913 }
1914
1915 CUDAConstantAttr *clone(ASTContext &C) const;
1916 void printPretty(raw_ostream &OS,
1917 const PrintingPolicy &Policy) const;
1918 const char *getSpelling() const;
1919
1920
1921 static bool classof(const Attr *A) { return A->getKind() == attr::CUDAConstant; }
1922};
1923
1924class CUDADeviceAttr : public InheritableAttr {
1925public:
1926 static CUDADeviceAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1927 auto *A = new (Ctx) CUDADeviceAttr(Loc, Ctx, 0);
1928 A->setImplicit(true);
1929 return A;
1930 }
1931
1932 CUDADeviceAttr(SourceRange R, ASTContext &Ctx
1933 , unsigned SI
1934 )
1935 : InheritableAttr(attr::CUDADevice, R, SI, false, false)
1936 {
1937 }
1938
1939 CUDADeviceAttr *clone(ASTContext &C) const;
1940 void printPretty(raw_ostream &OS,
1941 const PrintingPolicy &Policy) const;
1942 const char *getSpelling() const;
1943
1944
1945 static bool classof(const Attr *A) { return A->getKind() == attr::CUDADevice; }
1946};
1947
1948class CUDAGlobalAttr : public InheritableAttr {
1949public:
1950 static CUDAGlobalAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1951 auto *A = new (Ctx) CUDAGlobalAttr(Loc, Ctx, 0);
1952 A->setImplicit(true);
1953 return A;
1954 }
1955
1956 CUDAGlobalAttr(SourceRange R, ASTContext &Ctx
1957 , unsigned SI
1958 )
1959 : InheritableAttr(attr::CUDAGlobal, R, SI, false, false)
1960 {
1961 }
1962
1963 CUDAGlobalAttr *clone(ASTContext &C) const;
1964 void printPretty(raw_ostream &OS,
1965 const PrintingPolicy &Policy) const;
1966 const char *getSpelling() const;
1967
1968
1969 static bool classof(const Attr *A) { return A->getKind() == attr::CUDAGlobal; }
1970};
1971
1972class CUDAHostAttr : public InheritableAttr {
1973public:
1974 static CUDAHostAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1975 auto *A = new (Ctx) CUDAHostAttr(Loc, Ctx, 0);
1976 A->setImplicit(true);
1977 return A;
1978 }
1979
1980 CUDAHostAttr(SourceRange R, ASTContext &Ctx
1981 , unsigned SI
1982 )
1983 : InheritableAttr(attr::CUDAHost, R, SI, false, false)
1984 {
1985 }
1986
1987 CUDAHostAttr *clone(ASTContext &C) const;
1988 void printPretty(raw_ostream &OS,
1989 const PrintingPolicy &Policy) const;
1990 const char *getSpelling() const;
1991
1992
1993 static bool classof(const Attr *A) { return A->getKind() == attr::CUDAHost; }
1994};
1995
1996class CUDAInvalidTargetAttr : public InheritableAttr {
1997public:
1998 static CUDAInvalidTargetAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
1999 auto *A = new (Ctx) CUDAInvalidTargetAttr(Loc, Ctx, 0);
2000 A->setImplicit(true);
2001 return A;
2002 }
2003
2004 CUDAInvalidTargetAttr(SourceRange R, ASTContext &Ctx
2005 , unsigned SI
2006 )
2007 : InheritableAttr(attr::CUDAInvalidTarget, R, SI, false, false)
2008 {
2009 }
2010
2011 CUDAInvalidTargetAttr *clone(ASTContext &C) const;
2012 void printPretty(raw_ostream &OS,
2013 const PrintingPolicy &Policy) const;
2014 const char *getSpelling() const;
2015
2016
2017 static bool classof(const Attr *A) { return A->getKind() == attr::CUDAInvalidTarget; }
2018};
2019
2020class CUDALaunchBoundsAttr : public InheritableAttr {
2021Expr * maxThreads;
2022
2023Expr * minBlocks;
2024
2025public:
2026 static CUDALaunchBoundsAttr *CreateImplicit(ASTContext &Ctx, Expr * MaxThreads, Expr * MinBlocks, SourceRange Loc = SourceRange()) {
2027 auto *A = new (Ctx) CUDALaunchBoundsAttr(Loc, Ctx, MaxThreads, MinBlocks, 0);
2028 A->setImplicit(true);
2029 return A;
2030 }
2031
2032 CUDALaunchBoundsAttr(SourceRange R, ASTContext &Ctx
2033 , Expr * MaxThreads
2034 , Expr * MinBlocks
2035 , unsigned SI
2036 )
2037 : InheritableAttr(attr::CUDALaunchBounds, R, SI, false, false)
2038 , maxThreads(MaxThreads)
2039 , minBlocks(MinBlocks)
2040 {
2041 }
2042
2043 CUDALaunchBoundsAttr(SourceRange R, ASTContext &Ctx
2044 , Expr * MaxThreads
2045 , unsigned SI
2046 )
2047 : InheritableAttr(attr::CUDALaunchBounds, R, SI, false, false)
2048 , maxThreads(MaxThreads)
2049 , minBlocks()
2050 {
2051 }
2052
2053 CUDALaunchBoundsAttr *clone(ASTContext &C) const;
2054 void printPretty(raw_ostream &OS,
2055 const PrintingPolicy &Policy) const;
2056 const char *getSpelling() const;
2057 Expr * getMaxThreads() const {
2058 return maxThreads;
2059 }
2060
2061 Expr * getMinBlocks() const {
2062 return minBlocks;
2063 }
2064
2065
2066
2067 static bool classof(const Attr *A) { return A->getKind() == attr::CUDALaunchBounds; }
2068};
2069
2070class CUDASharedAttr : public InheritableAttr {
2071public:
2072 static CUDASharedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2073 auto *A = new (Ctx) CUDASharedAttr(Loc, Ctx, 0);
2074 A->setImplicit(true);
2075 return A;
2076 }
2077
2078 CUDASharedAttr(SourceRange R, ASTContext &Ctx
2079 , unsigned SI
2080 )
2081 : InheritableAttr(attr::CUDAShared, R, SI, false, false)
2082 {
2083 }
2084
2085 CUDASharedAttr *clone(ASTContext &C) const;
2086 void printPretty(raw_ostream &OS,
2087 const PrintingPolicy &Policy) const;
2088 const char *getSpelling() const;
2089
2090
2091 static bool classof(const Attr *A) { return A->getKind() == attr::CUDAShared; }
2092};
2093
2094class CXX11NoReturnAttr : public InheritableAttr {
2095public:
2096 static CXX11NoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2097 auto *A = new (Ctx) CXX11NoReturnAttr(Loc, Ctx, 0);
2098 A->setImplicit(true);
2099 return A;
2100 }
2101
2102 CXX11NoReturnAttr(SourceRange R, ASTContext &Ctx
2103 , unsigned SI
2104 )
2105 : InheritableAttr(attr::CXX11NoReturn, R, SI, false, false)
2106 {
2107 }
2108
2109 CXX11NoReturnAttr *clone(ASTContext &C) const;
2110 void printPretty(raw_ostream &OS,
2111 const PrintingPolicy &Policy) const;
2112 const char *getSpelling() const;
2113
2114
2115 static bool classof(const Attr *A) { return A->getKind() == attr::CXX11NoReturn; }
2116};
2117
2118class CallableWhenAttr : public InheritableAttr {
2119public:
2120 enum ConsumedState {
2121 Unknown,
2122 Consumed,
2123 Unconsumed
2124 };
2125private:
2126 unsigned callableStates_Size;
2127 ConsumedState *callableStates_;
2128
2129public:
2130 static CallableWhenAttr *CreateImplicit(ASTContext &Ctx, ConsumedState *CallableStates, unsigned CallableStatesSize, SourceRange Loc = SourceRange()) {
2131 auto *A = new (Ctx) CallableWhenAttr(Loc, Ctx, CallableStates, CallableStatesSize, 0);
2132 A->setImplicit(true);
2133 return A;
2134 }
2135
2136 CallableWhenAttr(SourceRange R, ASTContext &Ctx
2137 , ConsumedState *CallableStates, unsigned CallableStatesSize
2138 , unsigned SI
2139 )
2140 : InheritableAttr(attr::CallableWhen, R, SI, false, false)
2141 , callableStates_Size(CallableStatesSize), callableStates_(new (Ctx, 16) ConsumedState[callableStates_Size])
2142 {
2143 std::copy(CallableStates, CallableStates + callableStates_Size, callableStates_);
2144 }
2145
2146 CallableWhenAttr(SourceRange R, ASTContext &Ctx
2147 , unsigned SI
2148 )
2149 : InheritableAttr(attr::CallableWhen, R, SI, false, false)
2150 , callableStates_Size(0), callableStates_(nullptr)
2151 {
2152 }
2153
2154 CallableWhenAttr *clone(ASTContext &C) const;
2155 void printPretty(raw_ostream &OS,
2156 const PrintingPolicy &Policy) const;
2157 const char *getSpelling() const;
2158 typedef ConsumedState* callableStates_iterator;
2159 callableStates_iterator callableStates_begin() const { return callableStates_; }
2160 callableStates_iterator callableStates_end() const { return callableStates_ + callableStates_Size; }
2161 unsigned callableStates_size() const { return callableStates_Size; }
2162 llvm::iterator_range<callableStates_iterator> callableStates() const { return llvm::make_range(callableStates_begin(), callableStates_end()); }
2163
2164
2165 static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
2166 Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
2167 .Case("unknown", CallableWhenAttr::Unknown)
2168 .Case("consumed", CallableWhenAttr::Consumed)
2169 .Case("unconsumed", CallableWhenAttr::Unconsumed)
2170 .Default(Optional<ConsumedState>());
2171 if (R) {
2172 Out = *R;
2173 return true;
2174 }
2175 return false;
2176 }
2177
2178 static const char *ConvertConsumedStateToStr(ConsumedState Val) {
2179 switch(Val) {
2180 case CallableWhenAttr::Unknown: return "unknown";
2181 case CallableWhenAttr::Consumed: return "consumed";
2182 case CallableWhenAttr::Unconsumed: return "unconsumed";
2183 }
2184 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 2184)
;
2185 }
2186
2187
2188 static bool classof(const Attr *A) { return A->getKind() == attr::CallableWhen; }
2189};
2190
2191class CallbackAttr : public InheritableAttr {
2192 unsigned encoding_Size;
2193 int *encoding_;
2194
2195public:
2196 static CallbackAttr *CreateImplicit(ASTContext &Ctx, int *Encoding, unsigned EncodingSize, SourceRange Loc = SourceRange()) {
2197 auto *A = new (Ctx) CallbackAttr(Loc, Ctx, Encoding, EncodingSize, 0);
2198 A->setImplicit(true);
2199 return A;
2200 }
2201
2202 CallbackAttr(SourceRange R, ASTContext &Ctx
2203 , int *Encoding, unsigned EncodingSize
2204 , unsigned SI
2205 )
2206 : InheritableAttr(attr::Callback, R, SI, false, false)
2207 , encoding_Size(EncodingSize), encoding_(new (Ctx, 16) int[encoding_Size])
2208 {
2209 std::copy(Encoding, Encoding + encoding_Size, encoding_);
2210 }
2211
2212 CallbackAttr(SourceRange R, ASTContext &Ctx
2213 , unsigned SI
2214 )
2215 : InheritableAttr(attr::Callback, R, SI, false, false)
2216 , encoding_Size(0), encoding_(nullptr)
2217 {
2218 }
2219
2220 CallbackAttr *clone(ASTContext &C) const;
2221 void printPretty(raw_ostream &OS,
2222 const PrintingPolicy &Policy) const;
2223 const char *getSpelling() const;
2224 typedef int* encoding_iterator;
2225 encoding_iterator encoding_begin() const { return encoding_; }
2226 encoding_iterator encoding_end() const { return encoding_ + encoding_Size; }
2227 unsigned encoding_size() const { return encoding_Size; }
2228 llvm::iterator_range<encoding_iterator> encoding() const { return llvm::make_range(encoding_begin(), encoding_end()); }
2229
2230
2231
2232
2233 static bool classof(const Attr *A) { return A->getKind() == attr::Callback; }
2234};
2235
2236class CapabilityAttr : public InheritableAttr {
2237unsigned nameLength;
2238char *name;
2239
2240public:
2241 enum Spelling {
2242 GNU_capability = 0,
2243 CXX11_clang_capability = 1,
2244 GNU_shared_capability = 2,
2245 CXX11_clang_shared_capability = 3
2246 };
2247
2248 static CapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, llvm::StringRef Name, SourceRange Loc = SourceRange()) {
2249 auto *A = new (Ctx) CapabilityAttr(Loc, Ctx, Name, S);
2250 A->setImplicit(true);
2251 return A;
2252 }
2253
2254 CapabilityAttr(SourceRange R, ASTContext &Ctx
2255 , llvm::StringRef Name
2256 , unsigned SI
2257 )
2258 : InheritableAttr(attr::Capability, R, SI, false, false)
2259 , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
2260 {
2261 if (!Name.empty())
2262 std::memcpy(name, Name.data(), nameLength);
2263 }
2264
2265 CapabilityAttr *clone(ASTContext &C) const;
2266 void printPretty(raw_ostream &OS,
2267 const PrintingPolicy &Policy) const;
2268 const char *getSpelling() const;
2269 Spelling getSemanticSpelling() const {
2270 switch (SpellingListIndex) {
2271 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 2271)
;
2272 case 0: return GNU_capability;
2273 case 1: return CXX11_clang_capability;
2274 case 2: return GNU_shared_capability;
2275 case 3: return CXX11_clang_shared_capability;
2276 }
2277 }
2278 bool isShared() const { return SpellingListIndex == 2 ||
2279 SpellingListIndex == 3; }
2280 llvm::StringRef getName() const {
2281 return llvm::StringRef(name, nameLength);
2282 }
2283 unsigned getNameLength() const {
2284 return nameLength;
2285 }
2286 void setName(ASTContext &C, llvm::StringRef S) {
2287 nameLength = S.size();
2288 this->name = new (C, 1) char [nameLength];
2289 if (!S.empty())
2290 std::memcpy(this->name, S.data(), nameLength);
2291 }
2292
2293
2294 bool isMutex() const { return getName().equals_lower("mutex"); }
2295 bool isRole() const { return getName().equals_lower("role"); }
2296
2297
2298 static bool classof(const Attr *A) { return A->getKind() == attr::Capability; }
2299};
2300
2301class CapturedRecordAttr : public InheritableAttr {
2302public:
2303 static CapturedRecordAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2304 auto *A = new (Ctx) CapturedRecordAttr(Loc, Ctx, 0);
2305 A->setImplicit(true);
2306 return A;
2307 }
2308
2309 CapturedRecordAttr(SourceRange R, ASTContext &Ctx
2310 , unsigned SI
2311 )
2312 : InheritableAttr(attr::CapturedRecord, R, SI, false, false)
2313 {
2314 }
2315
2316 CapturedRecordAttr *clone(ASTContext &C) const;
2317 void printPretty(raw_ostream &OS,
2318 const PrintingPolicy &Policy) const;
2319 const char *getSpelling() const;
2320
2321
2322 static bool classof(const Attr *A) { return A->getKind() == attr::CapturedRecord; }
2323};
2324
2325class CarriesDependencyAttr : public InheritableParamAttr {
2326public:
2327 static CarriesDependencyAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2328 auto *A = new (Ctx) CarriesDependencyAttr(Loc, Ctx, 0);
2329 A->setImplicit(true);
2330 return A;
2331 }
2332
2333 CarriesDependencyAttr(SourceRange R, ASTContext &Ctx
2334 , unsigned SI
2335 )
2336 : InheritableParamAttr(attr::CarriesDependency, R, SI, false, false)
2337 {
2338 }
2339
2340 CarriesDependencyAttr *clone(ASTContext &C) const;
2341 void printPretty(raw_ostream &OS,
2342 const PrintingPolicy &Policy) const;
2343 const char *getSpelling() const;
2344
2345
2346 static bool classof(const Attr *A) { return A->getKind() == attr::CarriesDependency; }
2347};
2348
2349class CleanupAttr : public InheritableAttr {
2350FunctionDecl * functionDecl;
2351
2352public:
2353 static CleanupAttr *CreateImplicit(ASTContext &Ctx, FunctionDecl * FunctionDecl, SourceRange Loc = SourceRange()) {
2354 auto *A = new (Ctx) CleanupAttr(Loc, Ctx, FunctionDecl, 0);
2355 A->setImplicit(true);
2356 return A;
2357 }
2358
2359 CleanupAttr(SourceRange R, ASTContext &Ctx
2360 , FunctionDecl * FunctionDecl
2361 , unsigned SI
2362 )
2363 : InheritableAttr(attr::Cleanup, R, SI, false, false)
2364 , functionDecl(FunctionDecl)
2365 {
2366 }
2367
2368 CleanupAttr *clone(ASTContext &C) const;
2369 void printPretty(raw_ostream &OS,
2370 const PrintingPolicy &Policy) const;
2371 const char *getSpelling() const;
2372 FunctionDecl * getFunctionDecl() const {
2373 return functionDecl;
2374 }
2375
2376
2377
2378 static bool classof(const Attr *A) { return A->getKind() == attr::Cleanup; }
2379};
2380
2381class CodeSegAttr : public InheritableAttr {
2382unsigned nameLength;
2383char *name;
2384
2385public:
2386 static CodeSegAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Loc = SourceRange()) {
2387 auto *A = new (Ctx) CodeSegAttr(Loc, Ctx, Name, 0);
2388 A->setImplicit(true);
2389 return A;
2390 }
2391
2392 CodeSegAttr(SourceRange R, ASTContext &Ctx
2393 , llvm::StringRef Name
2394 , unsigned SI
2395 )
2396 : InheritableAttr(attr::CodeSeg, R, SI, false, false)
2397 , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
2398 {
2399 if (!Name.empty())
2400 std::memcpy(name, Name.data(), nameLength);
2401 }
2402
2403 CodeSegAttr *clone(ASTContext &C) const;
2404 void printPretty(raw_ostream &OS,
2405 const PrintingPolicy &Policy) const;
2406 const char *getSpelling() const;
2407 llvm::StringRef getName() const {
2408 return llvm::StringRef(name, nameLength);
2409 }
2410 unsigned getNameLength() const {
2411 return nameLength;
2412 }
2413 void setName(ASTContext &C, llvm::StringRef S) {
2414 nameLength = S.size();
2415 this->name = new (C, 1) char [nameLength];
2416 if (!S.empty())
2417 std::memcpy(this->name, S.data(), nameLength);
2418 }
2419
2420
2421
2422 static bool classof(const Attr *A) { return A->getKind() == attr::CodeSeg; }
2423};
2424
2425class ColdAttr : public InheritableAttr {
2426public:
2427 static ColdAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2428 auto *A = new (Ctx) ColdAttr(Loc, Ctx, 0);
2429 A->setImplicit(true);
2430 return A;
2431 }
2432
2433 ColdAttr(SourceRange R, ASTContext &Ctx
2434 , unsigned SI
2435 )
2436 : InheritableAttr(attr::Cold, R, SI, false, false)
2437 {
2438 }
2439
2440 ColdAttr *clone(ASTContext &C) const;
2441 void printPretty(raw_ostream &OS,
2442 const PrintingPolicy &Policy) const;
2443 const char *getSpelling() const;
2444
2445
2446 static bool classof(const Attr *A) { return A->getKind() == attr::Cold; }
2447};
2448
2449class CommonAttr : public InheritableAttr {
2450public:
2451 static CommonAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2452 auto *A = new (Ctx) CommonAttr(Loc, Ctx, 0);
2453 A->setImplicit(true);
2454 return A;
2455 }
2456
2457 CommonAttr(SourceRange R, ASTContext &Ctx
2458 , unsigned SI
2459 )
2460 : InheritableAttr(attr::Common, R, SI, false, false)
2461 {
2462 }
2463
2464 CommonAttr *clone(ASTContext &C) const;
2465 void printPretty(raw_ostream &OS,
2466 const PrintingPolicy &Policy) const;
2467 const char *getSpelling() const;
2468
2469
2470 static bool classof(const Attr *A) { return A->getKind() == attr::Common; }
2471};
2472
2473class ConstAttr : public InheritableAttr {
2474public:
2475 static ConstAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2476 auto *A = new (Ctx) ConstAttr(Loc, Ctx, 0);
2477 A->setImplicit(true);
2478 return A;
2479 }
2480
2481 ConstAttr(SourceRange R, ASTContext &Ctx
2482 , unsigned SI
2483 )
2484 : InheritableAttr(attr::Const, R, SI, false, false)
2485 {
2486 }
2487
2488 ConstAttr *clone(ASTContext &C) const;
2489 void printPretty(raw_ostream &OS,
2490 const PrintingPolicy &Policy) const;
2491 const char *getSpelling() const;
2492
2493
2494 static bool classof(const Attr *A) { return A->getKind() == attr::Const; }
2495};
2496
2497class ConstructorAttr : public InheritableAttr {
2498int priority;
2499
2500public:
2501 static ConstructorAttr *CreateImplicit(ASTContext &Ctx, int Priority, SourceRange Loc = SourceRange()) {
2502 auto *A = new (Ctx) ConstructorAttr(Loc, Ctx, Priority, 0);
2503 A->setImplicit(true);
2504 return A;
2505 }
2506
2507 ConstructorAttr(SourceRange R, ASTContext &Ctx
2508 , int Priority
2509 , unsigned SI
2510 )
2511 : InheritableAttr(attr::Constructor, R, SI, false, false)
2512 , priority(Priority)
2513 {
2514 }
2515
2516 ConstructorAttr(SourceRange R, ASTContext &Ctx
2517 , unsigned SI
2518 )
2519 : InheritableAttr(attr::Constructor, R, SI, false, false)
2520 , priority()
2521 {
2522 }
2523
2524 ConstructorAttr *clone(ASTContext &C) const;
2525 void printPretty(raw_ostream &OS,
2526 const PrintingPolicy &Policy) const;
2527 const char *getSpelling() const;
2528 int getPriority() const {
2529 return priority;
2530 }
2531
2532 static const int DefaultPriority = 65535;
2533
2534
2535
2536 static bool classof(const Attr *A) { return A->getKind() == attr::Constructor; }
2537};
2538
2539class ConsumableAttr : public InheritableAttr {
2540public:
2541 enum ConsumedState {
2542 Unknown,
2543 Consumed,
2544 Unconsumed
2545 };
2546private:
2547 ConsumedState defaultState;
2548
2549public:
2550 static ConsumableAttr *CreateImplicit(ASTContext &Ctx, ConsumedState DefaultState, SourceRange Loc = SourceRange()) {
2551 auto *A = new (Ctx) ConsumableAttr(Loc, Ctx, DefaultState, 0);
2552 A->setImplicit(true);
2553 return A;
2554 }
2555
2556 ConsumableAttr(SourceRange R, ASTContext &Ctx
2557 , ConsumedState DefaultState
2558 , unsigned SI
2559 )
2560 : InheritableAttr(attr::Consumable, R, SI, false, false)
2561 , defaultState(DefaultState)
2562 {
2563 }
2564
2565 ConsumableAttr *clone(ASTContext &C) const;
2566 void printPretty(raw_ostream &OS,
2567 const PrintingPolicy &Policy) const;
2568 const char *getSpelling() const;
2569 ConsumedState getDefaultState() const {
2570 return defaultState;
2571 }
2572
2573 static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
2574 Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
2575 .Case("unknown", ConsumableAttr::Unknown)
2576 .Case("consumed", ConsumableAttr::Consumed)
2577 .Case("unconsumed", ConsumableAttr::Unconsumed)
2578 .Default(Optional<ConsumedState>());
2579 if (R) {
2580 Out = *R;
2581 return true;
2582 }
2583 return false;
2584 }
2585
2586 static const char *ConvertConsumedStateToStr(ConsumedState Val) {
2587 switch(Val) {
2588 case ConsumableAttr::Unknown: return "unknown";
2589 case ConsumableAttr::Consumed: return "consumed";
2590 case ConsumableAttr::Unconsumed: return "unconsumed";
2591 }
2592 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 2592)
;
2593 }
2594
2595
2596 static bool classof(const Attr *A) { return A->getKind() == attr::Consumable; }
2597};
2598
2599class ConsumableAutoCastAttr : public InheritableAttr {
2600public:
2601 static ConsumableAutoCastAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2602 auto *A = new (Ctx) ConsumableAutoCastAttr(Loc, Ctx, 0);
2603 A->setImplicit(true);
2604 return A;
2605 }
2606
2607 ConsumableAutoCastAttr(SourceRange R, ASTContext &Ctx
2608 , unsigned SI
2609 )
2610 : InheritableAttr(attr::ConsumableAutoCast, R, SI, false, false)
2611 {
2612 }
2613
2614 ConsumableAutoCastAttr *clone(ASTContext &C) const;
2615 void printPretty(raw_ostream &OS,
2616 const PrintingPolicy &Policy) const;
2617 const char *getSpelling() const;
2618
2619
2620 static bool classof(const Attr *A) { return A->getKind() == attr::ConsumableAutoCast; }
2621};
2622
2623class ConsumableSetOnReadAttr : public InheritableAttr {
2624public:
2625 static ConsumableSetOnReadAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2626 auto *A = new (Ctx) ConsumableSetOnReadAttr(Loc, Ctx, 0);
2627 A->setImplicit(true);
2628 return A;
2629 }
2630
2631 ConsumableSetOnReadAttr(SourceRange R, ASTContext &Ctx
2632 , unsigned SI
2633 )
2634 : InheritableAttr(attr::ConsumableSetOnRead, R, SI, false, false)
2635 {
2636 }
2637
2638 ConsumableSetOnReadAttr *clone(ASTContext &C) const;
2639 void printPretty(raw_ostream &OS,
2640 const PrintingPolicy &Policy) const;
2641 const char *getSpelling() const;
2642
2643
2644 static bool classof(const Attr *A) { return A->getKind() == attr::ConsumableSetOnRead; }
2645};
2646
2647class ConvergentAttr : public InheritableAttr {
2648public:
2649 static ConvergentAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2650 auto *A = new (Ctx) ConvergentAttr(Loc, Ctx, 0);
2651 A->setImplicit(true);
2652 return A;
2653 }
2654
2655 ConvergentAttr(SourceRange R, ASTContext &Ctx
2656 , unsigned SI
2657 )
2658 : InheritableAttr(attr::Convergent, R, SI, false, false)
2659 {
2660 }
2661
2662 ConvergentAttr *clone(ASTContext &C) const;
2663 void printPretty(raw_ostream &OS,
2664 const PrintingPolicy &Policy) const;
2665 const char *getSpelling() const;
2666
2667
2668 static bool classof(const Attr *A) { return A->getKind() == attr::Convergent; }
2669};
2670
2671class DLLExportAttr : public InheritableAttr {
2672public:
2673 static DLLExportAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2674 auto *A = new (Ctx) DLLExportAttr(Loc, Ctx, 0);
2675 A->setImplicit(true);
2676 return A;
2677 }
2678
2679 DLLExportAttr(SourceRange R, ASTContext &Ctx
2680 , unsigned SI
2681 )
2682 : InheritableAttr(attr::DLLExport, R, SI, false, false)
2683 {
2684 }
2685
2686 DLLExportAttr *clone(ASTContext &C) const;
2687 void printPretty(raw_ostream &OS,
2688 const PrintingPolicy &Policy) const;
2689 const char *getSpelling() const;
2690
2691
2692 static bool classof(const Attr *A) { return A->getKind() == attr::DLLExport; }
2693};
2694
2695class DLLExportStaticLocalAttr : public InheritableAttr {
2696public:
2697 static DLLExportStaticLocalAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2698 auto *A = new (Ctx) DLLExportStaticLocalAttr(Loc, Ctx, 0);
2699 A->setImplicit(true);
2700 return A;
2701 }
2702
2703 DLLExportStaticLocalAttr(SourceRange R, ASTContext &Ctx
2704 , unsigned SI
2705 )
2706 : InheritableAttr(attr::DLLExportStaticLocal, R, SI, false, false)
2707 {
2708 }
2709
2710 DLLExportStaticLocalAttr *clone(ASTContext &C) const;
2711 void printPretty(raw_ostream &OS,
2712 const PrintingPolicy &Policy) const;
2713 const char *getSpelling() const;
2714
2715
2716 static bool classof(const Attr *A) { return A->getKind() == attr::DLLExportStaticLocal; }
2717};
2718
2719class DLLImportAttr : public InheritableAttr {
2720public:
2721 static DLLImportAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2722 auto *A = new (Ctx) DLLImportAttr(Loc, Ctx, 0);
2723 A->setImplicit(true);
2724 return A;
2725 }
2726
2727 DLLImportAttr(SourceRange R, ASTContext &Ctx
2728 , unsigned SI
2729 )
2730 : InheritableAttr(attr::DLLImport, R, SI, false, false)
2731 {
2732 }
2733
2734 DLLImportAttr *clone(ASTContext &C) const;
2735 void printPretty(raw_ostream &OS,
2736 const PrintingPolicy &Policy) const;
2737 const char *getSpelling() const;
2738
2739private:
2740 bool PropagatedToBaseTemplate = false;
2741
2742public:
2743 void setPropagatedToBaseTemplate() { PropagatedToBaseTemplate = true; }
2744 bool wasPropagatedToBaseTemplate() { return PropagatedToBaseTemplate; }
2745
2746
2747 static bool classof(const Attr *A) { return A->getKind() == attr::DLLImport; }
2748};
2749
2750class DLLImportStaticLocalAttr : public InheritableAttr {
2751public:
2752 static DLLImportStaticLocalAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
2753 auto *A = new (Ctx) DLLImportStaticLocalAttr(Loc, Ctx, 0);
2754 A->setImplicit(true);
2755 return A;
2756 }
2757
2758 DLLImportStaticLocalAttr(SourceRange R, ASTContext &Ctx
2759 , unsigned SI
2760 )
2761 : InheritableAttr(attr::DLLImportStaticLocal, R, SI, false, false)
2762 {
2763 }
2764
2765 DLLImportStaticLocalAttr *clone(ASTContext &C) const;
2766 void printPretty(raw_ostream &OS,
2767 const PrintingPolicy &Policy) const;
2768 const char *getSpelling() const;
2769
2770
2771 static bool classof(const Attr *A) { return A->getKind() == attr::DLLImportStaticLocal; }
2772};
2773
2774class DeprecatedAttr : public InheritableAttr {
2775unsigned messageLength;
2776char *message;
2777
2778unsigned replacementLength;
2779char *replacement;
2780
2781public:
2782 static DeprecatedAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, llvm::StringRef Replacement, SourceRange Loc = SourceRange()) {
2783 auto *A = new (Ctx) DeprecatedAttr(Loc, Ctx, Message, Replacement, 0);
2784 A->setImplicit(true);
2785 return A;
2786 }
2787
2788 DeprecatedAttr(SourceRange R, ASTContext &Ctx
2789 , llvm::StringRef Message
2790 , llvm::StringRef Replacement
2791 , unsigned SI
2792 )
2793 : InheritableAttr(attr::Deprecated, R, SI, false, false)
2794 , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
2795 , replacementLength(Replacement.size()),replacement(new (Ctx, 1) char[replacementLength])
2796 {
2797 if (!Message.empty())
2798 std::memcpy(message, Message.data(), messageLength);
2799 if (!Replacement.empty())
2800 std::memcpy(replacement, Replacement.data(), replacementLength);
2801 }
2802
2803 DeprecatedAttr(SourceRange R, ASTContext &Ctx
2804 , unsigned SI
2805 )
2806 : InheritableAttr(attr::Deprecated, R, SI, false, false)
2807 , messageLength(0),message(nullptr)
2808 , replacementLength(0),replacement(nullptr)
2809 {
2810 }
2811
2812 DeprecatedAttr *clone(ASTContext &C) const;
2813 void printPretty(raw_ostream &OS,
2814 const PrintingPolicy &Policy) const;
2815 const char *getSpelling() const;
2816 llvm::StringRef getMessage() const {
2817 return llvm::StringRef(message, messageLength);
2818 }
2819 unsigned getMessageLength() const {
2820 return messageLength;
2821 }
2822 void setMessage(ASTContext &C, llvm::StringRef S) {
2823 messageLength = S.size();
2824 this->message = new (C, 1) char [messageLength];
2825 if (!S.empty())
2826 std::memcpy(this->message, S.data(), messageLength);
2827 }
2828
2829 llvm::StringRef getReplacement() const {
2830 return llvm::StringRef(replacement, replacementLength);
2831 }
2832 unsigned getReplacementLength() const {
2833 return replacementLength;
2834 }
2835 void setReplacement(ASTContext &C, llvm::StringRef S) {
2836 replacementLength = S.size();
2837 this->replacement = new (C, 1) char [replacementLength];
2838 if (!S.empty())
2839 std::memcpy(this->replacement, S.data(), replacementLength);
2840 }
2841
2842
2843
2844 static bool classof(const Attr *A) { return A->getKind() == attr::Deprecated; }
2845};
2846
2847class DestructorAttr : public InheritableAttr {
2848int priority;
2849
2850public:
2851 static DestructorAttr *CreateImplicit(ASTContext &Ctx, int Priority, SourceRange Loc = SourceRange()) {
2852 auto *A = new (Ctx) DestructorAttr(Loc, Ctx, Priority, 0);
2853 A->setImplicit(true);
2854 return A;
2855 }
2856
2857 DestructorAttr(SourceRange R, ASTContext &Ctx
2858 , int Priority
2859 , unsigned SI
2860 )
2861 : InheritableAttr(attr::Destructor, R, SI, false, false)
2862 , priority(Priority)
2863 {
2864 }
2865
2866 DestructorAttr(SourceRange R, ASTContext &Ctx
2867 , unsigned SI
2868 )
2869 : InheritableAttr(attr::Destructor, R, SI, false, false)
2870 , priority()
2871 {
2872 }
2873
2874 DestructorAttr *clone(ASTContext &C) const;
2875 void printPretty(raw_ostream &OS,
2876 const PrintingPolicy &Policy) const;
2877 const char *getSpelling() const;
2878 int getPriority() const {
2879 return priority;
2880 }
2881
2882 static const int DefaultPriority = 65535;
2883
2884
2885
2886 static bool classof(const Attr *A) { return A->getKind() == attr::Destructor; }
2887};
2888
2889class DiagnoseIfAttr : public InheritableAttr {
2890Expr * cond;
2891
2892unsigned messageLength;
2893char *message;
2894
2895public:
2896 enum DiagnosticType {
2897 DT_Error,
2898 DT_Warning
2899 };
2900private:
2901 DiagnosticType diagnosticType;
2902
2903bool argDependent;
2904
2905NamedDecl * parent;
2906
2907public:
2908 static DiagnoseIfAttr *CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, bool ArgDependent, NamedDecl * Parent, SourceRange Loc = SourceRange()) {
2909 auto *A = new (Ctx) DiagnoseIfAttr(Loc, Ctx, Cond, Message, DiagnosticType, ArgDependent, Parent, 0);
2910 A->setImplicit(true);
2911 return A;
2912 }
2913
2914 static DiagnoseIfAttr *CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, DiagnosticType DiagnosticType, SourceRange Loc = SourceRange()) {
2915 auto *A = new (Ctx) DiagnoseIfAttr(Loc, Ctx, Cond, Message, DiagnosticType, 0);
2916 A->setImplicit(true);
2917 return A;
2918 }
2919
2920 DiagnoseIfAttr(SourceRange R, ASTContext &Ctx
2921 , Expr * Cond
2922 , llvm::StringRef Message
2923 , DiagnosticType DiagnosticType
2924 , bool ArgDependent
2925 , NamedDecl * Parent
2926 , unsigned SI
2927 )
2928 : InheritableAttr(attr::DiagnoseIf, R, SI, true, true)
2929 , cond(Cond)
2930 , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
2931 , diagnosticType(DiagnosticType)
2932 , argDependent(ArgDependent)
2933 , parent(Parent)
2934 {
2935 if (!Message.empty())
2936 std::memcpy(message, Message.data(), messageLength);
2937 }
2938
2939 DiagnoseIfAttr(SourceRange R, ASTContext &Ctx
2940 , Expr * Cond
2941 , llvm::StringRef Message
2942 , DiagnosticType DiagnosticType
2943 , unsigned SI
2944 )
2945 : InheritableAttr(attr::DiagnoseIf, R, SI, true, true)
2946 , cond(Cond)
2947 , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
2948 , diagnosticType(DiagnosticType)
2949 , argDependent()
2950 , parent()
2951 {
2952 if (!Message.empty())
2953 std::memcpy(message, Message.data(), messageLength);
2954 }
2955
2956 DiagnoseIfAttr *clone(ASTContext &C) const;
2957 void printPretty(raw_ostream &OS,
2958 const PrintingPolicy &Policy) const;
2959 const char *getSpelling() const;
2960 Expr * getCond() const {
2961 return cond;
2962 }
2963
2964 llvm::StringRef getMessage() const {
2965 return llvm::StringRef(message, messageLength);
2966 }
2967 unsigned getMessageLength() const {
2968 return messageLength;
2969 }
2970 void setMessage(ASTContext &C, llvm::StringRef S) {
2971 messageLength = S.size();
2972 this->message = new (C, 1) char [messageLength];
2973 if (!S.empty())
2974 std::memcpy(this->message, S.data(), messageLength);
2975 }
2976
2977 DiagnosticType getDiagnosticType() const {
2978 return diagnosticType;
2979 }
2980
2981 static bool ConvertStrToDiagnosticType(StringRef Val, DiagnosticType &Out) {
2982 Optional<DiagnosticType> R = llvm::StringSwitch<Optional<DiagnosticType>>(Val)
2983 .Case("error", DiagnoseIfAttr::DT_Error)
2984 .Case("warning", DiagnoseIfAttr::DT_Warning)
2985 .Default(Optional<DiagnosticType>());
2986 if (R) {
2987 Out = *R;
2988 return true;
2989 }
2990 return false;
2991 }
2992
2993 static const char *ConvertDiagnosticTypeToStr(DiagnosticType Val) {
2994 switch(Val) {
2995 case DiagnoseIfAttr::DT_Error: return "error";
2996 case DiagnoseIfAttr::DT_Warning: return "warning";
2997 }
2998 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 2998)
;
2999 }
3000 bool getArgDependent() const {
3001 return argDependent;
3002 }
3003
3004 NamedDecl * getParent() const {
3005 return parent;
3006 }
3007
3008
3009 bool isError() const { return diagnosticType == DT_Error; }
3010 bool isWarning() const { return diagnosticType == DT_Warning; }
3011
3012
3013 static bool classof(const Attr *A) { return A->getKind() == attr::DiagnoseIf; }
3014};
3015
3016class DisableTailCallsAttr : public InheritableAttr {
3017public:
3018 static DisableTailCallsAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3019 auto *A = new (Ctx) DisableTailCallsAttr(Loc, Ctx, 0);
3020 A->setImplicit(true);
3021 return A;
3022 }
3023
3024 DisableTailCallsAttr(SourceRange R, ASTContext &Ctx
3025 , unsigned SI
3026 )
3027 : InheritableAttr(attr::DisableTailCalls, R, SI, false, false)
3028 {
3029 }
3030
3031 DisableTailCallsAttr *clone(ASTContext &C) const;
3032 void printPretty(raw_ostream &OS,
3033 const PrintingPolicy &Policy) const;
3034 const char *getSpelling() const;
3035
3036
3037 static bool classof(const Attr *A) { return A->getKind() == attr::DisableTailCalls; }
3038};
3039
3040class EmptyBasesAttr : public InheritableAttr {
3041public:
3042 static EmptyBasesAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3043 auto *A = new (Ctx) EmptyBasesAttr(Loc, Ctx, 0);
3044 A->setImplicit(true);
3045 return A;
3046 }
3047
3048 EmptyBasesAttr(SourceRange R, ASTContext &Ctx
3049 , unsigned SI
3050 )
3051 : InheritableAttr(attr::EmptyBases, R, SI, false, false)
3052 {
3053 }
3054
3055 EmptyBasesAttr *clone(ASTContext &C) const;
3056 void printPretty(raw_ostream &OS,
3057 const PrintingPolicy &Policy) const;
3058 const char *getSpelling() const;
3059
3060
3061 static bool classof(const Attr *A) { return A->getKind() == attr::EmptyBases; }
3062};
3063
3064class EnableIfAttr : public InheritableAttr {
3065Expr * cond;
3066
3067unsigned messageLength;
3068char *message;
3069
3070public:
3071 static EnableIfAttr *CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, SourceRange Loc = SourceRange()) {
3072 auto *A = new (Ctx) EnableIfAttr(Loc, Ctx, Cond, Message, 0);
3073 A->setImplicit(true);
3074 return A;
3075 }
3076
3077 EnableIfAttr(SourceRange R, ASTContext &Ctx
3078 , Expr * Cond
3079 , llvm::StringRef Message
3080 , unsigned SI
3081 )
3082 : InheritableAttr(attr::EnableIf, R, SI, false, false)
3083 , cond(Cond)
3084 , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
3085 {
3086 if (!Message.empty())
3087 std::memcpy(message, Message.data(), messageLength);
3088 }
3089
3090 EnableIfAttr *clone(ASTContext &C) const;
3091 void printPretty(raw_ostream &OS,
3092 const PrintingPolicy &Policy) const;
3093 const char *getSpelling() const;
3094 Expr * getCond() const {
3095 return cond;
3096 }
3097
3098 llvm::StringRef getMessage() const {
3099 return llvm::StringRef(message, messageLength);
3100 }
3101 unsigned getMessageLength() const {
3102 return messageLength;
3103 }
3104 void setMessage(ASTContext &C, llvm::StringRef S) {
3105 messageLength = S.size();
3106 this->message = new (C, 1) char [messageLength];
3107 if (!S.empty())
3108 std::memcpy(this->message, S.data(), messageLength);
3109 }
3110
3111
3112
3113 static bool classof(const Attr *A) { return A->getKind() == attr::EnableIf; }
3114};
3115
3116class EnumExtensibilityAttr : public InheritableAttr {
3117public:
3118 enum Kind {
3119 Closed,
3120 Open
3121 };
3122private:
3123 Kind extensibility;
3124
3125public:
3126 static EnumExtensibilityAttr *CreateImplicit(ASTContext &Ctx, Kind Extensibility, SourceRange Loc = SourceRange()) {
3127 auto *A = new (Ctx) EnumExtensibilityAttr(Loc, Ctx, Extensibility, 0);
3128 A->setImplicit(true);
3129 return A;
3130 }
3131
3132 EnumExtensibilityAttr(SourceRange R, ASTContext &Ctx
3133 , Kind Extensibility
3134 , unsigned SI
3135 )
3136 : InheritableAttr(attr::EnumExtensibility, R, SI, false, false)
3137 , extensibility(Extensibility)
3138 {
3139 }
3140
3141 EnumExtensibilityAttr *clone(ASTContext &C) const;
3142 void printPretty(raw_ostream &OS,
3143 const PrintingPolicy &Policy) const;
3144 const char *getSpelling() const;
3145 Kind getExtensibility() const {
3146 return extensibility;
3147 }
3148
3149 static bool ConvertStrToKind(StringRef Val, Kind &Out) {
3150 Optional<Kind> R = llvm::StringSwitch<Optional<Kind>>(Val)
3151 .Case("closed", EnumExtensibilityAttr::Closed)
3152 .Case("open", EnumExtensibilityAttr::Open)
3153 .Default(Optional<Kind>());
3154 if (R) {
3155 Out = *R;
3156 return true;
3157 }
3158 return false;
3159 }
3160
3161 static const char *ConvertKindToStr(Kind Val) {
3162 switch(Val) {
3163 case EnumExtensibilityAttr::Closed: return "closed";
3164 case EnumExtensibilityAttr::Open: return "open";
3165 }
3166 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 3166)
;
3167 }
3168
3169
3170 static bool classof(const Attr *A) { return A->getKind() == attr::EnumExtensibility; }
3171};
3172
3173class ExcludeFromExplicitInstantiationAttr : public InheritableAttr {
3174public:
3175 static ExcludeFromExplicitInstantiationAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3176 auto *A = new (Ctx) ExcludeFromExplicitInstantiationAttr(Loc, Ctx, 0);
3177 A->setImplicit(true);
3178 return A;
3179 }
3180
3181 ExcludeFromExplicitInstantiationAttr(SourceRange R, ASTContext &Ctx
3182 , unsigned SI
3183 )
3184 : InheritableAttr(attr::ExcludeFromExplicitInstantiation, R, SI, false, false)
3185 {
3186 }
3187
3188 ExcludeFromExplicitInstantiationAttr *clone(ASTContext &C) const;
3189 void printPretty(raw_ostream &OS,
3190 const PrintingPolicy &Policy) const;
3191 const char *getSpelling() const;
3192
3193
3194 static bool classof(const Attr *A) { return A->getKind() == attr::ExcludeFromExplicitInstantiation; }
3195};
3196
3197class ExclusiveTrylockFunctionAttr : public InheritableAttr {
3198Expr * successValue;
3199
3200 unsigned args_Size;
3201 Expr * *args_;
3202
3203public:
3204 static ExclusiveTrylockFunctionAttr *CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
3205 auto *A = new (Ctx) ExclusiveTrylockFunctionAttr(Loc, Ctx, SuccessValue, Args, ArgsSize, 0);
3206 A->setImplicit(true);
3207 return A;
3208 }
3209
3210 ExclusiveTrylockFunctionAttr(SourceRange R, ASTContext &Ctx
3211 , Expr * SuccessValue
3212 , Expr * *Args, unsigned ArgsSize
3213 , unsigned SI
3214 )
3215 : InheritableAttr(attr::ExclusiveTrylockFunction, R, SI, true, true)
3216 , successValue(SuccessValue)
3217 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
3218 {
3219 std::copy(Args, Args + args_Size, args_);
3220 }
3221
3222 ExclusiveTrylockFunctionAttr(SourceRange R, ASTContext &Ctx
3223 , Expr * SuccessValue
3224 , unsigned SI
3225 )
3226 : InheritableAttr(attr::ExclusiveTrylockFunction, R, SI, true, true)
3227 , successValue(SuccessValue)
3228 , args_Size(0), args_(nullptr)
3229 {
3230 }
3231
3232 ExclusiveTrylockFunctionAttr *clone(ASTContext &C) const;
3233 void printPretty(raw_ostream &OS,
3234 const PrintingPolicy &Policy) const;
3235 const char *getSpelling() const;
3236 Expr * getSuccessValue() const {
3237 return successValue;
3238 }
3239
3240 typedef Expr ** args_iterator;
3241 args_iterator args_begin() const { return args_; }
3242 args_iterator args_end() const { return args_ + args_Size; }
3243 unsigned args_size() const { return args_Size; }
3244 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
3245
3246
3247
3248
3249 static bool classof(const Attr *A) { return A->getKind() == attr::ExclusiveTrylockFunction; }
3250};
3251
3252class ExternalSourceSymbolAttr : public InheritableAttr {
3253unsigned languageLength;
3254char *language;
3255
3256unsigned definedInLength;
3257char *definedIn;
3258
3259bool generatedDeclaration;
3260
3261public:
3262 static ExternalSourceSymbolAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Language, llvm::StringRef DefinedIn, bool GeneratedDeclaration, SourceRange Loc = SourceRange()) {
3263 auto *A = new (Ctx) ExternalSourceSymbolAttr(Loc, Ctx, Language, DefinedIn, GeneratedDeclaration, 0);
3264 A->setImplicit(true);
3265 return A;
3266 }
3267
3268 ExternalSourceSymbolAttr(SourceRange R, ASTContext &Ctx
3269 , llvm::StringRef Language
3270 , llvm::StringRef DefinedIn
3271 , bool GeneratedDeclaration
3272 , unsigned SI
3273 )
3274 : InheritableAttr(attr::ExternalSourceSymbol, R, SI, false, false)
3275 , languageLength(Language.size()),language(new (Ctx, 1) char[languageLength])
3276 , definedInLength(DefinedIn.size()),definedIn(new (Ctx, 1) char[definedInLength])
3277 , generatedDeclaration(GeneratedDeclaration)
3278 {
3279 if (!Language.empty())
3280 std::memcpy(language, Language.data(), languageLength);
3281 if (!DefinedIn.empty())
3282 std::memcpy(definedIn, DefinedIn.data(), definedInLength);
3283 }
3284
3285 ExternalSourceSymbolAttr(SourceRange R, ASTContext &Ctx
3286 , unsigned SI
3287 )
3288 : InheritableAttr(attr::ExternalSourceSymbol, R, SI, false, false)
3289 , languageLength(0),language(nullptr)
3290 , definedInLength(0),definedIn(nullptr)
3291 , generatedDeclaration()
3292 {
3293 }
3294
3295 ExternalSourceSymbolAttr *clone(ASTContext &C) const;
3296 void printPretty(raw_ostream &OS,
3297 const PrintingPolicy &Policy) const;
3298 const char *getSpelling() const;
3299 llvm::StringRef getLanguage() const {
3300 return llvm::StringRef(language, languageLength);
3301 }
3302 unsigned getLanguageLength() const {
3303 return languageLength;
3304 }
3305 void setLanguage(ASTContext &C, llvm::StringRef S) {
3306 languageLength = S.size();
3307 this->language = new (C, 1) char [languageLength];
3308 if (!S.empty())
3309 std::memcpy(this->language, S.data(), languageLength);
3310 }
3311
3312 llvm::StringRef getDefinedIn() const {
3313 return llvm::StringRef(definedIn, definedInLength);
3314 }
3315 unsigned getDefinedInLength() const {
3316 return definedInLength;
3317 }
3318 void setDefinedIn(ASTContext &C, llvm::StringRef S) {
3319 definedInLength = S.size();
3320 this->definedIn = new (C, 1) char [definedInLength];
3321 if (!S.empty())
3322 std::memcpy(this->definedIn, S.data(), definedInLength);
3323 }
3324
3325 bool getGeneratedDeclaration() const {
3326 return generatedDeclaration;
3327 }
3328
3329
3330
3331 static bool classof(const Attr *A) { return A->getKind() == attr::ExternalSourceSymbol; }
3332};
3333
3334class FallThroughAttr : public StmtAttr {
3335public:
3336 static FallThroughAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3337 auto *A = new (Ctx) FallThroughAttr(Loc, Ctx, 0);
3338 A->setImplicit(true);
3339 return A;
3340 }
3341
3342 FallThroughAttr(SourceRange R, ASTContext &Ctx
3343 , unsigned SI
3344 )
3345 : StmtAttr(attr::FallThrough, R, SI, false)
3346 {
3347 }
3348
3349 FallThroughAttr *clone(ASTContext &C) const;
3350 void printPretty(raw_ostream &OS,
3351 const PrintingPolicy &Policy) const;
3352 const char *getSpelling() const;
3353
3354
3355 static bool classof(const Attr *A) { return A->getKind() == attr::FallThrough; }
3356};
3357
3358class FastCallAttr : public InheritableAttr {
3359public:
3360 static FastCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3361 auto *A = new (Ctx) FastCallAttr(Loc, Ctx, 0);
3362 A->setImplicit(true);
3363 return A;
3364 }
3365
3366 FastCallAttr(SourceRange R, ASTContext &Ctx
3367 , unsigned SI
3368 )
3369 : InheritableAttr(attr::FastCall, R, SI, false, false)
3370 {
3371 }
3372
3373 FastCallAttr *clone(ASTContext &C) const;
3374 void printPretty(raw_ostream &OS,
3375 const PrintingPolicy &Policy) const;
3376 const char *getSpelling() const;
3377
3378
3379 static bool classof(const Attr *A) { return A->getKind() == attr::FastCall; }
3380};
3381
3382class FinalAttr : public InheritableAttr {
3383public:
3384 enum Spelling {
3385 Keyword_final = 0,
3386 Keyword_sealed = 1
3387 };
3388
3389 static FinalAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
3390 auto *A = new (Ctx) FinalAttr(Loc, Ctx, S);
3391 A->setImplicit(true);
3392 return A;
3393 }
3394
3395 FinalAttr(SourceRange R, ASTContext &Ctx
3396 , unsigned SI
3397 )
3398 : InheritableAttr(attr::Final, R, SI, false, false)
3399 {
3400 }
3401
3402 FinalAttr *clone(ASTContext &C) const;
3403 void printPretty(raw_ostream &OS,
3404 const PrintingPolicy &Policy) const;
3405 const char *getSpelling() const;
3406 Spelling getSemanticSpelling() const {
3407 switch (SpellingListIndex) {
3408 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 3408)
;
3409 case 0: return Keyword_final;
3410 case 1: return Keyword_sealed;
3411 }
3412 }
3413 bool isSpelledAsSealed() const { return SpellingListIndex == 1; }
3414
3415
3416 static bool classof(const Attr *A) { return A->getKind() == attr::Final; }
3417};
3418
3419class FlagEnumAttr : public InheritableAttr {
3420public:
3421 static FlagEnumAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3422 auto *A = new (Ctx) FlagEnumAttr(Loc, Ctx, 0);
3423 A->setImplicit(true);
3424 return A;
3425 }
3426
3427 FlagEnumAttr(SourceRange R, ASTContext &Ctx
3428 , unsigned SI
3429 )
3430 : InheritableAttr(attr::FlagEnum, R, SI, false, false)
3431 {
3432 }
3433
3434 FlagEnumAttr *clone(ASTContext &C) const;
3435 void printPretty(raw_ostream &OS,
3436 const PrintingPolicy &Policy) const;
3437 const char *getSpelling() const;
3438
3439
3440 static bool classof(const Attr *A) { return A->getKind() == attr::FlagEnum; }
3441};
3442
3443class FlattenAttr : public InheritableAttr {
3444public:
3445 static FlattenAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3446 auto *A = new (Ctx) FlattenAttr(Loc, Ctx, 0);
3447 A->setImplicit(true);
3448 return A;
3449 }
3450
3451 FlattenAttr(SourceRange R, ASTContext &Ctx
3452 , unsigned SI
3453 )
3454 : InheritableAttr(attr::Flatten, R, SI, false, false)
3455 {
3456 }
3457
3458 FlattenAttr *clone(ASTContext &C) const;
3459 void printPretty(raw_ostream &OS,
3460 const PrintingPolicy &Policy) const;
3461 const char *getSpelling() const;
3462
3463
3464 static bool classof(const Attr *A) { return A->getKind() == attr::Flatten; }
3465};
3466
3467class FormatAttr : public InheritableAttr {
3468IdentifierInfo * type;
3469
3470int formatIdx;
3471
3472int firstArg;
3473
3474public:
3475 static FormatAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * Type, int FormatIdx, int FirstArg, SourceRange Loc = SourceRange()) {
3476 auto *A = new (Ctx) FormatAttr(Loc, Ctx, Type, FormatIdx, FirstArg, 0);
3477 A->setImplicit(true);
3478 return A;
3479 }
3480
3481 FormatAttr(SourceRange R, ASTContext &Ctx
3482 , IdentifierInfo * Type
3483 , int FormatIdx
3484 , int FirstArg
3485 , unsigned SI
3486 )
3487 : InheritableAttr(attr::Format, R, SI, false, false)
3488 , type(Type)
3489 , formatIdx(FormatIdx)
3490 , firstArg(FirstArg)
3491 {
3492 }
3493
3494 FormatAttr *clone(ASTContext &C) const;
3495 void printPretty(raw_ostream &OS,
3496 const PrintingPolicy &Policy) const;
3497 const char *getSpelling() const;
3498 IdentifierInfo * getType() const {
3499 return type;
3500 }
3501
3502 int getFormatIdx() const {
3503 return formatIdx;
3504 }
3505
3506 int getFirstArg() const {
3507 return firstArg;
3508 }
3509
3510
3511
3512 static bool classof(const Attr *A) { return A->getKind() == attr::Format; }
3513};
3514
3515class FormatArgAttr : public InheritableAttr {
3516ParamIdx formatIdx;
3517
3518public:
3519 static FormatArgAttr *CreateImplicit(ASTContext &Ctx, ParamIdx FormatIdx, SourceRange Loc = SourceRange()) {
3520 auto *A = new (Ctx) FormatArgAttr(Loc, Ctx, FormatIdx, 0);
3521 A->setImplicit(true);
3522 return A;
3523 }
3524
3525 FormatArgAttr(SourceRange R, ASTContext &Ctx
3526 , ParamIdx FormatIdx
3527 , unsigned SI
3528 )
3529 : InheritableAttr(attr::FormatArg, R, SI, false, false)
3530 , formatIdx(FormatIdx)
3531 {
3532 }
3533
3534 FormatArgAttr *clone(ASTContext &C) const;
3535 void printPretty(raw_ostream &OS,
3536 const PrintingPolicy &Policy) const;
3537 const char *getSpelling() const;
3538 ParamIdx getFormatIdx() const {
3539 return formatIdx;
3540 }
3541
3542
3543
3544 static bool classof(const Attr *A) { return A->getKind() == attr::FormatArg; }
3545};
3546
3547class GNUInlineAttr : public InheritableAttr {
3548public:
3549 static GNUInlineAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3550 auto *A = new (Ctx) GNUInlineAttr(Loc, Ctx, 0);
3551 A->setImplicit(true);
3552 return A;
3553 }
3554
3555 GNUInlineAttr(SourceRange R, ASTContext &Ctx
3556 , unsigned SI
3557 )
3558 : InheritableAttr(attr::GNUInline, R, SI, false, false)
3559 {
3560 }
3561
3562 GNUInlineAttr *clone(ASTContext &C) const;
3563 void printPretty(raw_ostream &OS,
3564 const PrintingPolicy &Policy) const;
3565 const char *getSpelling() const;
3566
3567
3568 static bool classof(const Attr *A) { return A->getKind() == attr::GNUInline; }
3569};
3570
3571class GuardedByAttr : public InheritableAttr {
3572Expr * arg;
3573
3574public:
3575 static GuardedByAttr *CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Loc = SourceRange()) {
3576 auto *A = new (Ctx) GuardedByAttr(Loc, Ctx, Arg, 0);
3577 A->setImplicit(true);
3578 return A;
3579 }
3580
3581 GuardedByAttr(SourceRange R, ASTContext &Ctx
3582 , Expr * Arg
3583 , unsigned SI
3584 )
3585 : InheritableAttr(attr::GuardedBy, R, SI, true, true)
3586 , arg(Arg)
3587 {
3588 }
3589
3590 GuardedByAttr *clone(ASTContext &C) const;
3591 void printPretty(raw_ostream &OS,
3592 const PrintingPolicy &Policy) const;
3593 const char *getSpelling() const;
3594 Expr * getArg() const {
3595 return arg;
3596 }
3597
3598
3599
3600 static bool classof(const Attr *A) { return A->getKind() == attr::GuardedBy; }
3601};
3602
3603class GuardedVarAttr : public InheritableAttr {
3604public:
3605 static GuardedVarAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3606 auto *A = new (Ctx) GuardedVarAttr(Loc, Ctx, 0);
3607 A->setImplicit(true);
3608 return A;
3609 }
3610
3611 GuardedVarAttr(SourceRange R, ASTContext &Ctx
3612 , unsigned SI
3613 )
3614 : InheritableAttr(attr::GuardedVar, R, SI, false, false)
3615 {
3616 }
3617
3618 GuardedVarAttr *clone(ASTContext &C) const;
3619 void printPretty(raw_ostream &OS,
3620 const PrintingPolicy &Policy) const;
3621 const char *getSpelling() const;
3622
3623
3624 static bool classof(const Attr *A) { return A->getKind() == attr::GuardedVar; }
3625};
3626
3627class HotAttr : public InheritableAttr {
3628public:
3629 static HotAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3630 auto *A = new (Ctx) HotAttr(Loc, Ctx, 0);
3631 A->setImplicit(true);
3632 return A;
3633 }
3634
3635 HotAttr(SourceRange R, ASTContext &Ctx
3636 , unsigned SI
3637 )
3638 : InheritableAttr(attr::Hot, R, SI, false, false)
3639 {
3640 }
3641
3642 HotAttr *clone(ASTContext &C) const;
3643 void printPretty(raw_ostream &OS,
3644 const PrintingPolicy &Policy) const;
3645 const char *getSpelling() const;
3646
3647
3648 static bool classof(const Attr *A) { return A->getKind() == attr::Hot; }
3649};
3650
3651class IBActionAttr : public InheritableAttr {
3652public:
3653 static IBActionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3654 auto *A = new (Ctx) IBActionAttr(Loc, Ctx, 0);
3655 A->setImplicit(true);
3656 return A;
3657 }
3658
3659 IBActionAttr(SourceRange R, ASTContext &Ctx
3660 , unsigned SI
3661 )
3662 : InheritableAttr(attr::IBAction, R, SI, false, false)
3663 {
3664 }
3665
3666 IBActionAttr *clone(ASTContext &C) const;
3667 void printPretty(raw_ostream &OS,
3668 const PrintingPolicy &Policy) const;
3669 const char *getSpelling() const;
3670
3671
3672 static bool classof(const Attr *A) { return A->getKind() == attr::IBAction; }
3673};
3674
3675class IBOutletAttr : public InheritableAttr {
3676public:
3677 static IBOutletAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3678 auto *A = new (Ctx) IBOutletAttr(Loc, Ctx, 0);
3679 A->setImplicit(true);
3680 return A;
3681 }
3682
3683 IBOutletAttr(SourceRange R, ASTContext &Ctx
3684 , unsigned SI
3685 )
3686 : InheritableAttr(attr::IBOutlet, R, SI, false, false)
3687 {
3688 }
3689
3690 IBOutletAttr *clone(ASTContext &C) const;
3691 void printPretty(raw_ostream &OS,
3692 const PrintingPolicy &Policy) const;
3693 const char *getSpelling() const;
3694
3695
3696 static bool classof(const Attr *A) { return A->getKind() == attr::IBOutlet; }
3697};
3698
3699class IBOutletCollectionAttr : public InheritableAttr {
3700TypeSourceInfo * interface_;
3701
3702public:
3703 static IBOutletCollectionAttr *CreateImplicit(ASTContext &Ctx, TypeSourceInfo * Interface, SourceRange Loc = SourceRange()) {
3704 auto *A = new (Ctx) IBOutletCollectionAttr(Loc, Ctx, Interface, 0);
3705 A->setImplicit(true);
3706 return A;
3707 }
3708
3709 IBOutletCollectionAttr(SourceRange R, ASTContext &Ctx
3710 , TypeSourceInfo * Interface
3711 , unsigned SI
3712 )
3713 : InheritableAttr(attr::IBOutletCollection, R, SI, false, false)
3714 , interface_(Interface)
3715 {
3716 }
3717
3718 IBOutletCollectionAttr(SourceRange R, ASTContext &Ctx
3719 , unsigned SI
3720 )
3721 : InheritableAttr(attr::IBOutletCollection, R, SI, false, false)
3722 , interface_()
3723 {
3724 }
3725
3726 IBOutletCollectionAttr *clone(ASTContext &C) const;
3727 void printPretty(raw_ostream &OS,
3728 const PrintingPolicy &Policy) const;
3729 const char *getSpelling() const;
3730 QualType getInterface() const {
3731 return interface_->getType();
3732 } TypeSourceInfo * getInterfaceLoc() const {
3733 return interface_;
3734 }
3735
3736
3737
3738 static bool classof(const Attr *A) { return A->getKind() == attr::IBOutletCollection; }
3739};
3740
3741class IFuncAttr : public Attr {
3742unsigned resolverLength;
3743char *resolver;
3744
3745public:
3746 static IFuncAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Resolver, SourceRange Loc = SourceRange()) {
3747 auto *A = new (Ctx) IFuncAttr(Loc, Ctx, Resolver, 0);
3748 A->setImplicit(true);
3749 return A;
3750 }
3751
3752 IFuncAttr(SourceRange R, ASTContext &Ctx
3753 , llvm::StringRef Resolver
3754 , unsigned SI
3755 )
3756 : Attr(attr::IFunc, R, SI, false)
3757 , resolverLength(Resolver.size()),resolver(new (Ctx, 1) char[resolverLength])
3758 {
3759 if (!Resolver.empty())
3760 std::memcpy(resolver, Resolver.data(), resolverLength);
3761 }
3762
3763 IFuncAttr *clone(ASTContext &C) const;
3764 void printPretty(raw_ostream &OS,
3765 const PrintingPolicy &Policy) const;
3766 const char *getSpelling() const;
3767 llvm::StringRef getResolver() const {
3768 return llvm::StringRef(resolver, resolverLength);
3769 }
3770 unsigned getResolverLength() const {
3771 return resolverLength;
3772 }
3773 void setResolver(ASTContext &C, llvm::StringRef S) {
3774 resolverLength = S.size();
3775 this->resolver = new (C, 1) char [resolverLength];
3776 if (!S.empty())
3777 std::memcpy(this->resolver, S.data(), resolverLength);
3778 }
3779
3780
3781
3782 static bool classof(const Attr *A) { return A->getKind() == attr::IFunc; }
3783};
3784
3785class InitPriorityAttr : public InheritableAttr {
3786unsigned priority;
3787
3788public:
3789 static InitPriorityAttr *CreateImplicit(ASTContext &Ctx, unsigned Priority, SourceRange Loc = SourceRange()) {
3790 auto *A = new (Ctx) InitPriorityAttr(Loc, Ctx, Priority, 0);
3791 A->setImplicit(true);
3792 return A;
3793 }
3794
3795 InitPriorityAttr(SourceRange R, ASTContext &Ctx
3796 , unsigned Priority
3797 , unsigned SI
3798 )
3799 : InheritableAttr(attr::InitPriority, R, SI, false, false)
3800 , priority(Priority)
3801 {
3802 }
3803
3804 InitPriorityAttr *clone(ASTContext &C) const;
3805 void printPretty(raw_ostream &OS,
3806 const PrintingPolicy &Policy) const;
3807 const char *getSpelling() const;
3808 unsigned getPriority() const {
3809 return priority;
3810 }
3811
3812
3813
3814 static bool classof(const Attr *A) { return A->getKind() == attr::InitPriority; }
3815};
3816
3817class InitSegAttr : public Attr {
3818unsigned sectionLength;
3819char *section;
3820
3821public:
3822 static InitSegAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Section, SourceRange Loc = SourceRange()) {
3823 auto *A = new (Ctx) InitSegAttr(Loc, Ctx, Section, 0);
3824 A->setImplicit(true);
3825 return A;
3826 }
3827
3828 InitSegAttr(SourceRange R, ASTContext &Ctx
3829 , llvm::StringRef Section
3830 , unsigned SI
3831 )
3832 : Attr(attr::InitSeg, R, SI, false)
3833 , sectionLength(Section.size()),section(new (Ctx, 1) char[sectionLength])
3834 {
3835 if (!Section.empty())
3836 std::memcpy(section, Section.data(), sectionLength);
3837 }
3838
3839 InitSegAttr *clone(ASTContext &C) const;
3840 void printPretty(raw_ostream &OS,
3841 const PrintingPolicy &Policy) const;
3842 const char *getSpelling() const;
3843 llvm::StringRef getSection() const {
3844 return llvm::StringRef(section, sectionLength);
3845 }
3846 unsigned getSectionLength() const {
3847 return sectionLength;
3848 }
3849 void setSection(ASTContext &C, llvm::StringRef S) {
3850 sectionLength = S.size();
3851 this->section = new (C, 1) char [sectionLength];
3852 if (!S.empty())
3853 std::memcpy(this->section, S.data(), sectionLength);
3854 }
3855
3856
3857 void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
3858 OS << " (" << getSection() << ')';
3859 }
3860
3861
3862 static bool classof(const Attr *A) { return A->getKind() == attr::InitSeg; }
3863};
3864
3865class IntelOclBiccAttr : public InheritableAttr {
3866public:
3867 static IntelOclBiccAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3868 auto *A = new (Ctx) IntelOclBiccAttr(Loc, Ctx, 0);
3869 A->setImplicit(true);
3870 return A;
3871 }
3872
3873 IntelOclBiccAttr(SourceRange R, ASTContext &Ctx
3874 , unsigned SI
3875 )
3876 : InheritableAttr(attr::IntelOclBicc, R, SI, false, false)
3877 {
3878 }
3879
3880 IntelOclBiccAttr *clone(ASTContext &C) const;
3881 void printPretty(raw_ostream &OS,
3882 const PrintingPolicy &Policy) const;
3883 const char *getSpelling() const;
3884
3885
3886 static bool classof(const Attr *A) { return A->getKind() == attr::IntelOclBicc; }
3887};
3888
3889class InternalLinkageAttr : public InheritableAttr {
3890public:
3891 static InternalLinkageAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3892 auto *A = new (Ctx) InternalLinkageAttr(Loc, Ctx, 0);
3893 A->setImplicit(true);
3894 return A;
3895 }
3896
3897 InternalLinkageAttr(SourceRange R, ASTContext &Ctx
3898 , unsigned SI
3899 )
3900 : InheritableAttr(attr::InternalLinkage, R, SI, false, false)
3901 {
3902 }
3903
3904 InternalLinkageAttr *clone(ASTContext &C) const;
3905 void printPretty(raw_ostream &OS,
3906 const PrintingPolicy &Policy) const;
3907 const char *getSpelling() const;
3908
3909
3910 static bool classof(const Attr *A) { return A->getKind() == attr::InternalLinkage; }
3911};
3912
3913class LTOVisibilityPublicAttr : public InheritableAttr {
3914public:
3915 static LTOVisibilityPublicAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3916 auto *A = new (Ctx) LTOVisibilityPublicAttr(Loc, Ctx, 0);
3917 A->setImplicit(true);
3918 return A;
3919 }
3920
3921 LTOVisibilityPublicAttr(SourceRange R, ASTContext &Ctx
3922 , unsigned SI
3923 )
3924 : InheritableAttr(attr::LTOVisibilityPublic, R, SI, false, false)
3925 {
3926 }
3927
3928 LTOVisibilityPublicAttr *clone(ASTContext &C) const;
3929 void printPretty(raw_ostream &OS,
3930 const PrintingPolicy &Policy) const;
3931 const char *getSpelling() const;
3932
3933
3934 static bool classof(const Attr *A) { return A->getKind() == attr::LTOVisibilityPublic; }
3935};
3936
3937class LayoutVersionAttr : public InheritableAttr {
3938unsigned version;
3939
3940public:
3941 static LayoutVersionAttr *CreateImplicit(ASTContext &Ctx, unsigned Version, SourceRange Loc = SourceRange()) {
3942 auto *A = new (Ctx) LayoutVersionAttr(Loc, Ctx, Version, 0);
3943 A->setImplicit(true);
3944 return A;
3945 }
3946
3947 LayoutVersionAttr(SourceRange R, ASTContext &Ctx
3948 , unsigned Version
3949 , unsigned SI
3950 )
3951 : InheritableAttr(attr::LayoutVersion, R, SI, false, false)
3952 , version(Version)
3953 {
3954 }
3955
3956 LayoutVersionAttr *clone(ASTContext &C) const;
3957 void printPretty(raw_ostream &OS,
3958 const PrintingPolicy &Policy) const;
3959 const char *getSpelling() const;
3960 unsigned getVersion() const {
3961 return version;
3962 }
3963
3964
3965
3966 static bool classof(const Attr *A) { return A->getKind() == attr::LayoutVersion; }
3967};
3968
3969class LifetimeBoundAttr : public InheritableAttr {
3970public:
3971 static LifetimeBoundAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
3972 auto *A = new (Ctx) LifetimeBoundAttr(Loc, Ctx, 0);
3973 A->setImplicit(true);
3974 return A;
3975 }
3976
3977 LifetimeBoundAttr(SourceRange R, ASTContext &Ctx
3978 , unsigned SI
3979 )
3980 : InheritableAttr(attr::LifetimeBound, R, SI, false, false)
3981 {
3982 }
3983
3984 LifetimeBoundAttr *clone(ASTContext &C) const;
3985 void printPretty(raw_ostream &OS,
3986 const PrintingPolicy &Policy) const;
3987 const char *getSpelling() const;
3988
3989
3990 static bool classof(const Attr *A) { return A->getKind() == attr::LifetimeBound; }
3991};
3992
3993class LockReturnedAttr : public InheritableAttr {
3994Expr * arg;
3995
3996public:
3997 static LockReturnedAttr *CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Loc = SourceRange()) {
3998 auto *A = new (Ctx) LockReturnedAttr(Loc, Ctx, Arg, 0);
3999 A->setImplicit(true);
4000 return A;
4001 }
4002
4003 LockReturnedAttr(SourceRange R, ASTContext &Ctx
4004 , Expr * Arg
4005 , unsigned SI
4006 )
4007 : InheritableAttr(attr::LockReturned, R, SI, true, false)
4008 , arg(Arg)
4009 {
4010 }
4011
4012 LockReturnedAttr *clone(ASTContext &C) const;
4013 void printPretty(raw_ostream &OS,
4014 const PrintingPolicy &Policy) const;
4015 const char *getSpelling() const;
4016 Expr * getArg() const {
4017 return arg;
4018 }
4019
4020
4021
4022 static bool classof(const Attr *A) { return A->getKind() == attr::LockReturned; }
4023};
4024
4025class LocksExcludedAttr : public InheritableAttr {
4026 unsigned args_Size;
4027 Expr * *args_;
4028
4029public:
4030 static LocksExcludedAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
4031 auto *A = new (Ctx) LocksExcludedAttr(Loc, Ctx, Args, ArgsSize, 0);
4032 A->setImplicit(true);
4033 return A;
4034 }
4035
4036 LocksExcludedAttr(SourceRange R, ASTContext &Ctx
4037 , Expr * *Args, unsigned ArgsSize
4038 , unsigned SI
4039 )
4040 : InheritableAttr(attr::LocksExcluded, R, SI, true, true)
4041 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
4042 {
4043 std::copy(Args, Args + args_Size, args_);
4044 }
4045
4046 LocksExcludedAttr(SourceRange R, ASTContext &Ctx
4047 , unsigned SI
4048 )
4049 : InheritableAttr(attr::LocksExcluded, R, SI, true, true)
4050 , args_Size(0), args_(nullptr)
4051 {
4052 }
4053
4054 LocksExcludedAttr *clone(ASTContext &C) const;
4055 void printPretty(raw_ostream &OS,
4056 const PrintingPolicy &Policy) const;
4057 const char *getSpelling() const;
4058 typedef Expr ** args_iterator;
4059 args_iterator args_begin() const { return args_; }
4060 args_iterator args_end() const { return args_ + args_Size; }
4061 unsigned args_size() const { return args_Size; }
4062 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
4063
4064
4065
4066
4067 static bool classof(const Attr *A) { return A->getKind() == attr::LocksExcluded; }
4068};
4069
4070class LoopHintAttr : public Attr {
4071public:
4072 enum OptionType {
4073 Vectorize,
4074 VectorizeWidth,
4075 Interleave,
4076 InterleaveCount,
4077 Unroll,
4078 UnrollCount,
4079 UnrollAndJam,
4080 UnrollAndJamCount,
4081 PipelineDisabled,
4082 PipelineInitiationInterval,
4083 Distribute
4084 };
4085private:
4086 OptionType option;
4087
4088public:
4089 enum LoopHintState {
4090 Enable,
4091 Disable,
4092 Numeric,
4093 AssumeSafety,
4094 Full
4095 };
4096private:
4097 LoopHintState state;
4098
4099Expr * value;
4100
4101public:
4102 enum Spelling {
4103 Pragma_clang_loop = 0,
4104 Pragma_unroll = 1,
4105 Pragma_nounroll = 2,
4106 Pragma_unroll_and_jam = 3,
4107 Pragma_nounroll_and_jam = 4
4108 };
4109
4110 static LoopHintAttr *CreateImplicit(ASTContext &Ctx, Spelling S, OptionType Option, LoopHintState State, Expr * Value, SourceRange Loc = SourceRange()) {
4111 auto *A = new (Ctx) LoopHintAttr(Loc, Ctx, Option, State, Value, S);
4112 A->setImplicit(true);
4113 return A;
4114 }
4115
4116 LoopHintAttr(SourceRange R, ASTContext &Ctx
4117 , OptionType Option
4118 , LoopHintState State
4119 , Expr * Value
4120 , unsigned SI
4121 )
4122 : Attr(attr::LoopHint, R, SI, false)
4123 , option(Option)
4124 , state(State)
4125 , value(Value)
4126 {
4127 }
4128
4129 LoopHintAttr *clone(ASTContext &C) const;
4130 void printPretty(raw_ostream &OS,
4131 const PrintingPolicy &Policy) const;
4132 const char *getSpelling() const;
4133 Spelling getSemanticSpelling() const {
4134 switch (SpellingListIndex) {
4135 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 4135)
;
4136 case 0: return Pragma_clang_loop;
4137 case 1: return Pragma_unroll;
4138 case 2: return Pragma_nounroll;
4139 case 3: return Pragma_unroll_and_jam;
4140 case 4: return Pragma_nounroll_and_jam;
4141 }
4142 }
4143 OptionType getOption() const {
4144 return option;
4145 }
4146
4147 static bool ConvertStrToOptionType(StringRef Val, OptionType &Out) {
4148 Optional<OptionType> R = llvm::StringSwitch<Optional<OptionType>>(Val)
4149 .Case("vectorize", LoopHintAttr::Vectorize)
4150 .Case("vectorize_width", LoopHintAttr::VectorizeWidth)
4151 .Case("interleave", LoopHintAttr::Interleave)
4152 .Case("interleave_count", LoopHintAttr::InterleaveCount)
4153 .Case("unroll", LoopHintAttr::Unroll)
4154 .Case("unroll_count", LoopHintAttr::UnrollCount)
4155 .Case("unroll_and_jam", LoopHintAttr::UnrollAndJam)
4156 .Case("unroll_and_jam_count", LoopHintAttr::UnrollAndJamCount)
4157 .Case("pipeline", LoopHintAttr::PipelineDisabled)
4158 .Case("pipeline_initiation_interval", LoopHintAttr::PipelineInitiationInterval)
4159 .Case("distribute", LoopHintAttr::Distribute)
4160 .Default(Optional<OptionType>());
4161 if (R) {
4162 Out = *R;
4163 return true;
4164 }
4165 return false;
4166 }
4167
4168 static const char *ConvertOptionTypeToStr(OptionType Val) {
4169 switch(Val) {
4170 case LoopHintAttr::Vectorize: return "vectorize";
4171 case LoopHintAttr::VectorizeWidth: return "vectorize_width";
4172 case LoopHintAttr::Interleave: return "interleave";
4173 case LoopHintAttr::InterleaveCount: return "interleave_count";
4174 case LoopHintAttr::Unroll: return "unroll";
4175 case LoopHintAttr::UnrollCount: return "unroll_count";
4176 case LoopHintAttr::UnrollAndJam: return "unroll_and_jam";
4177 case LoopHintAttr::UnrollAndJamCount: return "unroll_and_jam_count";
4178 case LoopHintAttr::PipelineDisabled: return "pipeline";
4179 case LoopHintAttr::PipelineInitiationInterval: return "pipeline_initiation_interval";
4180 case LoopHintAttr::Distribute: return "distribute";
4181 }
4182 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 4182)
;
4183 }
4184 LoopHintState getState() const {
4185 return state;
4186 }
4187
4188 static bool ConvertStrToLoopHintState(StringRef Val, LoopHintState &Out) {
4189 Optional<LoopHintState> R = llvm::StringSwitch<Optional<LoopHintState>>(Val)
4190 .Case("enable", LoopHintAttr::Enable)
4191 .Case("disable", LoopHintAttr::Disable)
4192 .Case("numeric", LoopHintAttr::Numeric)
4193 .Case("assume_safety", LoopHintAttr::AssumeSafety)
4194 .Case("full", LoopHintAttr::Full)
4195 .Default(Optional<LoopHintState>());
4196 if (R) {
4197 Out = *R;
4198 return true;
4199 }
4200 return false;
4201 }
4202
4203 static const char *ConvertLoopHintStateToStr(LoopHintState Val) {
4204 switch(Val) {
4205 case LoopHintAttr::Enable: return "enable";
4206 case LoopHintAttr::Disable: return "disable";
4207 case LoopHintAttr::Numeric: return "numeric";
4208 case LoopHintAttr::AssumeSafety: return "assume_safety";
4209 case LoopHintAttr::Full: return "full";
4210 }
4211 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 4211)
;
4212 }
4213 Expr * getValue() const {
4214 return value;
4215 }
4216
4217
4218 static const char *getOptionName(int Option) {
4219 switch(Option) {
4220 case Vectorize: return "vectorize";
4221 case VectorizeWidth: return "vectorize_width";
4222 case Interleave: return "interleave";
4223 case InterleaveCount: return "interleave_count";
4224 case Unroll: return "unroll";
4225 case UnrollCount: return "unroll_count";
4226 case UnrollAndJam: return "unroll_and_jam";
4227 case UnrollAndJamCount: return "unroll_and_jam_count";
4228 case PipelineDisabled: return "pipeline";
4229 case PipelineInitiationInterval: return "pipeline_initiation_interval";
4230 case Distribute: return "distribute";
4231 }
4232 llvm_unreachable("Unhandled LoopHint option.")::llvm::llvm_unreachable_internal("Unhandled LoopHint option."
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 4232)
;
4233 }
4234
4235 void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
4236 unsigned SpellingIndex = getSpellingListIndex();
4237 // For "#pragma unroll" and "#pragma nounroll" the string "unroll" or
4238 // "nounroll" is already emitted as the pragma name.
4239 if (SpellingIndex == Pragma_nounroll || SpellingIndex == Pragma_nounroll_and_jam)
4240 return;
4241 else if (SpellingIndex == Pragma_unroll || SpellingIndex == Pragma_unroll_and_jam) {
4242 OS << ' ' << getValueString(Policy);
4243 return;
4244 }
4245
4246 assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling")((SpellingIndex == Pragma_clang_loop && "Unexpected spelling"
) ? static_cast<void> (0) : __assert_fail ("SpellingIndex == Pragma_clang_loop && \"Unexpected spelling\""
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 4246, __PRETTY_FUNCTION__))
;
4247 OS << ' ' << getOptionName(option) << getValueString(Policy);
4248 }
4249
4250 // Return a string containing the loop hint argument including the
4251 // enclosing parentheses.
4252 std::string getValueString(const PrintingPolicy &Policy) const {
4253 std::string ValueName;
4254 llvm::raw_string_ostream OS(ValueName);
4255 OS << "(";
4256 if (state == Numeric)
4257 value->printPretty(OS, nullptr, Policy);
4258 else if (state == Enable)
4259 OS << "enable";
4260 else if (state == Full)
4261 OS << "full";
4262 else if (state == AssumeSafety)
4263 OS << "assume_safety";
4264 else
4265 OS << "disable";
4266 OS << ")";
4267 return OS.str();
4268 }
4269
4270 // Return a string suitable for identifying this attribute in diagnostics.
4271 std::string getDiagnosticName(const PrintingPolicy &Policy) const {
4272 unsigned SpellingIndex = getSpellingListIndex();
4273 if (SpellingIndex == Pragma_nounroll)
4274 return "#pragma nounroll";
4275 else if (SpellingIndex == Pragma_unroll)
4276 return "#pragma unroll" + (option == UnrollCount ? getValueString(Policy) : "");
4277 else if (SpellingIndex == Pragma_nounroll_and_jam)
4278 return "#pragma nounroll_and_jam";
4279 else if (SpellingIndex == Pragma_unroll_and_jam)
4280 return "#pragma unroll_and_jam" +
4281 (option == UnrollAndJamCount ? getValueString(Policy) : "");
4282
4283 assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling")((SpellingIndex == Pragma_clang_loop && "Unexpected spelling"
) ? static_cast<void> (0) : __assert_fail ("SpellingIndex == Pragma_clang_loop && \"Unexpected spelling\""
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 4283, __PRETTY_FUNCTION__))
;
4284 return getOptionName(option) + getValueString(Policy);
4285 }
4286
4287
4288 static bool classof(const Attr *A) { return A->getKind() == attr::LoopHint; }
4289};
4290
4291class MIGServerRoutineAttr : public InheritableAttr {
4292public:
4293 static MIGServerRoutineAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4294 auto *A = new (Ctx) MIGServerRoutineAttr(Loc, Ctx, 0);
4295 A->setImplicit(true);
4296 return A;
4297 }
4298
4299 MIGServerRoutineAttr(SourceRange R, ASTContext &Ctx
4300 , unsigned SI
4301 )
4302 : InheritableAttr(attr::MIGServerRoutine, R, SI, false, false)
4303 {
4304 }
4305
4306 MIGServerRoutineAttr *clone(ASTContext &C) const;
4307 void printPretty(raw_ostream &OS,
4308 const PrintingPolicy &Policy) const;
4309 const char *getSpelling() const;
4310
4311
4312 static bool classof(const Attr *A) { return A->getKind() == attr::MIGServerRoutine; }
4313};
4314
4315class MSABIAttr : public InheritableAttr {
4316public:
4317 static MSABIAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4318 auto *A = new (Ctx) MSABIAttr(Loc, Ctx, 0);
4319 A->setImplicit(true);
4320 return A;
4321 }
4322
4323 MSABIAttr(SourceRange R, ASTContext &Ctx
4324 , unsigned SI
4325 )
4326 : InheritableAttr(attr::MSABI, R, SI, false, false)
4327 {
4328 }
4329
4330 MSABIAttr *clone(ASTContext &C) const;
4331 void printPretty(raw_ostream &OS,
4332 const PrintingPolicy &Policy) const;
4333 const char *getSpelling() const;
4334
4335
4336 static bool classof(const Attr *A) { return A->getKind() == attr::MSABI; }
4337};
4338
4339class MSAllocatorAttr : public InheritableAttr {
4340public:
4341 static MSAllocatorAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4342 auto *A = new (Ctx) MSAllocatorAttr(Loc, Ctx, 0);
4343 A->setImplicit(true);
4344 return A;
4345 }
4346
4347 MSAllocatorAttr(SourceRange R, ASTContext &Ctx
4348 , unsigned SI
4349 )
4350 : InheritableAttr(attr::MSAllocator, R, SI, false, false)
4351 {
4352 }
4353
4354 MSAllocatorAttr *clone(ASTContext &C) const;
4355 void printPretty(raw_ostream &OS,
4356 const PrintingPolicy &Policy) const;
4357 const char *getSpelling() const;
4358
4359
4360 static bool classof(const Attr *A) { return A->getKind() == attr::MSAllocator; }
4361};
4362
4363class MSInheritanceAttr : public InheritableAttr {
4364bool bestCase;
4365
4366public:
4367 enum Spelling {
4368 Keyword_single_inheritance = 0,
4369 Keyword_multiple_inheritance = 1,
4370 Keyword_virtual_inheritance = 2,
4371 Keyword_unspecified_inheritance = 3
4372 };
4373
4374 static MSInheritanceAttr *CreateImplicit(ASTContext &Ctx, Spelling S, bool BestCase, SourceRange Loc = SourceRange()) {
4375 auto *A = new (Ctx) MSInheritanceAttr(Loc, Ctx, BestCase, S);
4376 A->setImplicit(true);
4377 return A;
4378 }
4379
4380 static MSInheritanceAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
4381 auto *A = new (Ctx) MSInheritanceAttr(Loc, Ctx, S);
4382 A->setImplicit(true);
4383 return A;
4384 }
4385
4386 MSInheritanceAttr(SourceRange R, ASTContext &Ctx
4387 , bool BestCase
4388 , unsigned SI
4389 )
4390 : InheritableAttr(attr::MSInheritance, R, SI, false, false)
4391 , bestCase(BestCase)
4392 {
4393 }
4394
4395 MSInheritanceAttr(SourceRange R, ASTContext &Ctx
4396 , unsigned SI
4397 )
4398 : InheritableAttr(attr::MSInheritance, R, SI, false, false)
4399 , bestCase()
4400 {
4401 }
4402
4403 MSInheritanceAttr *clone(ASTContext &C) const;
4404 void printPretty(raw_ostream &OS,
4405 const PrintingPolicy &Policy) const;
4406 const char *getSpelling() const;
4407 Spelling getSemanticSpelling() const {
4408 switch (SpellingListIndex) {
4409 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 4409)
;
4410 case 0: return Keyword_single_inheritance;
4411 case 1: return Keyword_multiple_inheritance;
4412 case 2: return Keyword_virtual_inheritance;
4413 case 3: return Keyword_unspecified_inheritance;
4414 }
4415 }
4416 bool getBestCase() const {
4417 return bestCase;
4418 }
4419
4420 static const bool DefaultBestCase = true;
4421
4422
4423 static bool hasVBPtrOffsetField(Spelling Inheritance) {
4424 return Inheritance == Keyword_unspecified_inheritance;
4425 }
4426
4427 // Only member pointers to functions need a this adjustment, since it can be
4428 // combined with the field offset for data pointers.
4429 static bool hasNVOffsetField(bool IsMemberFunction, Spelling Inheritance) {
4430 return IsMemberFunction && Inheritance >= Keyword_multiple_inheritance;
4431 }
4432
4433 static bool hasVBTableOffsetField(Spelling Inheritance) {
4434 return Inheritance >= Keyword_virtual_inheritance;
4435 }
4436
4437 static bool hasOnlyOneField(bool IsMemberFunction,
4438 Spelling Inheritance) {
4439 if (IsMemberFunction)
4440 return Inheritance <= Keyword_single_inheritance;
4441 return Inheritance <= Keyword_multiple_inheritance;
4442 }
4443
4444
4445 static bool classof(const Attr *A) { return A->getKind() == attr::MSInheritance; }
4446};
4447
4448class MSNoVTableAttr : public InheritableAttr {
4449public:
4450 static MSNoVTableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4451 auto *A = new (Ctx) MSNoVTableAttr(Loc, Ctx, 0);
4452 A->setImplicit(true);
4453 return A;
4454 }
4455
4456 MSNoVTableAttr(SourceRange R, ASTContext &Ctx
4457 , unsigned SI
4458 )
4459 : InheritableAttr(attr::MSNoVTable, R, SI, false, false)
4460 {
4461 }
4462
4463 MSNoVTableAttr *clone(ASTContext &C) const;
4464 void printPretty(raw_ostream &OS,
4465 const PrintingPolicy &Policy) const;
4466 const char *getSpelling() const;
4467
4468
4469 static bool classof(const Attr *A) { return A->getKind() == attr::MSNoVTable; }
4470};
4471
4472class MSP430InterruptAttr : public InheritableAttr {
4473unsigned number;
4474
4475public:
4476 static MSP430InterruptAttr *CreateImplicit(ASTContext &Ctx, unsigned Number, SourceRange Loc = SourceRange()) {
4477 auto *A = new (Ctx) MSP430InterruptAttr(Loc, Ctx, Number, 0);
4478 A->setImplicit(true);
4479 return A;
4480 }
4481
4482 MSP430InterruptAttr(SourceRange R, ASTContext &Ctx
4483 , unsigned Number
4484 , unsigned SI
4485 )
4486 : InheritableAttr(attr::MSP430Interrupt, R, SI, false, false)
4487 , number(Number)
4488 {
4489 }
4490
4491 MSP430InterruptAttr *clone(ASTContext &C) const;
4492 void printPretty(raw_ostream &OS,
4493 const PrintingPolicy &Policy) const;
4494 const char *getSpelling() const;
4495 unsigned getNumber() const {
4496 return number;
4497 }
4498
4499
4500
4501 static bool classof(const Attr *A) { return A->getKind() == attr::MSP430Interrupt; }
4502};
4503
4504class MSStructAttr : public InheritableAttr {
4505public:
4506 static MSStructAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4507 auto *A = new (Ctx) MSStructAttr(Loc, Ctx, 0);
4508 A->setImplicit(true);
4509 return A;
4510 }
4511
4512 MSStructAttr(SourceRange R, ASTContext &Ctx
4513 , unsigned SI
4514 )
4515 : InheritableAttr(attr::MSStruct, R, SI, false, false)
4516 {
4517 }
4518
4519 MSStructAttr *clone(ASTContext &C) const;
4520 void printPretty(raw_ostream &OS,
4521 const PrintingPolicy &Policy) const;
4522 const char *getSpelling() const;
4523
4524
4525 static bool classof(const Attr *A) { return A->getKind() == attr::MSStruct; }
4526};
4527
4528class MSVtorDispAttr : public InheritableAttr {
4529unsigned vdm;
4530
4531public:
4532 static MSVtorDispAttr *CreateImplicit(ASTContext &Ctx, unsigned Vdm, SourceRange Loc = SourceRange()) {
4533 auto *A = new (Ctx) MSVtorDispAttr(Loc, Ctx, Vdm, 0);
4534 A->setImplicit(true);
4535 return A;
4536 }
4537
4538 MSVtorDispAttr(SourceRange R, ASTContext &Ctx
4539 , unsigned Vdm
4540 , unsigned SI
4541 )
4542 : InheritableAttr(attr::MSVtorDisp, R, SI, false, false)
4543 , vdm(Vdm)
4544 {
4545 }
4546
4547 MSVtorDispAttr *clone(ASTContext &C) const;
4548 void printPretty(raw_ostream &OS,
4549 const PrintingPolicy &Policy) const;
4550 const char *getSpelling() const;
4551 unsigned getVdm() const {
4552 return vdm;
4553 }
4554
4555
4556 enum Mode {
4557 Never,
4558 ForVBaseOverride,
4559 ForVFTable
4560 };
4561
4562 Mode getVtorDispMode() const { return Mode(vdm); }
4563
4564
4565 static bool classof(const Attr *A) { return A->getKind() == attr::MSVtorDisp; }
4566};
4567
4568class MaxFieldAlignmentAttr : public InheritableAttr {
4569unsigned alignment;
4570
4571public:
4572 static MaxFieldAlignmentAttr *CreateImplicit(ASTContext &Ctx, unsigned Alignment, SourceRange Loc = SourceRange()) {
4573 auto *A = new (Ctx) MaxFieldAlignmentAttr(Loc, Ctx, Alignment, 0);
4574 A->setImplicit(true);
4575 return A;
4576 }
4577
4578 MaxFieldAlignmentAttr(SourceRange R, ASTContext &Ctx
4579 , unsigned Alignment
4580 , unsigned SI
4581 )
4582 : InheritableAttr(attr::MaxFieldAlignment, R, SI, false, false)
4583 , alignment(Alignment)
4584 {
4585 }
4586
4587 MaxFieldAlignmentAttr *clone(ASTContext &C) const;
4588 void printPretty(raw_ostream &OS,
4589 const PrintingPolicy &Policy) const;
4590 const char *getSpelling() const;
4591 unsigned getAlignment() const {
4592 return alignment;
4593 }
4594
4595
4596
4597 static bool classof(const Attr *A) { return A->getKind() == attr::MaxFieldAlignment; }
4598};
4599
4600class MayAliasAttr : public InheritableAttr {
4601public:
4602 static MayAliasAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4603 auto *A = new (Ctx) MayAliasAttr(Loc, Ctx, 0);
4604 A->setImplicit(true);
4605 return A;
4606 }
4607
4608 MayAliasAttr(SourceRange R, ASTContext &Ctx
4609 , unsigned SI
4610 )
4611 : InheritableAttr(attr::MayAlias, R, SI, false, false)
4612 {
4613 }
4614
4615 MayAliasAttr *clone(ASTContext &C) const;
4616 void printPretty(raw_ostream &OS,
4617 const PrintingPolicy &Policy) const;
4618 const char *getSpelling() const;
4619
4620
4621 static bool classof(const Attr *A) { return A->getKind() == attr::MayAlias; }
4622};
4623
4624class MicroMipsAttr : public InheritableAttr {
4625public:
4626 static MicroMipsAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4627 auto *A = new (Ctx) MicroMipsAttr(Loc, Ctx, 0);
4628 A->setImplicit(true);
4629 return A;
4630 }
4631
4632 MicroMipsAttr(SourceRange R, ASTContext &Ctx
4633 , unsigned SI
4634 )
4635 : InheritableAttr(attr::MicroMips, R, SI, false, false)
4636 {
4637 }
4638
4639 MicroMipsAttr *clone(ASTContext &C) const;
4640 void printPretty(raw_ostream &OS,
4641 const PrintingPolicy &Policy) const;
4642 const char *getSpelling() const;
4643
4644
4645 static bool classof(const Attr *A) { return A->getKind() == attr::MicroMips; }
4646};
4647
4648class MinSizeAttr : public InheritableAttr {
4649public:
4650 static MinSizeAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4651 auto *A = new (Ctx) MinSizeAttr(Loc, Ctx, 0);
4652 A->setImplicit(true);
4653 return A;
4654 }
4655
4656 MinSizeAttr(SourceRange R, ASTContext &Ctx
4657 , unsigned SI
4658 )
4659 : InheritableAttr(attr::MinSize, R, SI, false, false)
4660 {
4661 }
4662
4663 MinSizeAttr *clone(ASTContext &C) const;
4664 void printPretty(raw_ostream &OS,
4665 const PrintingPolicy &Policy) const;
4666 const char *getSpelling() const;
4667
4668
4669 static bool classof(const Attr *A) { return A->getKind() == attr::MinSize; }
4670};
4671
4672class MinVectorWidthAttr : public InheritableAttr {
4673unsigned vectorWidth;
4674
4675public:
4676 static MinVectorWidthAttr *CreateImplicit(ASTContext &Ctx, unsigned VectorWidth, SourceRange Loc = SourceRange()) {
4677 auto *A = new (Ctx) MinVectorWidthAttr(Loc, Ctx, VectorWidth, 0);
4678 A->setImplicit(true);
4679 return A;
4680 }
4681
4682 MinVectorWidthAttr(SourceRange R, ASTContext &Ctx
4683 , unsigned VectorWidth
4684 , unsigned SI
4685 )
4686 : InheritableAttr(attr::MinVectorWidth, R, SI, false, false)
4687 , vectorWidth(VectorWidth)
4688 {
4689 }
4690
4691 MinVectorWidthAttr *clone(ASTContext &C) const;
4692 void printPretty(raw_ostream &OS,
4693 const PrintingPolicy &Policy) const;
4694 const char *getSpelling() const;
4695 unsigned getVectorWidth() const {
4696 return vectorWidth;
4697 }
4698
4699
4700
4701 static bool classof(const Attr *A) { return A->getKind() == attr::MinVectorWidth; }
4702};
4703
4704class Mips16Attr : public InheritableAttr {
4705public:
4706 static Mips16Attr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4707 auto *A = new (Ctx) Mips16Attr(Loc, Ctx, 0);
4708 A->setImplicit(true);
4709 return A;
4710 }
4711
4712 Mips16Attr(SourceRange R, ASTContext &Ctx
4713 , unsigned SI
4714 )
4715 : InheritableAttr(attr::Mips16, R, SI, false, false)
4716 {
4717 }
4718
4719 Mips16Attr *clone(ASTContext &C) const;
4720 void printPretty(raw_ostream &OS,
4721 const PrintingPolicy &Policy) const;
4722 const char *getSpelling() const;
4723
4724
4725 static bool classof(const Attr *A) { return A->getKind() == attr::Mips16; }
4726};
4727
4728class MipsInterruptAttr : public InheritableAttr {
4729public:
4730 enum InterruptType {
4731 sw0,
4732 sw1,
4733 hw0,
4734 hw1,
4735 hw2,
4736 hw3,
4737 hw4,
4738 hw5,
4739 eic
4740 };
4741private:
4742 InterruptType interrupt;
4743
4744public:
4745 static MipsInterruptAttr *CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, SourceRange Loc = SourceRange()) {
4746 auto *A = new (Ctx) MipsInterruptAttr(Loc, Ctx, Interrupt, 0);
4747 A->setImplicit(true);
4748 return A;
4749 }
4750
4751 MipsInterruptAttr(SourceRange R, ASTContext &Ctx
4752 , InterruptType Interrupt
4753 , unsigned SI
4754 )
4755 : InheritableAttr(attr::MipsInterrupt, R, SI, false, false)
4756 , interrupt(Interrupt)
4757 {
4758 }
4759
4760 MipsInterruptAttr *clone(ASTContext &C) const;
4761 void printPretty(raw_ostream &OS,
4762 const PrintingPolicy &Policy) const;
4763 const char *getSpelling() const;
4764 InterruptType getInterrupt() const {
4765 return interrupt;
4766 }
4767
4768 static bool ConvertStrToInterruptType(StringRef Val, InterruptType &Out) {
4769 Optional<InterruptType> R = llvm::StringSwitch<Optional<InterruptType>>(Val)
4770 .Case("vector=sw0", MipsInterruptAttr::sw0)
4771 .Case("vector=sw1", MipsInterruptAttr::sw1)
4772 .Case("vector=hw0", MipsInterruptAttr::hw0)
4773 .Case("vector=hw1", MipsInterruptAttr::hw1)
4774 .Case("vector=hw2", MipsInterruptAttr::hw2)
4775 .Case("vector=hw3", MipsInterruptAttr::hw3)
4776 .Case("vector=hw4", MipsInterruptAttr::hw4)
4777 .Case("vector=hw5", MipsInterruptAttr::hw5)
4778 .Case("eic", MipsInterruptAttr::eic)
4779 .Case("", MipsInterruptAttr::eic)
4780 .Default(Optional<InterruptType>());
4781 if (R) {
4782 Out = *R;
4783 return true;
4784 }
4785 return false;
4786 }
4787
4788 static const char *ConvertInterruptTypeToStr(InterruptType Val) {
4789 switch(Val) {
4790 case MipsInterruptAttr::sw0: return "vector=sw0";
4791 case MipsInterruptAttr::sw1: return "vector=sw1";
4792 case MipsInterruptAttr::hw0: return "vector=hw0";
4793 case MipsInterruptAttr::hw1: return "vector=hw1";
4794 case MipsInterruptAttr::hw2: return "vector=hw2";
4795 case MipsInterruptAttr::hw3: return "vector=hw3";
4796 case MipsInterruptAttr::hw4: return "vector=hw4";
4797 case MipsInterruptAttr::hw5: return "vector=hw5";
4798 case MipsInterruptAttr::eic: return "eic";
4799 }
4800 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 4800)
;
4801 }
4802
4803
4804 static bool classof(const Attr *A) { return A->getKind() == attr::MipsInterrupt; }
4805};
4806
4807class MipsLongCallAttr : public InheritableAttr {
4808public:
4809 enum Spelling {
4810 GNU_long_call = 0,
4811 CXX11_gnu_long_call = 1,
4812 GNU_far = 2,
4813 CXX11_gnu_far = 3
4814 };
4815
4816 static MipsLongCallAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
4817 auto *A = new (Ctx) MipsLongCallAttr(Loc, Ctx, S);
4818 A->setImplicit(true);
4819 return A;
4820 }
4821
4822 MipsLongCallAttr(SourceRange R, ASTContext &Ctx
4823 , unsigned SI
4824 )
4825 : InheritableAttr(attr::MipsLongCall, R, SI, false, false)
4826 {
4827 }
4828
4829 MipsLongCallAttr *clone(ASTContext &C) const;
4830 void printPretty(raw_ostream &OS,
4831 const PrintingPolicy &Policy) const;
4832 const char *getSpelling() const;
4833 Spelling getSemanticSpelling() const {
4834 switch (SpellingListIndex) {
4835 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 4835)
;
4836 case 0: return GNU_long_call;
4837 case 1: return CXX11_gnu_long_call;
4838 case 2: return GNU_far;
4839 case 3: return CXX11_gnu_far;
4840 }
4841 }
4842
4843
4844 static bool classof(const Attr *A) { return A->getKind() == attr::MipsLongCall; }
4845};
4846
4847class MipsShortCallAttr : public InheritableAttr {
4848public:
4849 enum Spelling {
4850 GNU_short_call = 0,
4851 CXX11_gnu_short_call = 1,
4852 GNU_near = 2,
4853 CXX11_gnu_near = 3
4854 };
4855
4856 static MipsShortCallAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
4857 auto *A = new (Ctx) MipsShortCallAttr(Loc, Ctx, S);
4858 A->setImplicit(true);
4859 return A;
4860 }
4861
4862 MipsShortCallAttr(SourceRange R, ASTContext &Ctx
4863 , unsigned SI
4864 )
4865 : InheritableAttr(attr::MipsShortCall, R, SI, false, false)
4866 {
4867 }
4868
4869 MipsShortCallAttr *clone(ASTContext &C) const;
4870 void printPretty(raw_ostream &OS,
4871 const PrintingPolicy &Policy) const;
4872 const char *getSpelling() const;
4873 Spelling getSemanticSpelling() const {
4874 switch (SpellingListIndex) {
4875 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 4875)
;
4876 case 0: return GNU_short_call;
4877 case 1: return CXX11_gnu_short_call;
4878 case 2: return GNU_near;
4879 case 3: return CXX11_gnu_near;
4880 }
4881 }
4882
4883
4884 static bool classof(const Attr *A) { return A->getKind() == attr::MipsShortCall; }
4885};
4886
4887class ModeAttr : public Attr {
4888IdentifierInfo * mode;
4889
4890public:
4891 static ModeAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * Mode, SourceRange Loc = SourceRange()) {
4892 auto *A = new (Ctx) ModeAttr(Loc, Ctx, Mode, 0);
4893 A->setImplicit(true);
4894 return A;
4895 }
4896
4897 ModeAttr(SourceRange R, ASTContext &Ctx
4898 , IdentifierInfo * Mode
4899 , unsigned SI
4900 )
4901 : Attr(attr::Mode, R, SI, false)
4902 , mode(Mode)
4903 {
4904 }
4905
4906 ModeAttr *clone(ASTContext &C) const;
4907 void printPretty(raw_ostream &OS,
4908 const PrintingPolicy &Policy) const;
4909 const char *getSpelling() const;
4910 IdentifierInfo * getMode() const {
4911 return mode;
4912 }
4913
4914
4915
4916 static bool classof(const Attr *A) { return A->getKind() == attr::Mode; }
4917};
4918
4919class NSConsumedAttr : public InheritableParamAttr {
4920public:
4921 static NSConsumedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4922 auto *A = new (Ctx) NSConsumedAttr(Loc, Ctx, 0);
4923 A->setImplicit(true);
4924 return A;
4925 }
4926
4927 NSConsumedAttr(SourceRange R, ASTContext &Ctx
4928 , unsigned SI
4929 )
4930 : InheritableParamAttr(attr::NSConsumed, R, SI, false, false)
4931 {
4932 }
4933
4934 NSConsumedAttr *clone(ASTContext &C) const;
4935 void printPretty(raw_ostream &OS,
4936 const PrintingPolicy &Policy) const;
4937 const char *getSpelling() const;
4938
4939
4940 static bool classof(const Attr *A) { return A->getKind() == attr::NSConsumed; }
4941};
4942
4943class NSConsumesSelfAttr : public InheritableAttr {
4944public:
4945 static NSConsumesSelfAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4946 auto *A = new (Ctx) NSConsumesSelfAttr(Loc, Ctx, 0);
4947 A->setImplicit(true);
4948 return A;
4949 }
4950
4951 NSConsumesSelfAttr(SourceRange R, ASTContext &Ctx
4952 , unsigned SI
4953 )
4954 : InheritableAttr(attr::NSConsumesSelf, R, SI, false, false)
4955 {
4956 }
4957
4958 NSConsumesSelfAttr *clone(ASTContext &C) const;
4959 void printPretty(raw_ostream &OS,
4960 const PrintingPolicy &Policy) const;
4961 const char *getSpelling() const;
4962
4963
4964 static bool classof(const Attr *A) { return A->getKind() == attr::NSConsumesSelf; }
4965};
4966
4967class NSReturnsAutoreleasedAttr : public InheritableAttr {
4968public:
4969 static NSReturnsAutoreleasedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4970 auto *A = new (Ctx) NSReturnsAutoreleasedAttr(Loc, Ctx, 0);
4971 A->setImplicit(true);
4972 return A;
4973 }
4974
4975 NSReturnsAutoreleasedAttr(SourceRange R, ASTContext &Ctx
4976 , unsigned SI
4977 )
4978 : InheritableAttr(attr::NSReturnsAutoreleased, R, SI, false, false)
4979 {
4980 }
4981
4982 NSReturnsAutoreleasedAttr *clone(ASTContext &C) const;
4983 void printPretty(raw_ostream &OS,
4984 const PrintingPolicy &Policy) const;
4985 const char *getSpelling() const;
4986
4987
4988 static bool classof(const Attr *A) { return A->getKind() == attr::NSReturnsAutoreleased; }
4989};
4990
4991class NSReturnsNotRetainedAttr : public InheritableAttr {
4992public:
4993 static NSReturnsNotRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
4994 auto *A = new (Ctx) NSReturnsNotRetainedAttr(Loc, Ctx, 0);
4995 A->setImplicit(true);
4996 return A;
4997 }
4998
4999 NSReturnsNotRetainedAttr(SourceRange R, ASTContext &Ctx
5000 , unsigned SI
5001 )
5002 : InheritableAttr(attr::NSReturnsNotRetained, R, SI, false, false)
5003 {
5004 }
5005
5006 NSReturnsNotRetainedAttr *clone(ASTContext &C) const;
5007 void printPretty(raw_ostream &OS,
5008 const PrintingPolicy &Policy) const;
5009 const char *getSpelling() const;
5010
5011
5012 static bool classof(const Attr *A) { return A->getKind() == attr::NSReturnsNotRetained; }
5013};
5014
5015class NSReturnsRetainedAttr : public InheritableAttr {
5016public:
5017 static NSReturnsRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5018 auto *A = new (Ctx) NSReturnsRetainedAttr(Loc, Ctx, 0);
5019 A->setImplicit(true);
5020 return A;
5021 }
5022
5023 NSReturnsRetainedAttr(SourceRange R, ASTContext &Ctx
5024 , unsigned SI
5025 )
5026 : InheritableAttr(attr::NSReturnsRetained, R, SI, false, false)
5027 {
5028 }
5029
5030 NSReturnsRetainedAttr *clone(ASTContext &C) const;
5031 void printPretty(raw_ostream &OS,
5032 const PrintingPolicy &Policy) const;
5033 const char *getSpelling() const;
5034
5035
5036 static bool classof(const Attr *A) { return A->getKind() == attr::NSReturnsRetained; }
5037};
5038
5039class NakedAttr : public InheritableAttr {
5040public:
5041 static NakedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5042 auto *A = new (Ctx) NakedAttr(Loc, Ctx, 0);
5043 A->setImplicit(true);
5044 return A;
5045 }
5046
5047 NakedAttr(SourceRange R, ASTContext &Ctx
5048 , unsigned SI
5049 )
5050 : InheritableAttr(attr::Naked, R, SI, false, false)
5051 {
5052 }
5053
5054 NakedAttr *clone(ASTContext &C) const;
5055 void printPretty(raw_ostream &OS,
5056 const PrintingPolicy &Policy) const;
5057 const char *getSpelling() const;
5058
5059
5060 static bool classof(const Attr *A) { return A->getKind() == attr::Naked; }
5061};
5062
5063class NoAliasAttr : public InheritableAttr {
5064public:
5065 static NoAliasAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5066 auto *A = new (Ctx) NoAliasAttr(Loc, Ctx, 0);
5067 A->setImplicit(true);
5068 return A;
5069 }
5070
5071 NoAliasAttr(SourceRange R, ASTContext &Ctx
5072 , unsigned SI
5073 )
5074 : InheritableAttr(attr::NoAlias, R, SI, false, false)
5075 {
5076 }
5077
5078 NoAliasAttr *clone(ASTContext &C) const;
5079 void printPretty(raw_ostream &OS,
5080 const PrintingPolicy &Policy) const;
5081 const char *getSpelling() const;
5082
5083
5084 static bool classof(const Attr *A) { return A->getKind() == attr::NoAlias; }
5085};
5086
5087class NoCommonAttr : public InheritableAttr {
5088public:
5089 static NoCommonAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5090 auto *A = new (Ctx) NoCommonAttr(Loc, Ctx, 0);
5091 A->setImplicit(true);
5092 return A;
5093 }
5094
5095 NoCommonAttr(SourceRange R, ASTContext &Ctx
5096 , unsigned SI
5097 )
5098 : InheritableAttr(attr::NoCommon, R, SI, false, false)
5099 {
5100 }
5101
5102 NoCommonAttr *clone(ASTContext &C) const;
5103 void printPretty(raw_ostream &OS,
5104 const PrintingPolicy &Policy) const;
5105 const char *getSpelling() const;
5106
5107
5108 static bool classof(const Attr *A) { return A->getKind() == attr::NoCommon; }
5109};
5110
5111class NoDebugAttr : public InheritableAttr {
5112public:
5113 static NoDebugAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5114 auto *A = new (Ctx) NoDebugAttr(Loc, Ctx, 0);
5115 A->setImplicit(true);
5116 return A;
5117 }
5118
5119 NoDebugAttr(SourceRange R, ASTContext &Ctx
5120 , unsigned SI
5121 )
5122 : InheritableAttr(attr::NoDebug, R, SI, false, false)
5123 {
5124 }
5125
5126 NoDebugAttr *clone(ASTContext &C) const;
5127 void printPretty(raw_ostream &OS,
5128 const PrintingPolicy &Policy) const;
5129 const char *getSpelling() const;
5130
5131
5132 static bool classof(const Attr *A) { return A->getKind() == attr::NoDebug; }
5133};
5134
5135class NoDerefAttr : public TypeAttr {
5136public:
5137 static NoDerefAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5138 auto *A = new (Ctx) NoDerefAttr(Loc, Ctx, 0);
5139 A->setImplicit(true);
5140 return A;
5141 }
5142
5143 NoDerefAttr(SourceRange R, ASTContext &Ctx
5144 , unsigned SI
5145 )
5146 : TypeAttr(attr::NoDeref, R, SI, false)
5147 {
5148 }
5149
5150 NoDerefAttr *clone(ASTContext &C) const;
5151 void printPretty(raw_ostream &OS,
5152 const PrintingPolicy &Policy) const;
5153 const char *getSpelling() const;
5154
5155
5156 static bool classof(const Attr *A) { return A->getKind() == attr::NoDeref; }
5157};
5158
5159class NoDestroyAttr : public InheritableAttr {
5160public:
5161 static NoDestroyAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5162 auto *A = new (Ctx) NoDestroyAttr(Loc, Ctx, 0);
5163 A->setImplicit(true);
5164 return A;
5165 }
5166
5167 NoDestroyAttr(SourceRange R, ASTContext &Ctx
5168 , unsigned SI
5169 )
5170 : InheritableAttr(attr::NoDestroy, R, SI, false, false)
5171 {
5172 }
5173
5174 NoDestroyAttr *clone(ASTContext &C) const;
5175 void printPretty(raw_ostream &OS,
5176 const PrintingPolicy &Policy) const;
5177 const char *getSpelling() const;
5178
5179
5180 static bool classof(const Attr *A) { return A->getKind() == attr::NoDestroy; }
5181};
5182
5183class NoDuplicateAttr : public InheritableAttr {
5184public:
5185 static NoDuplicateAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5186 auto *A = new (Ctx) NoDuplicateAttr(Loc, Ctx, 0);
5187 A->setImplicit(true);
5188 return A;
5189 }
5190
5191 NoDuplicateAttr(SourceRange R, ASTContext &Ctx
5192 , unsigned SI
5193 )
5194 : InheritableAttr(attr::NoDuplicate, R, SI, false, false)
5195 {
5196 }
5197
5198 NoDuplicateAttr *clone(ASTContext &C) const;
5199 void printPretty(raw_ostream &OS,
5200 const PrintingPolicy &Policy) const;
5201 const char *getSpelling() const;
5202
5203
5204 static bool classof(const Attr *A) { return A->getKind() == attr::NoDuplicate; }
5205};
5206
5207class NoEscapeAttr : public Attr {
5208public:
5209 static NoEscapeAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5210 auto *A = new (Ctx) NoEscapeAttr(Loc, Ctx, 0);
5211 A->setImplicit(true);
5212 return A;
5213 }
5214
5215 NoEscapeAttr(SourceRange R, ASTContext &Ctx
5216 , unsigned SI
5217 )
5218 : Attr(attr::NoEscape, R, SI, false)
5219 {
5220 }
5221
5222 NoEscapeAttr *clone(ASTContext &C) const;
5223 void printPretty(raw_ostream &OS,
5224 const PrintingPolicy &Policy) const;
5225 const char *getSpelling() const;
5226
5227
5228 static bool classof(const Attr *A) { return A->getKind() == attr::NoEscape; }
5229};
5230
5231class NoInlineAttr : public InheritableAttr {
5232public:
5233 static NoInlineAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5234 auto *A = new (Ctx) NoInlineAttr(Loc, Ctx, 0);
5235 A->setImplicit(true);
5236 return A;
5237 }
5238
5239 NoInlineAttr(SourceRange R, ASTContext &Ctx
5240 , unsigned SI
5241 )
5242 : InheritableAttr(attr::NoInline, R, SI, false, false)
5243 {
5244 }
5245
5246 NoInlineAttr *clone(ASTContext &C) const;
5247 void printPretty(raw_ostream &OS,
5248 const PrintingPolicy &Policy) const;
5249 const char *getSpelling() const;
5250
5251
5252 static bool classof(const Attr *A) { return A->getKind() == attr::NoInline; }
5253};
5254
5255class NoInstrumentFunctionAttr : public InheritableAttr {
5256public:
5257 static NoInstrumentFunctionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5258 auto *A = new (Ctx) NoInstrumentFunctionAttr(Loc, Ctx, 0);
5259 A->setImplicit(true);
5260 return A;
5261 }
5262
5263 NoInstrumentFunctionAttr(SourceRange R, ASTContext &Ctx
5264 , unsigned SI
5265 )
5266 : InheritableAttr(attr::NoInstrumentFunction, R, SI, false, false)
5267 {
5268 }
5269
5270 NoInstrumentFunctionAttr *clone(ASTContext &C) const;
5271 void printPretty(raw_ostream &OS,
5272 const PrintingPolicy &Policy) const;
5273 const char *getSpelling() const;
5274
5275
5276 static bool classof(const Attr *A) { return A->getKind() == attr::NoInstrumentFunction; }
5277};
5278
5279class NoMicroMipsAttr : public InheritableAttr {
5280public:
5281 static NoMicroMipsAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5282 auto *A = new (Ctx) NoMicroMipsAttr(Loc, Ctx, 0);
5283 A->setImplicit(true);
5284 return A;
5285 }
5286
5287 NoMicroMipsAttr(SourceRange R, ASTContext &Ctx
5288 , unsigned SI
5289 )
5290 : InheritableAttr(attr::NoMicroMips, R, SI, false, false)
5291 {
5292 }
5293
5294 NoMicroMipsAttr *clone(ASTContext &C) const;
5295 void printPretty(raw_ostream &OS,
5296 const PrintingPolicy &Policy) const;
5297 const char *getSpelling() const;
5298
5299
5300 static bool classof(const Attr *A) { return A->getKind() == attr::NoMicroMips; }
5301};
5302
5303class NoMips16Attr : public InheritableAttr {
5304public:
5305 static NoMips16Attr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5306 auto *A = new (Ctx) NoMips16Attr(Loc, Ctx, 0);
5307 A->setImplicit(true);
5308 return A;
5309 }
5310
5311 NoMips16Attr(SourceRange R, ASTContext &Ctx
5312 , unsigned SI
5313 )
5314 : InheritableAttr(attr::NoMips16, R, SI, false, false)
5315 {
5316 }
5317
5318 NoMips16Attr *clone(ASTContext &C) const;
5319 void printPretty(raw_ostream &OS,
5320 const PrintingPolicy &Policy) const;
5321 const char *getSpelling() const;
5322
5323
5324 static bool classof(const Attr *A) { return A->getKind() == attr::NoMips16; }
5325};
5326
5327class NoReturnAttr : public InheritableAttr {
5328public:
5329 static NoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5330 auto *A = new (Ctx) NoReturnAttr(Loc, Ctx, 0);
5331 A->setImplicit(true);
5332 return A;
5333 }
5334
5335 NoReturnAttr(SourceRange R, ASTContext &Ctx
5336 , unsigned SI
5337 )
5338 : InheritableAttr(attr::NoReturn, R, SI, false, false)
5339 {
5340 }
5341
5342 NoReturnAttr *clone(ASTContext &C) const;
5343 void printPretty(raw_ostream &OS,
5344 const PrintingPolicy &Policy) const;
5345 const char *getSpelling() const;
5346
5347
5348 static bool classof(const Attr *A) { return A->getKind() == attr::NoReturn; }
5349};
5350
5351class NoSanitizeAttr : public InheritableAttr {
5352 unsigned sanitizers_Size;
5353 StringRef *sanitizers_;
5354
5355public:
5356 static NoSanitizeAttr *CreateImplicit(ASTContext &Ctx, StringRef *Sanitizers, unsigned SanitizersSize, SourceRange Loc = SourceRange()) {
5357 auto *A = new (Ctx) NoSanitizeAttr(Loc, Ctx, Sanitizers, SanitizersSize, 0);
5358 A->setImplicit(true);
5359 return A;
5360 }
5361
5362 NoSanitizeAttr(SourceRange R, ASTContext &Ctx
5363 , StringRef *Sanitizers, unsigned SanitizersSize
5364 , unsigned SI
5365 )
5366 : InheritableAttr(attr::NoSanitize, R, SI, false, false)
5367 , sanitizers_Size(SanitizersSize), sanitizers_(new (Ctx, 16) StringRef[sanitizers_Size])
5368 {
5369 for (size_t I = 0, E = sanitizers_Size; I != E;
5370 ++I) {
5371 StringRef Ref = Sanitizers[I];
5372 if (!Ref.empty()) {
5373 char *Mem = new (Ctx, 1) char[Ref.size()];
5374 std::memcpy(Mem, Ref.data(), Ref.size());
5375 sanitizers_[I] = StringRef(Mem, Ref.size());
5376 }
5377 }
5378 }
5379
5380 NoSanitizeAttr(SourceRange R, ASTContext &Ctx
5381 , unsigned SI
5382 )
5383 : InheritableAttr(attr::NoSanitize, R, SI, false, false)
5384 , sanitizers_Size(0), sanitizers_(nullptr)
5385 {
5386 }
5387
5388 NoSanitizeAttr *clone(ASTContext &C) const;
5389 void printPretty(raw_ostream &OS,
5390 const PrintingPolicy &Policy) const;
5391 const char *getSpelling() const;
5392 typedef StringRef* sanitizers_iterator;
5393 sanitizers_iterator sanitizers_begin() const { return sanitizers_; }
5394 sanitizers_iterator sanitizers_end() const { return sanitizers_ + sanitizers_Size; }
5395 unsigned sanitizers_size() const { return sanitizers_Size; }
5396 llvm::iterator_range<sanitizers_iterator> sanitizers() const { return llvm::make_range(sanitizers_begin(), sanitizers_end()); }
5397
5398
5399
5400 SanitizerMask getMask() const {
5401 SanitizerMask Mask;
5402 for (auto SanitizerName : sanitizers()) {
5403 SanitizerMask ParsedMask =
5404 parseSanitizerValue(SanitizerName, /*AllowGroups=*/true);
5405 Mask |= expandSanitizerGroups(ParsedMask);
5406 }
5407 return Mask;
5408 }
5409
5410
5411 static bool classof(const Attr *A) { return A->getKind() == attr::NoSanitize; }
5412};
5413
5414class NoSpeculativeLoadHardeningAttr : public InheritableAttr {
5415public:
5416 static NoSpeculativeLoadHardeningAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5417 auto *A = new (Ctx) NoSpeculativeLoadHardeningAttr(Loc, Ctx, 0);
5418 A->setImplicit(true);
5419 return A;
5420 }
5421
5422 NoSpeculativeLoadHardeningAttr(SourceRange R, ASTContext &Ctx
5423 , unsigned SI
5424 )
5425 : InheritableAttr(attr::NoSpeculativeLoadHardening, R, SI, false, false)
5426 {
5427 }
5428
5429 NoSpeculativeLoadHardeningAttr *clone(ASTContext &C) const;
5430 void printPretty(raw_ostream &OS,
5431 const PrintingPolicy &Policy) const;
5432 const char *getSpelling() const;
5433
5434
5435 static bool classof(const Attr *A) { return A->getKind() == attr::NoSpeculativeLoadHardening; }
5436};
5437
5438class NoSplitStackAttr : public InheritableAttr {
5439public:
5440 static NoSplitStackAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5441 auto *A = new (Ctx) NoSplitStackAttr(Loc, Ctx, 0);
5442 A->setImplicit(true);
5443 return A;
5444 }
5445
5446 NoSplitStackAttr(SourceRange R, ASTContext &Ctx
5447 , unsigned SI
5448 )
5449 : InheritableAttr(attr::NoSplitStack, R, SI, false, false)
5450 {
5451 }
5452
5453 NoSplitStackAttr *clone(ASTContext &C) const;
5454 void printPretty(raw_ostream &OS,
5455 const PrintingPolicy &Policy) const;
5456 const char *getSpelling() const;
5457
5458
5459 static bool classof(const Attr *A) { return A->getKind() == attr::NoSplitStack; }
5460};
5461
5462class NoStackProtectorAttr : public InheritableAttr {
5463public:
5464 static NoStackProtectorAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5465 auto *A = new (Ctx) NoStackProtectorAttr(Loc, Ctx, 0);
5466 A->setImplicit(true);
5467 return A;
5468 }
5469
5470 NoStackProtectorAttr(SourceRange R, ASTContext &Ctx
5471 , unsigned SI
5472 )
5473 : InheritableAttr(attr::NoStackProtector, R, SI, false, false)
5474 {
5475 }
5476
5477 NoStackProtectorAttr *clone(ASTContext &C) const;
5478 void printPretty(raw_ostream &OS,
5479 const PrintingPolicy &Policy) const;
5480 const char *getSpelling() const;
5481
5482
5483 static bool classof(const Attr *A) { return A->getKind() == attr::NoStackProtector; }
5484};
5485
5486class NoThreadSafetyAnalysisAttr : public InheritableAttr {
5487public:
5488 static NoThreadSafetyAnalysisAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5489 auto *A = new (Ctx) NoThreadSafetyAnalysisAttr(Loc, Ctx, 0);
5490 A->setImplicit(true);
5491 return A;
5492 }
5493
5494 NoThreadSafetyAnalysisAttr(SourceRange R, ASTContext &Ctx
5495 , unsigned SI
5496 )
5497 : InheritableAttr(attr::NoThreadSafetyAnalysis, R, SI, false, false)
5498 {
5499 }
5500
5501 NoThreadSafetyAnalysisAttr *clone(ASTContext &C) const;
5502 void printPretty(raw_ostream &OS,
5503 const PrintingPolicy &Policy) const;
5504 const char *getSpelling() const;
5505
5506
5507 static bool classof(const Attr *A) { return A->getKind() == attr::NoThreadSafetyAnalysis; }
5508};
5509
5510class NoThrowAttr : public InheritableAttr {
5511public:
5512 static NoThrowAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5513 auto *A = new (Ctx) NoThrowAttr(Loc, Ctx, 0);
5514 A->setImplicit(true);
5515 return A;
5516 }
5517
5518 NoThrowAttr(SourceRange R, ASTContext &Ctx
5519 , unsigned SI
5520 )
5521 : InheritableAttr(attr::NoThrow, R, SI, false, false)
5522 {
5523 }
5524
5525 NoThrowAttr *clone(ASTContext &C) const;
5526 void printPretty(raw_ostream &OS,
5527 const PrintingPolicy &Policy) const;
5528 const char *getSpelling() const;
5529
5530
5531 static bool classof(const Attr *A) { return A->getKind() == attr::NoThrow; }
5532};
5533
5534class NonNullAttr : public InheritableParamAttr {
5535 unsigned args_Size;
5536 ParamIdx *args_;
5537
5538public:
5539 static NonNullAttr *CreateImplicit(ASTContext &Ctx, ParamIdx *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
5540 auto *A = new (Ctx) NonNullAttr(Loc, Ctx, Args, ArgsSize, 0);
5541 A->setImplicit(true);
5542 return A;
5543 }
5544
5545 NonNullAttr(SourceRange R, ASTContext &Ctx
5546 , ParamIdx *Args, unsigned ArgsSize
5547 , unsigned SI
5548 )
5549 : InheritableParamAttr(attr::NonNull, R, SI, false, true)
5550 , args_Size(ArgsSize), args_(new (Ctx, 16) ParamIdx[args_Size])
5551 {
5552 std::copy(Args, Args + args_Size, args_);
5553 }
5554
5555 NonNullAttr(SourceRange R, ASTContext &Ctx
5556 , unsigned SI
5557 )
5558 : InheritableParamAttr(attr::NonNull, R, SI, false, true)
5559 , args_Size(0), args_(nullptr)
5560 {
5561 }
5562
5563 NonNullAttr *clone(ASTContext &C) const;
5564 void printPretty(raw_ostream &OS,
5565 const PrintingPolicy &Policy) const;
5566 const char *getSpelling() const;
5567 typedef ParamIdx* args_iterator;
5568 args_iterator args_begin() const { return args_; }
5569 args_iterator args_end() const { return args_ + args_Size; }
5570 unsigned args_size() const { return args_Size; }
5571 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
5572
5573
5574
5575 bool isNonNull(unsigned IdxAST) const {
5576 if (!args_size())
5577 return true;
5578 return args_end() != std::find_if(
5579 args_begin(), args_end(),
5580 [=](const ParamIdx &Idx) { return Idx.getASTIndex() == IdxAST; });
5581 }
5582
5583
5584 static bool classof(const Attr *A) { return A->getKind() == attr::NonNull; }
5585};
5586
5587class NotTailCalledAttr : public InheritableAttr {
5588public:
5589 static NotTailCalledAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5590 auto *A = new (Ctx) NotTailCalledAttr(Loc, Ctx, 0);
5591 A->setImplicit(true);
5592 return A;
5593 }
5594
5595 NotTailCalledAttr(SourceRange R, ASTContext &Ctx
5596 , unsigned SI
5597 )
5598 : InheritableAttr(attr::NotTailCalled, R, SI, false, false)
5599 {
5600 }
5601
5602 NotTailCalledAttr *clone(ASTContext &C) const;
5603 void printPretty(raw_ostream &OS,
5604 const PrintingPolicy &Policy) const;
5605 const char *getSpelling() const;
5606
5607
5608 static bool classof(const Attr *A) { return A->getKind() == attr::NotTailCalled; }
5609};
5610
5611class OMPAllocateDeclAttr : public InheritableAttr {
5612public:
5613 enum AllocatorTypeTy {
5614 OMPDefaultMemAlloc,
5615 OMPLargeCapMemAlloc,
5616 OMPConstMemAlloc,
5617 OMPHighBWMemAlloc,
5618 OMPLowLatMemAlloc,
5619 OMPCGroupMemAlloc,
5620 OMPPTeamMemAlloc,
5621 OMPThreadMemAlloc,
5622 OMPUserDefinedMemAlloc
5623 };
5624private:
5625 AllocatorTypeTy allocatorType;
5626
5627Expr * allocator;
5628
5629public:
5630 static OMPAllocateDeclAttr *CreateImplicit(ASTContext &Ctx, AllocatorTypeTy AllocatorType, Expr * Allocator, SourceRange Loc = SourceRange()) {
5631 auto *A = new (Ctx) OMPAllocateDeclAttr(Loc, Ctx, AllocatorType, Allocator, 0);
5632 A->setImplicit(true);
5633 return A;
5634 }
5635
5636 OMPAllocateDeclAttr(SourceRange R, ASTContext &Ctx
5637 , AllocatorTypeTy AllocatorType
5638 , Expr * Allocator
5639 , unsigned SI
5640 )
5641 : InheritableAttr(attr::OMPAllocateDecl, R, SI, false, false)
5642 , allocatorType(AllocatorType)
5643 , allocator(Allocator)
5644 {
5645 }
5646
5647 OMPAllocateDeclAttr *clone(ASTContext &C) const;
5648 void printPretty(raw_ostream &OS,
5649 const PrintingPolicy &Policy) const;
5650 const char *getSpelling() const;
5651 AllocatorTypeTy getAllocatorType() const {
5652 return allocatorType;
5653 }
5654
5655 static bool ConvertStrToAllocatorTypeTy(StringRef Val, AllocatorTypeTy &Out) {
5656 Optional<AllocatorTypeTy> R = llvm::StringSwitch<Optional<AllocatorTypeTy>>(Val)
5657 .Case("omp_default_mem_alloc", OMPAllocateDeclAttr::OMPDefaultMemAlloc)
5658 .Case("omp_large_cap_mem_alloc", OMPAllocateDeclAttr::OMPLargeCapMemAlloc)
5659 .Case("omp_const_mem_alloc", OMPAllocateDeclAttr::OMPConstMemAlloc)
5660 .Case("omp_high_bw_mem_alloc", OMPAllocateDeclAttr::OMPHighBWMemAlloc)
5661 .Case("omp_low_lat_mem_alloc", OMPAllocateDeclAttr::OMPLowLatMemAlloc)
5662 .Case("omp_cgroup_mem_alloc", OMPAllocateDeclAttr::OMPCGroupMemAlloc)
5663 .Case("omp_pteam_mem_alloc", OMPAllocateDeclAttr::OMPPTeamMemAlloc)
5664 .Case("omp_thread_mem_alloc", OMPAllocateDeclAttr::OMPThreadMemAlloc)
5665 .Case("", OMPAllocateDeclAttr::OMPUserDefinedMemAlloc)
5666 .Default(Optional<AllocatorTypeTy>());
5667 if (R) {
5668 Out = *R;
5669 return true;
5670 }
5671 return false;
5672 }
5673
5674 static const char *ConvertAllocatorTypeTyToStr(AllocatorTypeTy Val) {
5675 switch(Val) {
5676 case OMPAllocateDeclAttr::OMPDefaultMemAlloc: return "omp_default_mem_alloc";
5677 case OMPAllocateDeclAttr::OMPLargeCapMemAlloc: return "omp_large_cap_mem_alloc";
5678 case OMPAllocateDeclAttr::OMPConstMemAlloc: return "omp_const_mem_alloc";
5679 case OMPAllocateDeclAttr::OMPHighBWMemAlloc: return "omp_high_bw_mem_alloc";
5680 case OMPAllocateDeclAttr::OMPLowLatMemAlloc: return "omp_low_lat_mem_alloc";
5681 case OMPAllocateDeclAttr::OMPCGroupMemAlloc: return "omp_cgroup_mem_alloc";
5682 case OMPAllocateDeclAttr::OMPPTeamMemAlloc: return "omp_pteam_mem_alloc";
5683 case OMPAllocateDeclAttr::OMPThreadMemAlloc: return "omp_thread_mem_alloc";
5684 case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc: return "";
5685 }
5686 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 5686)
;
5687 }
5688 Expr * getAllocator() const {
5689 return allocator;
5690 }
5691
5692
5693
5694 static bool classof(const Attr *A) { return A->getKind() == attr::OMPAllocateDecl; }
5695};
5696
5697class OMPCaptureKindAttr : public Attr {
5698unsigned captureKind;
5699
5700public:
5701 static OMPCaptureKindAttr *CreateImplicit(ASTContext &Ctx, unsigned CaptureKind, SourceRange Loc = SourceRange()) {
5702 auto *A = new (Ctx) OMPCaptureKindAttr(Loc, Ctx, CaptureKind, 0);
5703 A->setImplicit(true);
5704 return A;
5705 }
5706
5707 OMPCaptureKindAttr(SourceRange R, ASTContext &Ctx
5708 , unsigned CaptureKind
5709 , unsigned SI
5710 )
5711 : Attr(attr::OMPCaptureKind, R, SI, false)
5712 , captureKind(CaptureKind)
5713 {
5714 }
5715
5716 OMPCaptureKindAttr *clone(ASTContext &C) const;
5717 void printPretty(raw_ostream &OS,
5718 const PrintingPolicy &Policy) const;
5719 const char *getSpelling() const;
5720 unsigned getCaptureKind() const {
5721 return captureKind;
5722 }
5723
5724
5725
5726 static bool classof(const Attr *A) { return A->getKind() == attr::OMPCaptureKind; }
5727};
5728
5729class OMPCaptureNoInitAttr : public InheritableAttr {
5730public:
5731 static OMPCaptureNoInitAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
5732 auto *A = new (Ctx) OMPCaptureNoInitAttr(Loc, Ctx, 0);
5733 A->setImplicit(true);
5734 return A;
5735 }
5736
5737 OMPCaptureNoInitAttr(SourceRange R, ASTContext &Ctx
5738 , unsigned SI
5739 )
5740 : InheritableAttr(attr::OMPCaptureNoInit, R, SI, false, false)
5741 {
5742 }
5743
5744 OMPCaptureNoInitAttr *clone(ASTContext &C) const;
5745 void printPretty(raw_ostream &OS,
5746 const PrintingPolicy &Policy) const;
5747 const char *getSpelling() const;
5748
5749
5750 static bool classof(const Attr *A) { return A->getKind() == attr::OMPCaptureNoInit; }
5751};
5752
5753class OMPDeclareSimdDeclAttr : public Attr {
5754public:
5755 enum BranchStateTy {
5756 BS_Undefined,
5757 BS_Inbranch,
5758 BS_Notinbranch
5759 };
5760private:
5761 BranchStateTy branchState;
5762
5763Expr * simdlen;
5764
5765 unsigned uniforms_Size;
5766 Expr * *uniforms_;
5767
5768 unsigned aligneds_Size;
5769 Expr * *aligneds_;
5770
5771 unsigned alignments_Size;
5772 Expr * *alignments_;
5773
5774 unsigned linears_Size;
5775 Expr * *linears_;
5776
5777 unsigned modifiers_Size;
5778 unsigned *modifiers_;
5779
5780 unsigned steps_Size;
5781 Expr * *steps_;
5782
5783public:
5784 static OMPDeclareSimdDeclAttr *CreateImplicit(ASTContext &Ctx, BranchStateTy BranchState, Expr * Simdlen, Expr * *Uniforms, unsigned UniformsSize, Expr * *Aligneds, unsigned AlignedsSize, Expr * *Alignments, unsigned AlignmentsSize, Expr * *Linears, unsigned LinearsSize, unsigned *Modifiers, unsigned ModifiersSize, Expr * *Steps, unsigned StepsSize, SourceRange Loc = SourceRange()) {
5785 auto *A = new (Ctx) OMPDeclareSimdDeclAttr(Loc, Ctx, BranchState, Simdlen, Uniforms, UniformsSize, Aligneds, AlignedsSize, Alignments, AlignmentsSize, Linears, LinearsSize, Modifiers, ModifiersSize, Steps, StepsSize, 0);
5786 A->setImplicit(true);
5787 return A;
5788 }
5789
5790 OMPDeclareSimdDeclAttr(SourceRange R, ASTContext &Ctx
5791 , BranchStateTy BranchState
5792 , Expr * Simdlen
5793 , Expr * *Uniforms, unsigned UniformsSize
5794 , Expr * *Aligneds, unsigned AlignedsSize
5795 , Expr * *Alignments, unsigned AlignmentsSize
5796 , Expr * *Linears, unsigned LinearsSize
5797 , unsigned *Modifiers, unsigned ModifiersSize
5798 , Expr * *Steps, unsigned StepsSize
5799 , unsigned SI
5800 )
5801 : Attr(attr::OMPDeclareSimdDecl, R, SI, false)
5802 , branchState(BranchState)
5803 , simdlen(Simdlen)
5804 , uniforms_Size(UniformsSize), uniforms_(new (Ctx, 16) Expr *[uniforms_Size])
5805 , aligneds_Size(AlignedsSize), aligneds_(new (Ctx, 16) Expr *[aligneds_Size])
5806 , alignments_Size(AlignmentsSize), alignments_(new (Ctx, 16) Expr *[alignments_Size])
5807 , linears_Size(LinearsSize), linears_(new (Ctx, 16) Expr *[linears_Size])
5808 , modifiers_Size(ModifiersSize), modifiers_(new (Ctx, 16) unsigned[modifiers_Size])
5809 , steps_Size(StepsSize), steps_(new (Ctx, 16) Expr *[steps_Size])
5810 {
5811 std::copy(Uniforms, Uniforms + uniforms_Size, uniforms_);
5812 std::copy(Aligneds, Aligneds + aligneds_Size, aligneds_);
5813 std::copy(Alignments, Alignments + alignments_Size, alignments_);
5814 std::copy(Linears, Linears + linears_Size, linears_);
5815 std::copy(Modifiers, Modifiers + modifiers_Size, modifiers_);
5816 std::copy(Steps, Steps + steps_Size, steps_);
5817 }
5818
5819 OMPDeclareSimdDeclAttr(SourceRange R, ASTContext &Ctx
5820 , BranchStateTy BranchState
5821 , Expr * Simdlen
5822 , unsigned SI
5823 )
5824 : Attr(attr::OMPDeclareSimdDecl, R, SI, false)
5825 , branchState(BranchState)
5826 , simdlen(Simdlen)
5827 , uniforms_Size(0), uniforms_(nullptr)
5828 , aligneds_Size(0), aligneds_(nullptr)
5829 , alignments_Size(0), alignments_(nullptr)
5830 , linears_Size(0), linears_(nullptr)
5831 , modifiers_Size(0), modifiers_(nullptr)
5832 , steps_Size(0), steps_(nullptr)
5833 {
5834 }
5835
5836 OMPDeclareSimdDeclAttr *clone(ASTContext &C) const;
5837 void printPretty(raw_ostream &OS,
5838 const PrintingPolicy &Policy) const;
5839 const char *getSpelling() const;
5840 BranchStateTy getBranchState() const {
5841 return branchState;
5842 }
5843
5844 static bool ConvertStrToBranchStateTy(StringRef Val, BranchStateTy &Out) {
5845 Optional<BranchStateTy> R = llvm::StringSwitch<Optional<BranchStateTy>>(Val)
5846 .Case("", OMPDeclareSimdDeclAttr::BS_Undefined)
5847 .Case("inbranch", OMPDeclareSimdDeclAttr::BS_Inbranch)
5848 .Case("notinbranch", OMPDeclareSimdDeclAttr::BS_Notinbranch)
5849 .Default(Optional<BranchStateTy>());
5850 if (R) {
5851 Out = *R;
5852 return true;
5853 }
5854 return false;
5855 }
5856
5857 static const char *ConvertBranchStateTyToStr(BranchStateTy Val) {
5858 switch(Val) {
5859 case OMPDeclareSimdDeclAttr::BS_Undefined: return "";
5860 case OMPDeclareSimdDeclAttr::BS_Inbranch: return "inbranch";
5861 case OMPDeclareSimdDeclAttr::BS_Notinbranch: return "notinbranch";
5862 }
5863 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 5863)
;
5864 }
5865 Expr * getSimdlen() const {
5866 return simdlen;
5867 }
5868
5869 typedef Expr ** uniforms_iterator;
5870 uniforms_iterator uniforms_begin() const { return uniforms_; }
5871 uniforms_iterator uniforms_end() const { return uniforms_ + uniforms_Size; }
5872 unsigned uniforms_size() const { return uniforms_Size; }
5873 llvm::iterator_range<uniforms_iterator> uniforms() const { return llvm::make_range(uniforms_begin(), uniforms_end()); }
5874
5875
5876 typedef Expr ** aligneds_iterator;
5877 aligneds_iterator aligneds_begin() const { return aligneds_; }
5878 aligneds_iterator aligneds_end() const { return aligneds_ + aligneds_Size; }
5879 unsigned aligneds_size() const { return aligneds_Size; }
5880 llvm::iterator_range<aligneds_iterator> aligneds() const { return llvm::make_range(aligneds_begin(), aligneds_end()); }
5881
5882
5883 typedef Expr ** alignments_iterator;
5884 alignments_iterator alignments_begin() const { return alignments_; }
5885 alignments_iterator alignments_end() const { return alignments_ + alignments_Size; }
5886 unsigned alignments_size() const { return alignments_Size; }
5887 llvm::iterator_range<alignments_iterator> alignments() const { return llvm::make_range(alignments_begin(), alignments_end()); }
5888
5889
5890 typedef Expr ** linears_iterator;
5891 linears_iterator linears_begin() const { return linears_; }
5892 linears_iterator linears_end() const { return linears_ + linears_Size; }
5893 unsigned linears_size() const { return linears_Size; }
5894 llvm::iterator_range<linears_iterator> linears() const { return llvm::make_range(linears_begin(), linears_end()); }
5895
5896
5897 typedef unsigned* modifiers_iterator;
5898 modifiers_iterator modifiers_begin() const { return modifiers_; }
5899 modifiers_iterator modifiers_end() const { return modifiers_ + modifiers_Size; }
5900 unsigned modifiers_size() const { return modifiers_Size; }
5901 llvm::iterator_range<modifiers_iterator> modifiers() const { return llvm::make_range(modifiers_begin(), modifiers_end()); }
5902
5903
5904 typedef Expr ** steps_iterator;
5905 steps_iterator steps_begin() const { return steps_; }
5906 steps_iterator steps_end() const { return steps_ + steps_Size; }
5907 unsigned steps_size() const { return steps_Size; }
5908 llvm::iterator_range<steps_iterator> steps() const { return llvm::make_range(steps_begin(), steps_end()); }
5909
5910
5911
5912 void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy)
5913 const {
5914 if (getBranchState() != BS_Undefined)
5915 OS << ' ' << ConvertBranchStateTyToStr(getBranchState());
5916 if (auto *E = getSimdlen()) {
5917 OS << " simdlen(";
5918 E->printPretty(OS, nullptr, Policy);
5919 OS << ")";
5920 }
5921 if (uniforms_size() > 0) {
5922 OS << " uniform";
5923 StringRef Sep = "(";
5924 for (auto *E : uniforms()) {
5925 OS << Sep;
5926 E->printPretty(OS, nullptr, Policy);
5927 Sep = ", ";
5928 }
5929 OS << ")";
5930 }
5931 alignments_iterator NI = alignments_begin();
5932 for (auto *E : aligneds()) {
5933 OS << " aligned(";
5934 E->printPretty(OS, nullptr, Policy);
5935 if (*NI) {
5936 OS << ": ";
5937 (*NI)->printPretty(OS, nullptr, Policy);
5938 }
5939 OS << ")";
5940 ++NI;
5941 }
5942 steps_iterator I = steps_begin();
5943 modifiers_iterator MI = modifiers_begin();
5944 for (auto *E : linears()) {
5945 OS << " linear(";
5946 if (*MI != OMPC_LINEAR_unknown)
5947 OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "(";
5948 E->printPretty(OS, nullptr, Policy);
5949 if (*MI != OMPC_LINEAR_unknown)
5950 OS << ")";
5951 if (*I) {
5952 OS << ": ";
5953 (*I)->printPretty(OS, nullptr, Policy);
5954 }
5955 OS << ")";
5956 ++I;
5957 ++MI;
5958 }
5959 }
5960
5961
5962 static bool classof(const Attr *A) { return A->getKind() == attr::OMPDeclareSimdDecl; }
5963};
5964
5965class OMPDeclareTargetDeclAttr : public InheritableAttr {
5966public:
5967 enum MapTypeTy {
5968 MT_To,
5969 MT_Link
5970 };
5971private:
5972 MapTypeTy mapType;
5973
5974public:
5975 static OMPDeclareTargetDeclAttr *CreateImplicit(ASTContext &Ctx, MapTypeTy MapType, SourceRange Loc = SourceRange()) {
5976 auto *A = new (Ctx) OMPDeclareTargetDeclAttr(Loc, Ctx, MapType, 0);
5977 A->setImplicit(true);
5978 return A;
5979 }
5980
5981 OMPDeclareTargetDeclAttr(SourceRange R, ASTContext &Ctx
5982 , MapTypeTy MapType
5983 , unsigned SI
5984 )
5985 : InheritableAttr(attr::OMPDeclareTargetDecl, R, SI, false, false)
5986 , mapType(MapType)
5987 {
5988 }
5989
5990 OMPDeclareTargetDeclAttr *clone(ASTContext &C) const;
5991 void printPretty(raw_ostream &OS,
5992 const PrintingPolicy &Policy) const;
5993 const char *getSpelling() const;
5994 MapTypeTy getMapType() const {
5995 return mapType;
5996 }
5997
5998 static bool ConvertStrToMapTypeTy(StringRef Val, MapTypeTy &Out) {
5999 Optional<MapTypeTy> R = llvm::StringSwitch<Optional<MapTypeTy>>(Val)
6000 .Case("to", OMPDeclareTargetDeclAttr::MT_To)
6001 .Case("link", OMPDeclareTargetDeclAttr::MT_Link)
6002 .Default(Optional<MapTypeTy>());
6003 if (R) {
6004 Out = *R;
6005 return true;
6006 }
6007 return false;
6008 }
6009
6010 static const char *ConvertMapTypeTyToStr(MapTypeTy Val) {
6011 switch(Val) {
6012 case OMPDeclareTargetDeclAttr::MT_To: return "to";
6013 case OMPDeclareTargetDeclAttr::MT_Link: return "link";
6014 }
6015 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 6015)
;
6016 }
6017
6018 void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
6019 // Use fake syntax because it is for testing and debugging purpose only.
6020 if (getMapType() != MT_To)
6021 OS << ' ' << ConvertMapTypeTyToStr(getMapType());
6022 }
6023 static llvm::Optional<MapTypeTy>
6024 isDeclareTargetDeclaration(const ValueDecl *VD) {
6025 if (!VD->hasAttrs())
6026 return llvm::None;
6027 if (const auto *Attr = VD->getAttr<OMPDeclareTargetDeclAttr>())
6028 return Attr->getMapType();
6029
6030 return llvm::None;
6031 }
6032
6033
6034 static bool classof(const Attr *A) { return A->getKind() == attr::OMPDeclareTargetDecl; }
6035};
6036
6037class OMPReferencedVarAttr : public Attr {
6038Expr * ref;
6039
6040public:
6041 static OMPReferencedVarAttr *CreateImplicit(ASTContext &Ctx, Expr * Ref, SourceRange Loc = SourceRange()) {
6042 auto *A = new (Ctx) OMPReferencedVarAttr(Loc, Ctx, Ref, 0);
6043 A->setImplicit(true);
6044 return A;
6045 }
6046
6047 OMPReferencedVarAttr(SourceRange R, ASTContext &Ctx
6048 , Expr * Ref
6049 , unsigned SI
6050 )
6051 : Attr(attr::OMPReferencedVar, R, SI, false)
6052 , ref(Ref)
6053 {
6054 }
6055
6056 OMPReferencedVarAttr *clone(ASTContext &C) const;
6057 void printPretty(raw_ostream &OS,
6058 const PrintingPolicy &Policy) const;
6059 const char *getSpelling() const;
6060 Expr * getRef() const {
6061 return ref;
6062 }
6063
6064
6065
6066 static bool classof(const Attr *A) { return A->getKind() == attr::OMPReferencedVar; }
6067};
6068
6069class OMPThreadPrivateDeclAttr : public InheritableAttr {
6070public:
6071 static OMPThreadPrivateDeclAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6072 auto *A = new (Ctx) OMPThreadPrivateDeclAttr(Loc, Ctx, 0);
6073 A->setImplicit(true);
6074 return A;
6075 }
6076
6077 OMPThreadPrivateDeclAttr(SourceRange R, ASTContext &Ctx
6078 , unsigned SI
6079 )
6080 : InheritableAttr(attr::OMPThreadPrivateDecl, R, SI, false, false)
6081 {
6082 }
6083
6084 OMPThreadPrivateDeclAttr *clone(ASTContext &C) const;
6085 void printPretty(raw_ostream &OS,
6086 const PrintingPolicy &Policy) const;
6087 const char *getSpelling() const;
6088
6089
6090 static bool classof(const Attr *A) { return A->getKind() == attr::OMPThreadPrivateDecl; }
6091};
6092
6093class OSConsumedAttr : public InheritableParamAttr {
6094public:
6095 static OSConsumedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6096 auto *A = new (Ctx) OSConsumedAttr(Loc, Ctx, 0);
6097 A->setImplicit(true);
6098 return A;
6099 }
6100
6101 OSConsumedAttr(SourceRange R, ASTContext &Ctx
6102 , unsigned SI
6103 )
6104 : InheritableParamAttr(attr::OSConsumed, R, SI, false, false)
6105 {
6106 }
6107
6108 OSConsumedAttr *clone(ASTContext &C) const;
6109 void printPretty(raw_ostream &OS,
6110 const PrintingPolicy &Policy) const;
6111 const char *getSpelling() const;
6112
6113
6114 static bool classof(const Attr *A) { return A->getKind() == attr::OSConsumed; }
6115};
6116
6117class OSConsumesThisAttr : public InheritableAttr {
6118public:
6119 static OSConsumesThisAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6120 auto *A = new (Ctx) OSConsumesThisAttr(Loc, Ctx, 0);
6121 A->setImplicit(true);
6122 return A;
6123 }
6124
6125 OSConsumesThisAttr(SourceRange R, ASTContext &Ctx
6126 , unsigned SI
6127 )
6128 : InheritableAttr(attr::OSConsumesThis, R, SI, false, false)
6129 {
6130 }
6131
6132 OSConsumesThisAttr *clone(ASTContext &C) const;
6133 void printPretty(raw_ostream &OS,
6134 const PrintingPolicy &Policy) const;
6135 const char *getSpelling() const;
6136
6137
6138 static bool classof(const Attr *A) { return A->getKind() == attr::OSConsumesThis; }
6139};
6140
6141class OSReturnsNotRetainedAttr : public InheritableAttr {
6142public:
6143 static OSReturnsNotRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6144 auto *A = new (Ctx) OSReturnsNotRetainedAttr(Loc, Ctx, 0);
6145 A->setImplicit(true);
6146 return A;
6147 }
6148
6149 OSReturnsNotRetainedAttr(SourceRange R, ASTContext &Ctx
6150 , unsigned SI
6151 )
6152 : InheritableAttr(attr::OSReturnsNotRetained, R, SI, false, false)
6153 {
6154 }
6155
6156 OSReturnsNotRetainedAttr *clone(ASTContext &C) const;
6157 void printPretty(raw_ostream &OS,
6158 const PrintingPolicy &Policy) const;
6159 const char *getSpelling() const;
6160
6161
6162 static bool classof(const Attr *A) { return A->getKind() == attr::OSReturnsNotRetained; }
6163};
6164
6165class OSReturnsRetainedAttr : public InheritableAttr {
6166public:
6167 static OSReturnsRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6168 auto *A = new (Ctx) OSReturnsRetainedAttr(Loc, Ctx, 0);
6169 A->setImplicit(true);
6170 return A;
6171 }
6172
6173 OSReturnsRetainedAttr(SourceRange R, ASTContext &Ctx
6174 , unsigned SI
6175 )
6176 : InheritableAttr(attr::OSReturnsRetained, R, SI, false, false)
6177 {
6178 }
6179
6180 OSReturnsRetainedAttr *clone(ASTContext &C) const;
6181 void printPretty(raw_ostream &OS,
6182 const PrintingPolicy &Policy) const;
6183 const char *getSpelling() const;
6184
6185
6186 static bool classof(const Attr *A) { return A->getKind() == attr::OSReturnsRetained; }
6187};
6188
6189class OSReturnsRetainedOnNonZeroAttr : public InheritableAttr {
6190public:
6191 static OSReturnsRetainedOnNonZeroAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6192 auto *A = new (Ctx) OSReturnsRetainedOnNonZeroAttr(Loc, Ctx, 0);
6193 A->setImplicit(true);
6194 return A;
6195 }
6196
6197 OSReturnsRetainedOnNonZeroAttr(SourceRange R, ASTContext &Ctx
6198 , unsigned SI
6199 )
6200 : InheritableAttr(attr::OSReturnsRetainedOnNonZero, R, SI, false, false)
6201 {
6202 }
6203
6204 OSReturnsRetainedOnNonZeroAttr *clone(ASTContext &C) const;
6205 void printPretty(raw_ostream &OS,
6206 const PrintingPolicy &Policy) const;
6207 const char *getSpelling() const;
6208
6209
6210 static bool classof(const Attr *A) { return A->getKind() == attr::OSReturnsRetainedOnNonZero; }
6211};
6212
6213class OSReturnsRetainedOnZeroAttr : public InheritableAttr {
6214public:
6215 static OSReturnsRetainedOnZeroAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6216 auto *A = new (Ctx) OSReturnsRetainedOnZeroAttr(Loc, Ctx, 0);
6217 A->setImplicit(true);
6218 return A;
6219 }
6220
6221 OSReturnsRetainedOnZeroAttr(SourceRange R, ASTContext &Ctx
6222 , unsigned SI
6223 )
6224 : InheritableAttr(attr::OSReturnsRetainedOnZero, R, SI, false, false)
6225 {
6226 }
6227
6228 OSReturnsRetainedOnZeroAttr *clone(ASTContext &C) const;
6229 void printPretty(raw_ostream &OS,
6230 const PrintingPolicy &Policy) const;
6231 const char *getSpelling() const;
6232
6233
6234 static bool classof(const Attr *A) { return A->getKind() == attr::OSReturnsRetainedOnZero; }
6235};
6236
6237class ObjCBoxableAttr : public Attr {
6238public:
6239 static ObjCBoxableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6240 auto *A = new (Ctx) ObjCBoxableAttr(Loc, Ctx, 0);
6241 A->setImplicit(true);
6242 return A;
6243 }
6244
6245 ObjCBoxableAttr(SourceRange R, ASTContext &Ctx
6246 , unsigned SI
6247 )
6248 : Attr(attr::ObjCBoxable, R, SI, false)
6249 {
6250 }
6251
6252 ObjCBoxableAttr *clone(ASTContext &C) const;
6253 void printPretty(raw_ostream &OS,
6254 const PrintingPolicy &Policy) const;
6255 const char *getSpelling() const;
6256
6257
6258 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCBoxable; }
6259};
6260
6261class ObjCBridgeAttr : public InheritableAttr {
6262IdentifierInfo * bridgedType;
6263
6264public:
6265 static ObjCBridgeAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * BridgedType, SourceRange Loc = SourceRange()) {
6266 auto *A = new (Ctx) ObjCBridgeAttr(Loc, Ctx, BridgedType, 0);
6267 A->setImplicit(true);
6268 return A;
6269 }
6270
6271 ObjCBridgeAttr(SourceRange R, ASTContext &Ctx
6272 , IdentifierInfo * BridgedType
6273 , unsigned SI
6274 )
6275 : InheritableAttr(attr::ObjCBridge, R, SI, false, false)
6276 , bridgedType(BridgedType)
6277 {
6278 }
6279
6280 ObjCBridgeAttr *clone(ASTContext &C) const;
6281 void printPretty(raw_ostream &OS,
6282 const PrintingPolicy &Policy) const;
6283 const char *getSpelling() const;
6284 IdentifierInfo * getBridgedType() const {
6285 return bridgedType;
6286 }
6287
6288
6289
6290 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCBridge; }
6291};
6292
6293class ObjCBridgeMutableAttr : public InheritableAttr {
6294IdentifierInfo * bridgedType;
6295
6296public:
6297 static ObjCBridgeMutableAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * BridgedType, SourceRange Loc = SourceRange()) {
6298 auto *A = new (Ctx) ObjCBridgeMutableAttr(Loc, Ctx, BridgedType, 0);
6299 A->setImplicit(true);
6300 return A;
6301 }
6302
6303 ObjCBridgeMutableAttr(SourceRange R, ASTContext &Ctx
6304 , IdentifierInfo * BridgedType
6305 , unsigned SI
6306 )
6307 : InheritableAttr(attr::ObjCBridgeMutable, R, SI, false, false)
6308 , bridgedType(BridgedType)
6309 {
6310 }
6311
6312 ObjCBridgeMutableAttr *clone(ASTContext &C) const;
6313 void printPretty(raw_ostream &OS,
6314 const PrintingPolicy &Policy) const;
6315 const char *getSpelling() const;
6316 IdentifierInfo * getBridgedType() const {
6317 return bridgedType;
6318 }
6319
6320
6321
6322 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCBridgeMutable; }
6323};
6324
6325class ObjCBridgeRelatedAttr : public InheritableAttr {
6326IdentifierInfo * relatedClass;
6327
6328IdentifierInfo * classMethod;
6329
6330IdentifierInfo * instanceMethod;
6331
6332public:
6333 static ObjCBridgeRelatedAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * RelatedClass, IdentifierInfo * ClassMethod, IdentifierInfo * InstanceMethod, SourceRange Loc = SourceRange()) {
6334 auto *A = new (Ctx) ObjCBridgeRelatedAttr(Loc, Ctx, RelatedClass, ClassMethod, InstanceMethod, 0);
6335 A->setImplicit(true);
6336 return A;
6337 }
6338
6339 ObjCBridgeRelatedAttr(SourceRange R, ASTContext &Ctx
6340 , IdentifierInfo * RelatedClass
6341 , IdentifierInfo * ClassMethod
6342 , IdentifierInfo * InstanceMethod
6343 , unsigned SI
6344 )
6345 : InheritableAttr(attr::ObjCBridgeRelated, R, SI, false, false)
6346 , relatedClass(RelatedClass)
6347 , classMethod(ClassMethod)
6348 , instanceMethod(InstanceMethod)
6349 {
6350 }
6351
6352 ObjCBridgeRelatedAttr *clone(ASTContext &C) const;
6353 void printPretty(raw_ostream &OS,
6354 const PrintingPolicy &Policy) const;
6355 const char *getSpelling() const;
6356 IdentifierInfo * getRelatedClass() const {
6357 return relatedClass;
6358 }
6359
6360 IdentifierInfo * getClassMethod() const {
6361 return classMethod;
6362 }
6363
6364 IdentifierInfo * getInstanceMethod() const {
6365 return instanceMethod;
6366 }
6367
6368
6369
6370 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCBridgeRelated; }
6371};
6372
6373class ObjCClassStubAttr : public Attr {
6374public:
6375 static ObjCClassStubAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6376 auto *A = new (Ctx) ObjCClassStubAttr(Loc, Ctx, 0);
6377 A->setImplicit(true);
6378 return A;
6379 }
6380
6381 ObjCClassStubAttr(SourceRange R, ASTContext &Ctx
6382 , unsigned SI
6383 )
6384 : Attr(attr::ObjCClassStub, R, SI, false)
6385 {
6386 }
6387
6388 ObjCClassStubAttr *clone(ASTContext &C) const;
6389 void printPretty(raw_ostream &OS,
6390 const PrintingPolicy &Policy) const;
6391 const char *getSpelling() const;
6392
6393
6394 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCClassStub; }
6395};
6396
6397class ObjCDesignatedInitializerAttr : public Attr {
6398public:
6399 static ObjCDesignatedInitializerAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6400 auto *A = new (Ctx) ObjCDesignatedInitializerAttr(Loc, Ctx, 0);
6401 A->setImplicit(true);
6402 return A;
6403 }
6404
6405 ObjCDesignatedInitializerAttr(SourceRange R, ASTContext &Ctx
6406 , unsigned SI
6407 )
6408 : Attr(attr::ObjCDesignatedInitializer, R, SI, false)
6409 {
6410 }
6411
6412 ObjCDesignatedInitializerAttr *clone(ASTContext &C) const;
6413 void printPretty(raw_ostream &OS,
6414 const PrintingPolicy &Policy) const;
6415 const char *getSpelling() const;
6416
6417
6418 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCDesignatedInitializer; }
6419};
6420
6421class ObjCExceptionAttr : public InheritableAttr {
6422public:
6423 static ObjCExceptionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6424 auto *A = new (Ctx) ObjCExceptionAttr(Loc, Ctx, 0);
6425 A->setImplicit(true);
6426 return A;
6427 }
6428
6429 ObjCExceptionAttr(SourceRange R, ASTContext &Ctx
6430 , unsigned SI
6431 )
6432 : InheritableAttr(attr::ObjCException, R, SI, false, false)
6433 {
6434 }
6435
6436 ObjCExceptionAttr *clone(ASTContext &C) const;
6437 void printPretty(raw_ostream &OS,
6438 const PrintingPolicy &Policy) const;
6439 const char *getSpelling() const;
6440
6441
6442 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCException; }
6443};
6444
6445class ObjCExplicitProtocolImplAttr : public InheritableAttr {
6446public:
6447 static ObjCExplicitProtocolImplAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6448 auto *A = new (Ctx) ObjCExplicitProtocolImplAttr(Loc, Ctx, 0);
6449 A->setImplicit(true);
6450 return A;
6451 }
6452
6453 ObjCExplicitProtocolImplAttr(SourceRange R, ASTContext &Ctx
6454 , unsigned SI
6455 )
6456 : InheritableAttr(attr::ObjCExplicitProtocolImpl, R, SI, false, false)
6457 {
6458 }
6459
6460 ObjCExplicitProtocolImplAttr *clone(ASTContext &C) const;
6461 void printPretty(raw_ostream &OS,
6462 const PrintingPolicy &Policy) const;
6463 const char *getSpelling() const;
6464
6465
6466 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCExplicitProtocolImpl; }
6467};
6468
6469class ObjCExternallyRetainedAttr : public InheritableAttr {
6470public:
6471 static ObjCExternallyRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6472 auto *A = new (Ctx) ObjCExternallyRetainedAttr(Loc, Ctx, 0);
6473 A->setImplicit(true);
6474 return A;
6475 }
6476
6477 ObjCExternallyRetainedAttr(SourceRange R, ASTContext &Ctx
6478 , unsigned SI
6479 )
6480 : InheritableAttr(attr::ObjCExternallyRetained, R, SI, false, false)
6481 {
6482 }
6483
6484 ObjCExternallyRetainedAttr *clone(ASTContext &C) const;
6485 void printPretty(raw_ostream &OS,
6486 const PrintingPolicy &Policy) const;
6487 const char *getSpelling() const;
6488
6489
6490 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCExternallyRetained; }
6491};
6492
6493class ObjCGCAttr : public TypeAttr {
6494IdentifierInfo * kind;
6495
6496public:
6497 static ObjCGCAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * Kind, SourceRange Loc = SourceRange()) {
6498 auto *A = new (Ctx) ObjCGCAttr(Loc, Ctx, Kind, 0);
6499 A->setImplicit(true);
6500 return A;
6501 }
6502
6503 ObjCGCAttr(SourceRange R, ASTContext &Ctx
6504 , IdentifierInfo * Kind
6505 , unsigned SI
6506 )
6507 : TypeAttr(attr::ObjCGC, R, SI, false)
6508 , kind(Kind)
6509 {
6510 }
6511
6512 ObjCGCAttr *clone(ASTContext &C) const;
6513 void printPretty(raw_ostream &OS,
6514 const PrintingPolicy &Policy) const;
6515 const char *getSpelling() const;
6516 IdentifierInfo * getKind() const {
6517 return kind;
6518 }
6519
6520
6521
6522 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCGC; }
6523};
6524
6525class ObjCIndependentClassAttr : public InheritableAttr {
6526public:
6527 static ObjCIndependentClassAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6528 auto *A = new (Ctx) ObjCIndependentClassAttr(Loc, Ctx, 0);
6529 A->setImplicit(true);
6530 return A;
6531 }
6532
6533 ObjCIndependentClassAttr(SourceRange R, ASTContext &Ctx
6534 , unsigned SI
6535 )
6536 : InheritableAttr(attr::ObjCIndependentClass, R, SI, false, false)
6537 {
6538 }
6539
6540 ObjCIndependentClassAttr *clone(ASTContext &C) const;
6541 void printPretty(raw_ostream &OS,
6542 const PrintingPolicy &Policy) const;
6543 const char *getSpelling() const;
6544
6545
6546 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCIndependentClass; }
6547};
6548
6549class ObjCInertUnsafeUnretainedAttr : public TypeAttr {
6550public:
6551 static ObjCInertUnsafeUnretainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6552 auto *A = new (Ctx) ObjCInertUnsafeUnretainedAttr(Loc, Ctx, 0);
6553 A->setImplicit(true);
6554 return A;
6555 }
6556
6557 ObjCInertUnsafeUnretainedAttr(SourceRange R, ASTContext &Ctx
6558 , unsigned SI
6559 )
6560 : TypeAttr(attr::ObjCInertUnsafeUnretained, R, SI, false)
6561 {
6562 }
6563
6564 ObjCInertUnsafeUnretainedAttr *clone(ASTContext &C) const;
6565 void printPretty(raw_ostream &OS,
6566 const PrintingPolicy &Policy) const;
6567 const char *getSpelling() const;
6568
6569
6570 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCInertUnsafeUnretained; }
6571};
6572
6573class ObjCKindOfAttr : public TypeAttr {
6574public:
6575 static ObjCKindOfAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6576 auto *A = new (Ctx) ObjCKindOfAttr(Loc, Ctx, 0);
6577 A->setImplicit(true);
6578 return A;
6579 }
6580
6581 ObjCKindOfAttr(SourceRange R, ASTContext &Ctx
6582 , unsigned SI
6583 )
6584 : TypeAttr(attr::ObjCKindOf, R, SI, false)
6585 {
6586 }
6587
6588 ObjCKindOfAttr *clone(ASTContext &C) const;
6589 void printPretty(raw_ostream &OS,
6590 const PrintingPolicy &Policy) const;
6591 const char *getSpelling() const;
6592
6593
6594 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCKindOf; }
6595};
6596
6597class ObjCMethodFamilyAttr : public InheritableAttr {
6598public:
6599 enum FamilyKind {
6600 OMF_None,
6601 OMF_alloc,
6602 OMF_copy,
6603 OMF_init,
6604 OMF_mutableCopy,
6605 OMF_new
6606 };
6607private:
6608 FamilyKind family;
6609
6610public:
6611 static ObjCMethodFamilyAttr *CreateImplicit(ASTContext &Ctx, FamilyKind Family, SourceRange Loc = SourceRange()) {
6612 auto *A = new (Ctx) ObjCMethodFamilyAttr(Loc, Ctx, Family, 0);
6613 A->setImplicit(true);
6614 return A;
6615 }
6616
6617 ObjCMethodFamilyAttr(SourceRange R, ASTContext &Ctx
6618 , FamilyKind Family
6619 , unsigned SI
6620 )
6621 : InheritableAttr(attr::ObjCMethodFamily, R, SI, false, false)
6622 , family(Family)
6623 {
6624 }
6625
6626 ObjCMethodFamilyAttr *clone(ASTContext &C) const;
6627 void printPretty(raw_ostream &OS,
6628 const PrintingPolicy &Policy) const;
6629 const char *getSpelling() const;
6630 FamilyKind getFamily() const {
6631 return family;
6632 }
6633
6634 static bool ConvertStrToFamilyKind(StringRef Val, FamilyKind &Out) {
6635 Optional<FamilyKind> R = llvm::StringSwitch<Optional<FamilyKind>>(Val)
6636 .Case("none", ObjCMethodFamilyAttr::OMF_None)
6637 .Case("alloc", ObjCMethodFamilyAttr::OMF_alloc)
6638 .Case("copy", ObjCMethodFamilyAttr::OMF_copy)
6639 .Case("init", ObjCMethodFamilyAttr::OMF_init)
6640 .Case("mutableCopy", ObjCMethodFamilyAttr::OMF_mutableCopy)
6641 .Case("new", ObjCMethodFamilyAttr::OMF_new)
6642 .Default(Optional<FamilyKind>());
6643 if (R) {
6644 Out = *R;
6645 return true;
6646 }
6647 return false;
6648 }
6649
6650 static const char *ConvertFamilyKindToStr(FamilyKind Val) {
6651 switch(Val) {
6652 case ObjCMethodFamilyAttr::OMF_None: return "none";
6653 case ObjCMethodFamilyAttr::OMF_alloc: return "alloc";
6654 case ObjCMethodFamilyAttr::OMF_copy: return "copy";
6655 case ObjCMethodFamilyAttr::OMF_init: return "init";
6656 case ObjCMethodFamilyAttr::OMF_mutableCopy: return "mutableCopy";
6657 case ObjCMethodFamilyAttr::OMF_new: return "new";
6658 }
6659 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 6659)
;
6660 }
6661
6662
6663 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCMethodFamily; }
6664};
6665
6666class ObjCNSObjectAttr : public InheritableAttr {
6667public:
6668 static ObjCNSObjectAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6669 auto *A = new (Ctx) ObjCNSObjectAttr(Loc, Ctx, 0);
6670 A->setImplicit(true);
6671 return A;
6672 }
6673
6674 ObjCNSObjectAttr(SourceRange R, ASTContext &Ctx
6675 , unsigned SI
6676 )
6677 : InheritableAttr(attr::ObjCNSObject, R, SI, false, false)
6678 {
6679 }
6680
6681 ObjCNSObjectAttr *clone(ASTContext &C) const;
6682 void printPretty(raw_ostream &OS,
6683 const PrintingPolicy &Policy) const;
6684 const char *getSpelling() const;
6685
6686
6687 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCNSObject; }
6688};
6689
6690class ObjCNonLazyClassAttr : public Attr {
6691public:
6692 static ObjCNonLazyClassAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6693 auto *A = new (Ctx) ObjCNonLazyClassAttr(Loc, Ctx, 0);
6694 A->setImplicit(true);
6695 return A;
6696 }
6697
6698 ObjCNonLazyClassAttr(SourceRange R, ASTContext &Ctx
6699 , unsigned SI
6700 )
6701 : Attr(attr::ObjCNonLazyClass, R, SI, false)
6702 {
6703 }
6704
6705 ObjCNonLazyClassAttr *clone(ASTContext &C) const;
6706 void printPretty(raw_ostream &OS,
6707 const PrintingPolicy &Policy) const;
6708 const char *getSpelling() const;
6709
6710
6711 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCNonLazyClass; }
6712};
6713
6714class ObjCOwnershipAttr : public InheritableAttr {
6715IdentifierInfo * kind;
6716
6717public:
6718 static ObjCOwnershipAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * Kind, SourceRange Loc = SourceRange()) {
6719 auto *A = new (Ctx) ObjCOwnershipAttr(Loc, Ctx, Kind, 0);
6720 A->setImplicit(true);
6721 return A;
6722 }
6723
6724 ObjCOwnershipAttr(SourceRange R, ASTContext &Ctx
6725 , IdentifierInfo * Kind
6726 , unsigned SI
6727 )
6728 : InheritableAttr(attr::ObjCOwnership, R, SI, false, false)
6729 , kind(Kind)
6730 {
6731 }
6732
6733 ObjCOwnershipAttr *clone(ASTContext &C) const;
6734 void printPretty(raw_ostream &OS,
6735 const PrintingPolicy &Policy) const;
6736 const char *getSpelling() const;
6737 IdentifierInfo * getKind() const {
6738 return kind;
6739 }
6740
6741
6742
6743 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCOwnership; }
6744};
6745
6746class ObjCPreciseLifetimeAttr : public InheritableAttr {
6747public:
6748 static ObjCPreciseLifetimeAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6749 auto *A = new (Ctx) ObjCPreciseLifetimeAttr(Loc, Ctx, 0);
6750 A->setImplicit(true);
6751 return A;
6752 }
6753
6754 ObjCPreciseLifetimeAttr(SourceRange R, ASTContext &Ctx
6755 , unsigned SI
6756 )
6757 : InheritableAttr(attr::ObjCPreciseLifetime, R, SI, false, false)
6758 {
6759 }
6760
6761 ObjCPreciseLifetimeAttr *clone(ASTContext &C) const;
6762 void printPretty(raw_ostream &OS,
6763 const PrintingPolicy &Policy) const;
6764 const char *getSpelling() const;
6765
6766
6767 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCPreciseLifetime; }
6768};
6769
6770class ObjCRequiresPropertyDefsAttr : public InheritableAttr {
6771public:
6772 static ObjCRequiresPropertyDefsAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6773 auto *A = new (Ctx) ObjCRequiresPropertyDefsAttr(Loc, Ctx, 0);
6774 A->setImplicit(true);
6775 return A;
6776 }
6777
6778 ObjCRequiresPropertyDefsAttr(SourceRange R, ASTContext &Ctx
6779 , unsigned SI
6780 )
6781 : InheritableAttr(attr::ObjCRequiresPropertyDefs, R, SI, false, false)
6782 {
6783 }
6784
6785 ObjCRequiresPropertyDefsAttr *clone(ASTContext &C) const;
6786 void printPretty(raw_ostream &OS,
6787 const PrintingPolicy &Policy) const;
6788 const char *getSpelling() const;
6789
6790
6791 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRequiresPropertyDefs; }
6792};
6793
6794class ObjCRequiresSuperAttr : public InheritableAttr {
6795public:
6796 static ObjCRequiresSuperAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6797 auto *A = new (Ctx) ObjCRequiresSuperAttr(Loc, Ctx, 0);
6798 A->setImplicit(true);
6799 return A;
6800 }
6801
6802 ObjCRequiresSuperAttr(SourceRange R, ASTContext &Ctx
6803 , unsigned SI
6804 )
6805 : InheritableAttr(attr::ObjCRequiresSuper, R, SI, false, false)
6806 {
6807 }
6808
6809 ObjCRequiresSuperAttr *clone(ASTContext &C) const;
6810 void printPretty(raw_ostream &OS,
6811 const PrintingPolicy &Policy) const;
6812 const char *getSpelling() const;
6813
6814
6815 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRequiresSuper; }
6816};
6817
6818class ObjCReturnsInnerPointerAttr : public InheritableAttr {
6819public:
6820 static ObjCReturnsInnerPointerAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6821 auto *A = new (Ctx) ObjCReturnsInnerPointerAttr(Loc, Ctx, 0);
6822 A->setImplicit(true);
6823 return A;
6824 }
6825
6826 ObjCReturnsInnerPointerAttr(SourceRange R, ASTContext &Ctx
6827 , unsigned SI
6828 )
6829 : InheritableAttr(attr::ObjCReturnsInnerPointer, R, SI, false, false)
6830 {
6831 }
6832
6833 ObjCReturnsInnerPointerAttr *clone(ASTContext &C) const;
6834 void printPretty(raw_ostream &OS,
6835 const PrintingPolicy &Policy) const;
6836 const char *getSpelling() const;
6837
6838
6839 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCReturnsInnerPointer; }
6840};
6841
6842class ObjCRootClassAttr : public InheritableAttr {
6843public:
6844 static ObjCRootClassAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6845 auto *A = new (Ctx) ObjCRootClassAttr(Loc, Ctx, 0);
6846 A->setImplicit(true);
6847 return A;
6848 }
6849
6850 ObjCRootClassAttr(SourceRange R, ASTContext &Ctx
6851 , unsigned SI
6852 )
6853 : InheritableAttr(attr::ObjCRootClass, R, SI, false, false)
6854 {
6855 }
6856
6857 ObjCRootClassAttr *clone(ASTContext &C) const;
6858 void printPretty(raw_ostream &OS,
6859 const PrintingPolicy &Policy) const;
6860 const char *getSpelling() const;
6861
6862
6863 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRootClass; }
6864};
6865
6866class ObjCRuntimeNameAttr : public Attr {
6867unsigned metadataNameLength;
6868char *metadataName;
6869
6870public:
6871 static ObjCRuntimeNameAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef MetadataName, SourceRange Loc = SourceRange()) {
6872 auto *A = new (Ctx) ObjCRuntimeNameAttr(Loc, Ctx, MetadataName, 0);
6873 A->setImplicit(true);
6874 return A;
6875 }
6876
6877 ObjCRuntimeNameAttr(SourceRange R, ASTContext &Ctx
6878 , llvm::StringRef MetadataName
6879 , unsigned SI
6880 )
6881 : Attr(attr::ObjCRuntimeName, R, SI, false)
6882 , metadataNameLength(MetadataName.size()),metadataName(new (Ctx, 1) char[metadataNameLength])
6883 {
6884 if (!MetadataName.empty())
6885 std::memcpy(metadataName, MetadataName.data(), metadataNameLength);
6886 }
6887
6888 ObjCRuntimeNameAttr *clone(ASTContext &C) const;
6889 void printPretty(raw_ostream &OS,
6890 const PrintingPolicy &Policy) const;
6891 const char *getSpelling() const;
6892 llvm::StringRef getMetadataName() const {
6893 return llvm::StringRef(metadataName, metadataNameLength);
6894 }
6895 unsigned getMetadataNameLength() const {
6896 return metadataNameLength;
6897 }
6898 void setMetadataName(ASTContext &C, llvm::StringRef S) {
6899 metadataNameLength = S.size();
6900 this->metadataName = new (C, 1) char [metadataNameLength];
6901 if (!S.empty())
6902 std::memcpy(this->metadataName, S.data(), metadataNameLength);
6903 }
6904
6905
6906
6907 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRuntimeName; }
6908};
6909
6910class ObjCRuntimeVisibleAttr : public Attr {
6911public:
6912 static ObjCRuntimeVisibleAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6913 auto *A = new (Ctx) ObjCRuntimeVisibleAttr(Loc, Ctx, 0);
6914 A->setImplicit(true);
6915 return A;
6916 }
6917
6918 ObjCRuntimeVisibleAttr(SourceRange R, ASTContext &Ctx
6919 , unsigned SI
6920 )
6921 : Attr(attr::ObjCRuntimeVisible, R, SI, false)
6922 {
6923 }
6924
6925 ObjCRuntimeVisibleAttr *clone(ASTContext &C) const;
6926 void printPretty(raw_ostream &OS,
6927 const PrintingPolicy &Policy) const;
6928 const char *getSpelling() const;
6929
6930
6931 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRuntimeVisible; }
6932};
6933
6934class ObjCSubclassingRestrictedAttr : public InheritableAttr {
6935public:
6936 static ObjCSubclassingRestrictedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
6937 auto *A = new (Ctx) ObjCSubclassingRestrictedAttr(Loc, Ctx, 0);
6938 A->setImplicit(true);
6939 return A;
6940 }
6941
6942 ObjCSubclassingRestrictedAttr(SourceRange R, ASTContext &Ctx
6943 , unsigned SI
6944 )
6945 : InheritableAttr(attr::ObjCSubclassingRestricted, R, SI, false, false)
6946 {
6947 }
6948
6949 ObjCSubclassingRestrictedAttr *clone(ASTContext &C) const;
6950 void printPretty(raw_ostream &OS,
6951 const PrintingPolicy &Policy) const;
6952 const char *getSpelling() const;
6953
6954
6955 static bool classof(const Attr *A) { return A->getKind() == attr::ObjCSubclassingRestricted; }
6956};
6957
6958class OpenCLAccessAttr : public Attr {
6959public:
6960 enum Spelling {
6961 Keyword_read_only = 0,
6962 Keyword_write_only = 2,
6963 Keyword_read_write = 4
6964 };
6965
6966 static OpenCLAccessAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
6967 auto *A = new (Ctx) OpenCLAccessAttr(Loc, Ctx, S);
6968 A->setImplicit(true);
6969 return A;
6970 }
6971
6972 OpenCLAccessAttr(SourceRange R, ASTContext &Ctx
6973 , unsigned SI
6974 )
6975 : Attr(attr::OpenCLAccess, R, SI, false)
6976 {
6977 }
6978
6979 OpenCLAccessAttr *clone(ASTContext &C) const;
6980 void printPretty(raw_ostream &OS,
6981 const PrintingPolicy &Policy) const;
6982 const char *getSpelling() const;
6983 Spelling getSemanticSpelling() const {
6984 switch (SpellingListIndex) {
6985 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 6985)
;
6986 case 0: return Keyword_read_only;
6987 case 1: return Keyword_read_only;
6988 case 2: return Keyword_write_only;
6989 case 3: return Keyword_write_only;
6990 case 4: return Keyword_read_write;
6991 case 5: return Keyword_read_write;
6992 }
6993 }
6994 bool isReadOnly() const { return SpellingListIndex == 0 ||
6995 SpellingListIndex == 1; }
6996 bool isReadWrite() const { return SpellingListIndex == 4 ||
6997 SpellingListIndex == 5; }
6998 bool isWriteOnly() const { return SpellingListIndex == 2 ||
6999 SpellingListIndex == 3; }
7000
7001
7002 static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLAccess; }
7003};
7004
7005class OpenCLConstantAddressSpaceAttr : public TypeAttr {
7006public:
7007 static OpenCLConstantAddressSpaceAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7008 auto *A = new (Ctx) OpenCLConstantAddressSpaceAttr(Loc, Ctx, 0);
7009 A->setImplicit(true);
7010 return A;
7011 }
7012
7013 OpenCLConstantAddressSpaceAttr(SourceRange R, ASTContext &Ctx
7014 , unsigned SI
7015 )
7016 : TypeAttr(attr::OpenCLConstantAddressSpace, R, SI, false)
7017 {
7018 }
7019
7020 OpenCLConstantAddressSpaceAttr *clone(ASTContext &C) const;
7021 void printPretty(raw_ostream &OS,
7022 const PrintingPolicy &Policy) const;
7023 const char *getSpelling() const;
7024
7025
7026 static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLConstantAddressSpace; }
7027};
7028
7029class OpenCLGenericAddressSpaceAttr : public TypeAttr {
7030public:
7031 static OpenCLGenericAddressSpaceAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7032 auto *A = new (Ctx) OpenCLGenericAddressSpaceAttr(Loc, Ctx, 0);
7033 A->setImplicit(true);
7034 return A;
7035 }
7036
7037 OpenCLGenericAddressSpaceAttr(SourceRange R, ASTContext &Ctx
7038 , unsigned SI
7039 )
7040 : TypeAttr(attr::OpenCLGenericAddressSpace, R, SI, false)
7041 {
7042 }
7043
7044 OpenCLGenericAddressSpaceAttr *clone(ASTContext &C) const;
7045 void printPretty(raw_ostream &OS,
7046 const PrintingPolicy &Policy) const;
7047 const char *getSpelling() const;
7048
7049
7050 static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLGenericAddressSpace; }
7051};
7052
7053class OpenCLGlobalAddressSpaceAttr : public TypeAttr {
7054public:
7055 static OpenCLGlobalAddressSpaceAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7056 auto *A = new (Ctx) OpenCLGlobalAddressSpaceAttr(Loc, Ctx, 0);
7057 A->setImplicit(true);
7058 return A;
7059 }
7060
7061 OpenCLGlobalAddressSpaceAttr(SourceRange R, ASTContext &Ctx
7062 , unsigned SI
7063 )
7064 : TypeAttr(attr::OpenCLGlobalAddressSpace, R, SI, false)
7065 {
7066 }
7067
7068 OpenCLGlobalAddressSpaceAttr *clone(ASTContext &C) const;
7069 void printPretty(raw_ostream &OS,
7070 const PrintingPolicy &Policy) const;
7071 const char *getSpelling() const;
7072
7073
7074 static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLGlobalAddressSpace; }
7075};
7076
7077class OpenCLIntelReqdSubGroupSizeAttr : public InheritableAttr {
7078unsigned subGroupSize;
7079
7080public:
7081 static OpenCLIntelReqdSubGroupSizeAttr *CreateImplicit(ASTContext &Ctx, unsigned SubGroupSize, SourceRange Loc = SourceRange()) {
7082 auto *A = new (Ctx) OpenCLIntelReqdSubGroupSizeAttr(Loc, Ctx, SubGroupSize, 0);
7083 A->setImplicit(true);
7084 return A;
7085 }
7086
7087 OpenCLIntelReqdSubGroupSizeAttr(SourceRange R, ASTContext &Ctx
7088 , unsigned SubGroupSize
7089 , unsigned SI
7090 )
7091 : InheritableAttr(attr::OpenCLIntelReqdSubGroupSize, R, SI, false, false)
7092 , subGroupSize(SubGroupSize)
7093 {
7094 }
7095
7096 OpenCLIntelReqdSubGroupSizeAttr *clone(ASTContext &C) const;
7097 void printPretty(raw_ostream &OS,
7098 const PrintingPolicy &Policy) const;
7099 const char *getSpelling() const;
7100 unsigned getSubGroupSize() const {
7101 return subGroupSize;
7102 }
7103
7104
7105
7106 static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLIntelReqdSubGroupSize; }
7107};
7108
7109class OpenCLKernelAttr : public InheritableAttr {
7110public:
7111 static OpenCLKernelAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7112 auto *A = new (Ctx) OpenCLKernelAttr(Loc, Ctx, 0);
7113 A->setImplicit(true);
7114 return A;
7115 }
7116
7117 OpenCLKernelAttr(SourceRange R, ASTContext &Ctx
7118 , unsigned SI
7119 )
7120 : InheritableAttr(attr::OpenCLKernel, R, SI, false, false)
7121 {
7122 }
7123
7124 OpenCLKernelAttr *clone(ASTContext &C) const;
7125 void printPretty(raw_ostream &OS,
7126 const PrintingPolicy &Policy) const;
7127 const char *getSpelling() const;
7128
7129
7130 static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLKernel; }
7131};
7132
7133class OpenCLLocalAddressSpaceAttr : public TypeAttr {
7134public:
7135 static OpenCLLocalAddressSpaceAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7136 auto *A = new (Ctx) OpenCLLocalAddressSpaceAttr(Loc, Ctx, 0);
7137 A->setImplicit(true);
7138 return A;
7139 }
7140
7141 OpenCLLocalAddressSpaceAttr(SourceRange R, ASTContext &Ctx
7142 , unsigned SI
7143 )
7144 : TypeAttr(attr::OpenCLLocalAddressSpace, R, SI, false)
7145 {
7146 }
7147
7148 OpenCLLocalAddressSpaceAttr *clone(ASTContext &C) const;
7149 void printPretty(raw_ostream &OS,
7150 const PrintingPolicy &Policy) const;
7151 const char *getSpelling() const;
7152
7153
7154 static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLLocalAddressSpace; }
7155};
7156
7157class OpenCLPrivateAddressSpaceAttr : public TypeAttr {
7158public:
7159 static OpenCLPrivateAddressSpaceAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7160 auto *A = new (Ctx) OpenCLPrivateAddressSpaceAttr(Loc, Ctx, 0);
7161 A->setImplicit(true);
7162 return A;
7163 }
7164
7165 OpenCLPrivateAddressSpaceAttr(SourceRange R, ASTContext &Ctx
7166 , unsigned SI
7167 )
7168 : TypeAttr(attr::OpenCLPrivateAddressSpace, R, SI, false)
7169 {
7170 }
7171
7172 OpenCLPrivateAddressSpaceAttr *clone(ASTContext &C) const;
7173 void printPretty(raw_ostream &OS,
7174 const PrintingPolicy &Policy) const;
7175 const char *getSpelling() const;
7176
7177
7178 static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLPrivateAddressSpace; }
7179};
7180
7181class OpenCLUnrollHintAttr : public InheritableAttr {
7182unsigned unrollHint;
7183
7184public:
7185 static OpenCLUnrollHintAttr *CreateImplicit(ASTContext &Ctx, unsigned UnrollHint, SourceRange Loc = SourceRange()) {
7186 auto *A = new (Ctx) OpenCLUnrollHintAttr(Loc, Ctx, UnrollHint, 0);
7187 A->setImplicit(true);
7188 return A;
7189 }
7190
7191 OpenCLUnrollHintAttr(SourceRange R, ASTContext &Ctx
7192 , unsigned UnrollHint
7193 , unsigned SI
7194 )
7195 : InheritableAttr(attr::OpenCLUnrollHint, R, SI, false, false)
7196 , unrollHint(UnrollHint)
7197 {
7198 }
7199
7200 OpenCLUnrollHintAttr *clone(ASTContext &C) const;
7201 void printPretty(raw_ostream &OS,
7202 const PrintingPolicy &Policy) const;
7203 const char *getSpelling() const;
7204 unsigned getUnrollHint() const {
7205 return unrollHint;
7206 }
7207
7208
7209
7210 static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLUnrollHint; }
7211};
7212
7213class OptimizeNoneAttr : public InheritableAttr {
7214public:
7215 static OptimizeNoneAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7216 auto *A = new (Ctx) OptimizeNoneAttr(Loc, Ctx, 0);
7217 A->setImplicit(true);
7218 return A;
7219 }
7220
7221 OptimizeNoneAttr(SourceRange R, ASTContext &Ctx
7222 , unsigned SI
7223 )
7224 : InheritableAttr(attr::OptimizeNone, R, SI, false, false)
7225 {
7226 }
7227
7228 OptimizeNoneAttr *clone(ASTContext &C) const;
7229 void printPretty(raw_ostream &OS,
7230 const PrintingPolicy &Policy) const;
7231 const char *getSpelling() const;
7232
7233
7234 static bool classof(const Attr *A) { return A->getKind() == attr::OptimizeNone; }
7235};
7236
7237class OverloadableAttr : public Attr {
7238public:
7239 static OverloadableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7240 auto *A = new (Ctx) OverloadableAttr(Loc, Ctx, 0);
7241 A->setImplicit(true);
7242 return A;
7243 }
7244
7245 OverloadableAttr(SourceRange R, ASTContext &Ctx
7246 , unsigned SI
7247 )
7248 : Attr(attr::Overloadable, R, SI, false)
7249 {
7250 }
7251
7252 OverloadableAttr *clone(ASTContext &C) const;
7253 void printPretty(raw_ostream &OS,
7254 const PrintingPolicy &Policy) const;
7255 const char *getSpelling() const;
7256
7257
7258 static bool classof(const Attr *A) { return A->getKind() == attr::Overloadable; }
7259};
7260
7261class OverrideAttr : public InheritableAttr {
7262public:
7263 static OverrideAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7264 auto *A = new (Ctx) OverrideAttr(Loc, Ctx, 0);
7265 A->setImplicit(true);
7266 return A;
7267 }
7268
7269 OverrideAttr(SourceRange R, ASTContext &Ctx
7270 , unsigned SI
7271 )
7272 : InheritableAttr(attr::Override, R, SI, false, false)
7273 {
7274 }
7275
7276 OverrideAttr *clone(ASTContext &C) const;
7277 void printPretty(raw_ostream &OS,
7278 const PrintingPolicy &Policy) const;
7279 const char *getSpelling() const;
7280
7281
7282 static bool classof(const Attr *A) { return A->getKind() == attr::Override; }
7283};
7284
7285class OwnershipAttr : public InheritableAttr {
7286IdentifierInfo * module;
7287
7288 unsigned args_Size;
7289 ParamIdx *args_;
7290
7291public:
7292 enum Spelling {
7293 GNU_ownership_holds = 0,
7294 CXX11_clang_ownership_holds = 1,
7295 C2x_clang_ownership_holds = 2,
7296 GNU_ownership_returns = 3,
7297 CXX11_clang_ownership_returns = 4,
7298 C2x_clang_ownership_returns = 5,
7299 GNU_ownership_takes = 6,
7300 CXX11_clang_ownership_takes = 7,
7301 C2x_clang_ownership_takes = 8
7302 };
7303
7304 static OwnershipAttr *CreateImplicit(ASTContext &Ctx, Spelling S, IdentifierInfo * Module, ParamIdx *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
7305 auto *A = new (Ctx) OwnershipAttr(Loc, Ctx, Module, Args, ArgsSize, S);
7306 A->setImplicit(true);
7307 return A;
7308 }
7309
7310 OwnershipAttr(SourceRange R, ASTContext &Ctx
7311 , IdentifierInfo * Module
7312 , ParamIdx *Args, unsigned ArgsSize
7313 , unsigned SI
7314 )
7315 : InheritableAttr(attr::Ownership, R, SI, false, false)
7316 , module(Module)
7317 , args_Size(ArgsSize), args_(new (Ctx, 16) ParamIdx[args_Size])
7318 {
7319 std::copy(Args, Args + args_Size, args_);
7320 }
7321
7322 OwnershipAttr(SourceRange R, ASTContext &Ctx
7323 , IdentifierInfo * Module
7324 , unsigned SI
7325 )
7326 : InheritableAttr(attr::Ownership, R, SI, false, false)
7327 , module(Module)
7328 , args_Size(0), args_(nullptr)
7329 {
7330 }
7331
7332 OwnershipAttr *clone(ASTContext &C) const;
7333 void printPretty(raw_ostream &OS,
7334 const PrintingPolicy &Policy) const;
7335 const char *getSpelling() const;
7336 Spelling getSemanticSpelling() const {
7337 switch (SpellingListIndex) {
7338 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 7338)
;
7339 case 0: return GNU_ownership_holds;
7340 case 1: return CXX11_clang_ownership_holds;
7341 case 2: return C2x_clang_ownership_holds;
7342 case 3: return GNU_ownership_returns;
7343 case 4: return CXX11_clang_ownership_returns;
7344 case 5: return C2x_clang_ownership_returns;
7345 case 6: return GNU_ownership_takes;
7346 case 7: return CXX11_clang_ownership_takes;
7347 case 8: return C2x_clang_ownership_takes;
7348 }
7349 }
7350 bool isHolds() const { return SpellingListIndex == 0 ||
7351 SpellingListIndex == 1 ||
7352 SpellingListIndex == 2; }
7353 bool isReturns() const { return SpellingListIndex == 3 ||
7354 SpellingListIndex == 4 ||
7355 SpellingListIndex == 5; }
7356 bool isTakes() const { return SpellingListIndex == 6 ||
7357 SpellingListIndex == 7 ||
7358 SpellingListIndex == 8; }
7359 IdentifierInfo * getModule() const {
7360 return module;
7361 }
7362
7363 typedef ParamIdx* args_iterator;
7364 args_iterator args_begin() const { return args_; }
7365 args_iterator args_end() const { return args_ + args_Size; }
7366 unsigned args_size() const { return args_Size; }
7367 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
7368
7369
7370
7371 enum OwnershipKind { Holds, Returns, Takes };
7372 OwnershipKind getOwnKind() const {
7373 return isHolds() ? Holds :
7374 isTakes() ? Takes :
7375 Returns;
7376 }
7377
7378
7379 static bool classof(const Attr *A) { return A->getKind() == attr::Ownership; }
7380};
7381
7382class PackedAttr : public InheritableAttr {
7383public:
7384 static PackedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7385 auto *A = new (Ctx) PackedAttr(Loc, Ctx, 0);
9
'A' initialized to a null pointer value
7386 A->setImplicit(true);
10
Called C++ object pointer is null
7387 return A;
7388 }
7389
7390 PackedAttr(SourceRange R, ASTContext &Ctx
7391 , unsigned SI
7392 )
7393 : InheritableAttr(attr::Packed, R, SI, false, false)
7394 {
7395 }
7396
7397 PackedAttr *clone(ASTContext &C) const;
7398 void printPretty(raw_ostream &OS,
7399 const PrintingPolicy &Policy) const;
7400 const char *getSpelling() const;
7401
7402
7403 static bool classof(const Attr *A) { return A->getKind() == attr::Packed; }
7404};
7405
7406class ParamTypestateAttr : public InheritableAttr {
7407public:
7408 enum ConsumedState {
7409 Unknown,
7410 Consumed,
7411 Unconsumed
7412 };
7413private:
7414 ConsumedState paramState;
7415
7416public:
7417 static ParamTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState ParamState, SourceRange Loc = SourceRange()) {
7418 auto *A = new (Ctx) ParamTypestateAttr(Loc, Ctx, ParamState, 0);
7419 A->setImplicit(true);
7420 return A;
7421 }
7422
7423 ParamTypestateAttr(SourceRange R, ASTContext &Ctx
7424 , ConsumedState ParamState
7425 , unsigned SI
7426 )
7427 : InheritableAttr(attr::ParamTypestate, R, SI, false, false)
7428 , paramState(ParamState)
7429 {
7430 }
7431
7432 ParamTypestateAttr *clone(ASTContext &C) const;
7433 void printPretty(raw_ostream &OS,
7434 const PrintingPolicy &Policy) const;
7435 const char *getSpelling() const;
7436 ConsumedState getParamState() const {
7437 return paramState;
7438 }
7439
7440 static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
7441 Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
7442 .Case("unknown", ParamTypestateAttr::Unknown)
7443 .Case("consumed", ParamTypestateAttr::Consumed)
7444 .Case("unconsumed", ParamTypestateAttr::Unconsumed)
7445 .Default(Optional<ConsumedState>());
7446 if (R) {
7447 Out = *R;
7448 return true;
7449 }
7450 return false;
7451 }
7452
7453 static const char *ConvertConsumedStateToStr(ConsumedState Val) {
7454 switch(Val) {
7455 case ParamTypestateAttr::Unknown: return "unknown";
7456 case ParamTypestateAttr::Consumed: return "consumed";
7457 case ParamTypestateAttr::Unconsumed: return "unconsumed";
7458 }
7459 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 7459)
;
7460 }
7461
7462
7463 static bool classof(const Attr *A) { return A->getKind() == attr::ParamTypestate; }
7464};
7465
7466class PascalAttr : public InheritableAttr {
7467public:
7468 static PascalAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7469 auto *A = new (Ctx) PascalAttr(Loc, Ctx, 0);
7470 A->setImplicit(true);
7471 return A;
7472 }
7473
7474 PascalAttr(SourceRange R, ASTContext &Ctx
7475 , unsigned SI
7476 )
7477 : InheritableAttr(attr::Pascal, R, SI, false, false)
7478 {
7479 }
7480
7481 PascalAttr *clone(ASTContext &C) const;
7482 void printPretty(raw_ostream &OS,
7483 const PrintingPolicy &Policy) const;
7484 const char *getSpelling() const;
7485
7486
7487 static bool classof(const Attr *A) { return A->getKind() == attr::Pascal; }
7488};
7489
7490class PassObjectSizeAttr : public InheritableParamAttr {
7491int type;
7492
7493public:
7494 enum Spelling {
7495 GNU_pass_object_size = 0,
7496 CXX11_clang_pass_object_size = 1,
7497 C2x_clang_pass_object_size = 2,
7498 GNU_pass_dynamic_object_size = 3,
7499 CXX11_clang_pass_dynamic_object_size = 4,
7500 C2x_clang_pass_dynamic_object_size = 5
7501 };
7502
7503 static PassObjectSizeAttr *CreateImplicit(ASTContext &Ctx, Spelling S, int Type, SourceRange Loc = SourceRange()) {
7504 auto *A = new (Ctx) PassObjectSizeAttr(Loc, Ctx, Type, S);
7505 A->setImplicit(true);
7506 return A;
7507 }
7508
7509 PassObjectSizeAttr(SourceRange R, ASTContext &Ctx
7510 , int Type
7511 , unsigned SI
7512 )
7513 : InheritableParamAttr(attr::PassObjectSize, R, SI, false, false)
7514 , type(Type)
7515 {
7516 }
7517
7518 PassObjectSizeAttr *clone(ASTContext &C) const;
7519 void printPretty(raw_ostream &OS,
7520 const PrintingPolicy &Policy) const;
7521 const char *getSpelling() const;
7522 Spelling getSemanticSpelling() const {
7523 switch (SpellingListIndex) {
7524 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 7524)
;
7525 case 0: return GNU_pass_object_size;
7526 case 1: return CXX11_clang_pass_object_size;
7527 case 2: return C2x_clang_pass_object_size;
7528 case 3: return GNU_pass_dynamic_object_size;
7529 case 4: return CXX11_clang_pass_dynamic_object_size;
7530 case 5: return C2x_clang_pass_dynamic_object_size;
7531 }
7532 }
7533 bool isDynamic() const { return SpellingListIndex == 3 ||
7534 SpellingListIndex == 4 ||
7535 SpellingListIndex == 5; }
7536 int getType() const {
7537 return type;
7538 }
7539
7540
7541
7542 static bool classof(const Attr *A) { return A->getKind() == attr::PassObjectSize; }
7543};
7544
7545class PcsAttr : public InheritableAttr {
7546public:
7547 enum PCSType {
7548 AAPCS,
7549 AAPCS_VFP
7550 };
7551private:
7552 PCSType pCS;
7553
7554public:
7555 static PcsAttr *CreateImplicit(ASTContext &Ctx, PCSType PCS, SourceRange Loc = SourceRange()) {
7556 auto *A = new (Ctx) PcsAttr(Loc, Ctx, PCS, 0);
7557 A->setImplicit(true);
7558 return A;
7559 }
7560
7561 PcsAttr(SourceRange R, ASTContext &Ctx
7562 , PCSType PCS
7563 , unsigned SI
7564 )
7565 : InheritableAttr(attr::Pcs, R, SI, false, false)
7566 , pCS(PCS)
7567 {
7568 }
7569
7570 PcsAttr *clone(ASTContext &C) const;
7571 void printPretty(raw_ostream &OS,
7572 const PrintingPolicy &Policy) const;
7573 const char *getSpelling() const;
7574 PCSType getPCS() const {
7575 return pCS;
7576 }
7577
7578 static bool ConvertStrToPCSType(StringRef Val, PCSType &Out) {
7579 Optional<PCSType> R = llvm::StringSwitch<Optional<PCSType>>(Val)
7580 .Case("aapcs", PcsAttr::AAPCS)
7581 .Case("aapcs-vfp", PcsAttr::AAPCS_VFP)
7582 .Default(Optional<PCSType>());
7583 if (R) {
7584 Out = *R;
7585 return true;
7586 }
7587 return false;
7588 }
7589
7590 static const char *ConvertPCSTypeToStr(PCSType Val) {
7591 switch(Val) {
7592 case PcsAttr::AAPCS: return "aapcs";
7593 case PcsAttr::AAPCS_VFP: return "aapcs-vfp";
7594 }
7595 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 7595)
;
7596 }
7597
7598
7599 static bool classof(const Attr *A) { return A->getKind() == attr::Pcs; }
7600};
7601
7602class PragmaClangBSSSectionAttr : public InheritableAttr {
7603unsigned nameLength;
7604char *name;
7605
7606public:
7607 static PragmaClangBSSSectionAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Loc = SourceRange()) {
7608 auto *A = new (Ctx) PragmaClangBSSSectionAttr(Loc, Ctx, Name, 0);
7609 A->setImplicit(true);
7610 return A;
7611 }
7612
7613 PragmaClangBSSSectionAttr(SourceRange R, ASTContext &Ctx
7614 , llvm::StringRef Name
7615 , unsigned SI
7616 )
7617 : InheritableAttr(attr::PragmaClangBSSSection, R, SI, false, false)
7618 , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
7619 {
7620 if (!Name.empty())
7621 std::memcpy(name, Name.data(), nameLength);
7622 }
7623
7624 PragmaClangBSSSectionAttr *clone(ASTContext &C) const;
7625 void printPretty(raw_ostream &OS,
7626 const PrintingPolicy &Policy) const;
7627 const char *getSpelling() const;
7628 llvm::StringRef getName() const {
7629 return llvm::StringRef(name, nameLength);
7630 }
7631 unsigned getNameLength() const {
7632 return nameLength;
7633 }
7634 void setName(ASTContext &C, llvm::StringRef S) {
7635 nameLength = S.size();
7636 this->name = new (C, 1) char [nameLength];
7637 if (!S.empty())
7638 std::memcpy(this->name, S.data(), nameLength);
7639 }
7640
7641
7642
7643 static bool classof(const Attr *A) { return A->getKind() == attr::PragmaClangBSSSection; }
7644};
7645
7646class PragmaClangDataSectionAttr : public InheritableAttr {
7647unsigned nameLength;
7648char *name;
7649
7650public:
7651 static PragmaClangDataSectionAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Loc = SourceRange()) {
7652 auto *A = new (Ctx) PragmaClangDataSectionAttr(Loc, Ctx, Name, 0);
7653 A->setImplicit(true);
7654 return A;
7655 }
7656
7657 PragmaClangDataSectionAttr(SourceRange R, ASTContext &Ctx
7658 , llvm::StringRef Name
7659 , unsigned SI
7660 )
7661 : InheritableAttr(attr::PragmaClangDataSection, R, SI, false, false)
7662 , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
7663 {
7664 if (!Name.empty())
7665 std::memcpy(name, Name.data(), nameLength);
7666 }
7667
7668 PragmaClangDataSectionAttr *clone(ASTContext &C) const;
7669 void printPretty(raw_ostream &OS,
7670 const PrintingPolicy &Policy) const;
7671 const char *getSpelling() const;
7672 llvm::StringRef getName() const {
7673 return llvm::StringRef(name, nameLength);
7674 }
7675 unsigned getNameLength() const {
7676 return nameLength;
7677 }
7678 void setName(ASTContext &C, llvm::StringRef S) {
7679 nameLength = S.size();
7680 this->name = new (C, 1) char [nameLength];
7681 if (!S.empty())
7682 std::memcpy(this->name, S.data(), nameLength);
7683 }
7684
7685
7686
7687 static bool classof(const Attr *A) { return A->getKind() == attr::PragmaClangDataSection; }
7688};
7689
7690class PragmaClangRodataSectionAttr : public InheritableAttr {
7691unsigned nameLength;
7692char *name;
7693
7694public:
7695 static PragmaClangRodataSectionAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Loc = SourceRange()) {
7696 auto *A = new (Ctx) PragmaClangRodataSectionAttr(Loc, Ctx, Name, 0);
7697 A->setImplicit(true);
7698 return A;
7699 }
7700
7701 PragmaClangRodataSectionAttr(SourceRange R, ASTContext &Ctx
7702 , llvm::StringRef Name
7703 , unsigned SI
7704 )
7705 : InheritableAttr(attr::PragmaClangRodataSection, R, SI, false, false)
7706 , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
7707 {
7708 if (!Name.empty())
7709 std::memcpy(name, Name.data(), nameLength);
7710 }
7711
7712 PragmaClangRodataSectionAttr *clone(ASTContext &C) const;
7713 void printPretty(raw_ostream &OS,
7714 const PrintingPolicy &Policy) const;
7715 const char *getSpelling() const;
7716 llvm::StringRef getName() const {
7717 return llvm::StringRef(name, nameLength);
7718 }
7719 unsigned getNameLength() const {
7720 return nameLength;
7721 }
7722 void setName(ASTContext &C, llvm::StringRef S) {
7723 nameLength = S.size();
7724 this->name = new (C, 1) char [nameLength];
7725 if (!S.empty())
7726 std::memcpy(this->name, S.data(), nameLength);
7727 }
7728
7729
7730
7731 static bool classof(const Attr *A) { return A->getKind() == attr::PragmaClangRodataSection; }
7732};
7733
7734class PragmaClangTextSectionAttr : public InheritableAttr {
7735unsigned nameLength;
7736char *name;
7737
7738public:
7739 static PragmaClangTextSectionAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Name, SourceRange Loc = SourceRange()) {
7740 auto *A = new (Ctx) PragmaClangTextSectionAttr(Loc, Ctx, Name, 0);
7741 A->setImplicit(true);
7742 return A;
7743 }
7744
7745 PragmaClangTextSectionAttr(SourceRange R, ASTContext &Ctx
7746 , llvm::StringRef Name
7747 , unsigned SI
7748 )
7749 : InheritableAttr(attr::PragmaClangTextSection, R, SI, false, false)
7750 , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
7751 {
7752 if (!Name.empty())
7753 std::memcpy(name, Name.data(), nameLength);
7754 }
7755
7756 PragmaClangTextSectionAttr *clone(ASTContext &C) const;
7757 void printPretty(raw_ostream &OS,
7758 const PrintingPolicy &Policy) const;
7759 const char *getSpelling() const;
7760 llvm::StringRef getName() const {
7761 return llvm::StringRef(name, nameLength);
7762 }
7763 unsigned getNameLength() const {
7764 return nameLength;
7765 }
7766 void setName(ASTContext &C, llvm::StringRef S) {
7767 nameLength = S.size();
7768 this->name = new (C, 1) char [nameLength];
7769 if (!S.empty())
7770 std::memcpy(this->name, S.data(), nameLength);
7771 }
7772
7773
7774
7775 static bool classof(const Attr *A) { return A->getKind() == attr::PragmaClangTextSection; }
7776};
7777
7778class PreserveAllAttr : public InheritableAttr {
7779public:
7780 static PreserveAllAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7781 auto *A = new (Ctx) PreserveAllAttr(Loc, Ctx, 0);
7782 A->setImplicit(true);
7783 return A;
7784 }
7785
7786 PreserveAllAttr(SourceRange R, ASTContext &Ctx
7787 , unsigned SI
7788 )
7789 : InheritableAttr(attr::PreserveAll, R, SI, false, false)
7790 {
7791 }
7792
7793 PreserveAllAttr *clone(ASTContext &C) const;
7794 void printPretty(raw_ostream &OS,
7795 const PrintingPolicy &Policy) const;
7796 const char *getSpelling() const;
7797
7798
7799 static bool classof(const Attr *A) { return A->getKind() == attr::PreserveAll; }
7800};
7801
7802class PreserveMostAttr : public InheritableAttr {
7803public:
7804 static PreserveMostAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7805 auto *A = new (Ctx) PreserveMostAttr(Loc, Ctx, 0);
7806 A->setImplicit(true);
7807 return A;
7808 }
7809
7810 PreserveMostAttr(SourceRange R, ASTContext &Ctx
7811 , unsigned SI
7812 )
7813 : InheritableAttr(attr::PreserveMost, R, SI, false, false)
7814 {
7815 }
7816
7817 PreserveMostAttr *clone(ASTContext &C) const;
7818 void printPretty(raw_ostream &OS,
7819 const PrintingPolicy &Policy) const;
7820 const char *getSpelling() const;
7821
7822
7823 static bool classof(const Attr *A) { return A->getKind() == attr::PreserveMost; }
7824};
7825
7826class PtGuardedByAttr : public InheritableAttr {
7827Expr * arg;
7828
7829public:
7830 static PtGuardedByAttr *CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Loc = SourceRange()) {
7831 auto *A = new (Ctx) PtGuardedByAttr(Loc, Ctx, Arg, 0);
7832 A->setImplicit(true);
7833 return A;
7834 }
7835
7836 PtGuardedByAttr(SourceRange R, ASTContext &Ctx
7837 , Expr * Arg
7838 , unsigned SI
7839 )
7840 : InheritableAttr(attr::PtGuardedBy, R, SI, true, true)
7841 , arg(Arg)
7842 {
7843 }
7844
7845 PtGuardedByAttr *clone(ASTContext &C) const;
7846 void printPretty(raw_ostream &OS,
7847 const PrintingPolicy &Policy) const;
7848 const char *getSpelling() const;
7849 Expr * getArg() const {
7850 return arg;
7851 }
7852
7853
7854
7855 static bool classof(const Attr *A) { return A->getKind() == attr::PtGuardedBy; }
7856};
7857
7858class PtGuardedVarAttr : public InheritableAttr {
7859public:
7860 static PtGuardedVarAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7861 auto *A = new (Ctx) PtGuardedVarAttr(Loc, Ctx, 0);
7862 A->setImplicit(true);
7863 return A;
7864 }
7865
7866 PtGuardedVarAttr(SourceRange R, ASTContext &Ctx
7867 , unsigned SI
7868 )
7869 : InheritableAttr(attr::PtGuardedVar, R, SI, false, false)
7870 {
7871 }
7872
7873 PtGuardedVarAttr *clone(ASTContext &C) const;
7874 void printPretty(raw_ostream &OS,
7875 const PrintingPolicy &Policy) const;
7876 const char *getSpelling() const;
7877
7878
7879 static bool classof(const Attr *A) { return A->getKind() == attr::PtGuardedVar; }
7880};
7881
7882class Ptr32Attr : public TypeAttr {
7883public:
7884 static Ptr32Attr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7885 auto *A = new (Ctx) Ptr32Attr(Loc, Ctx, 0);
7886 A->setImplicit(true);
7887 return A;
7888 }
7889
7890 Ptr32Attr(SourceRange R, ASTContext &Ctx
7891 , unsigned SI
7892 )
7893 : TypeAttr(attr::Ptr32, R, SI, false)
7894 {
7895 }
7896
7897 Ptr32Attr *clone(ASTContext &C) const;
7898 void printPretty(raw_ostream &OS,
7899 const PrintingPolicy &Policy) const;
7900 const char *getSpelling() const;
7901
7902
7903 static bool classof(const Attr *A) { return A->getKind() == attr::Ptr32; }
7904};
7905
7906class Ptr64Attr : public TypeAttr {
7907public:
7908 static Ptr64Attr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7909 auto *A = new (Ctx) Ptr64Attr(Loc, Ctx, 0);
7910 A->setImplicit(true);
7911 return A;
7912 }
7913
7914 Ptr64Attr(SourceRange R, ASTContext &Ctx
7915 , unsigned SI
7916 )
7917 : TypeAttr(attr::Ptr64, R, SI, false)
7918 {
7919 }
7920
7921 Ptr64Attr *clone(ASTContext &C) const;
7922 void printPretty(raw_ostream &OS,
7923 const PrintingPolicy &Policy) const;
7924 const char *getSpelling() const;
7925
7926
7927 static bool classof(const Attr *A) { return A->getKind() == attr::Ptr64; }
7928};
7929
7930class PureAttr : public InheritableAttr {
7931public:
7932 static PureAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
7933 auto *A = new (Ctx) PureAttr(Loc, Ctx, 0);
7934 A->setImplicit(true);
7935 return A;
7936 }
7937
7938 PureAttr(SourceRange R, ASTContext &Ctx
7939 , unsigned SI
7940 )
7941 : InheritableAttr(attr::Pure, R, SI, false, false)
7942 {
7943 }
7944
7945 PureAttr *clone(ASTContext &C) const;
7946 void printPretty(raw_ostream &OS,
7947 const PrintingPolicy &Policy) const;
7948 const char *getSpelling() const;
7949
7950
7951 static bool classof(const Attr *A) { return A->getKind() == attr::Pure; }
7952};
7953
7954class RISCVInterruptAttr : public InheritableAttr {
7955public:
7956 enum InterruptType {
7957 user,
7958 supervisor,
7959 machine
7960 };
7961private:
7962 InterruptType interrupt;
7963
7964public:
7965 static RISCVInterruptAttr *CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, SourceRange Loc = SourceRange()) {
7966 auto *A = new (Ctx) RISCVInterruptAttr(Loc, Ctx, Interrupt, 0);
7967 A->setImplicit(true);
7968 return A;
7969 }
7970
7971 RISCVInterruptAttr(SourceRange R, ASTContext &Ctx
7972 , InterruptType Interrupt
7973 , unsigned SI
7974 )
7975 : InheritableAttr(attr::RISCVInterrupt, R, SI, false, false)
7976 , interrupt(Interrupt)
7977 {
7978 }
7979
7980 RISCVInterruptAttr(SourceRange R, ASTContext &Ctx
7981 , unsigned SI
7982 )
7983 : InheritableAttr(attr::RISCVInterrupt, R, SI, false, false)
7984 , interrupt(InterruptType(0))
7985 {
7986 }
7987
7988 RISCVInterruptAttr *clone(ASTContext &C) const;
7989 void printPretty(raw_ostream &OS,
7990 const PrintingPolicy &Policy) const;
7991 const char *getSpelling() const;
7992 InterruptType getInterrupt() const {
7993 return interrupt;
7994 }
7995
7996 static bool ConvertStrToInterruptType(StringRef Val, InterruptType &Out) {
7997 Optional<InterruptType> R = llvm::StringSwitch<Optional<InterruptType>>(Val)
7998 .Case("user", RISCVInterruptAttr::user)
7999 .Case("supervisor", RISCVInterruptAttr::supervisor)
8000 .Case("machine", RISCVInterruptAttr::machine)
8001 .Default(Optional<InterruptType>());
8002 if (R) {
8003 Out = *R;
8004 return true;
8005 }
8006 return false;
8007 }
8008
8009 static const char *ConvertInterruptTypeToStr(InterruptType Val) {
8010 switch(Val) {
8011 case RISCVInterruptAttr::user: return "user";
8012 case RISCVInterruptAttr::supervisor: return "supervisor";
8013 case RISCVInterruptAttr::machine: return "machine";
8014 }
8015 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 8015)
;
8016 }
8017
8018
8019 static bool classof(const Attr *A) { return A->getKind() == attr::RISCVInterrupt; }
8020};
8021
8022class RegCallAttr : public InheritableAttr {
8023public:
8024 static RegCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8025 auto *A = new (Ctx) RegCallAttr(Loc, Ctx, 0);
8026 A->setImplicit(true);
8027 return A;
8028 }
8029
8030 RegCallAttr(SourceRange R, ASTContext &Ctx
8031 , unsigned SI
8032 )
8033 : InheritableAttr(attr::RegCall, R, SI, false, false)
8034 {
8035 }
8036
8037 RegCallAttr *clone(ASTContext &C) const;
8038 void printPretty(raw_ostream &OS,
8039 const PrintingPolicy &Policy) const;
8040 const char *getSpelling() const;
8041
8042
8043 static bool classof(const Attr *A) { return A->getKind() == attr::RegCall; }
8044};
8045
8046class ReinitializesAttr : public InheritableAttr {
8047public:
8048 static ReinitializesAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8049 auto *A = new (Ctx) ReinitializesAttr(Loc, Ctx, 0);
8050 A->setImplicit(true);
8051 return A;
8052 }
8053
8054 ReinitializesAttr(SourceRange R, ASTContext &Ctx
8055 , unsigned SI
8056 )
8057 : InheritableAttr(attr::Reinitializes, R, SI, false, false)
8058 {
8059 }
8060
8061 ReinitializesAttr *clone(ASTContext &C) const;
8062 void printPretty(raw_ostream &OS,
8063 const PrintingPolicy &Policy) const;
8064 const char *getSpelling() const;
8065
8066
8067 static bool classof(const Attr *A) { return A->getKind() == attr::Reinitializes; }
8068};
8069
8070class ReleaseCapabilityAttr : public InheritableAttr {
8071 unsigned args_Size;
8072 Expr * *args_;
8073
8074public:
8075 enum Spelling {
8076 GNU_release_capability = 0,
8077 CXX11_clang_release_capability = 1,
8078 GNU_release_shared_capability = 2,
8079 CXX11_clang_release_shared_capability = 3,
8080 GNU_release_generic_capability = 4,
8081 CXX11_clang_release_generic_capability = 5,
8082 GNU_unlock_function = 6,
8083 CXX11_clang_unlock_function = 7
8084 };
8085
8086 static ReleaseCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
8087 auto *A = new (Ctx) ReleaseCapabilityAttr(Loc, Ctx, Args, ArgsSize, S);
8088 A->setImplicit(true);
8089 return A;
8090 }
8091
8092 ReleaseCapabilityAttr(SourceRange R, ASTContext &Ctx
8093 , Expr * *Args, unsigned ArgsSize
8094 , unsigned SI
8095 )
8096 : InheritableAttr(attr::ReleaseCapability, R, SI, true, true)
8097 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
8098 {
8099 std::copy(Args, Args + args_Size, args_);
8100 }
8101
8102 ReleaseCapabilityAttr(SourceRange R, ASTContext &Ctx
8103 , unsigned SI
8104 )
8105 : InheritableAttr(attr::ReleaseCapability, R, SI, true, true)
8106 , args_Size(0), args_(nullptr)
8107 {
8108 }
8109
8110 ReleaseCapabilityAttr *clone(ASTContext &C) const;
8111 void printPretty(raw_ostream &OS,
8112 const PrintingPolicy &Policy) const;
8113 const char *getSpelling() const;
8114 Spelling getSemanticSpelling() const {
8115 switch (SpellingListIndex) {
8116 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 8116)
;
8117 case 0: return GNU_release_capability;
8118 case 1: return CXX11_clang_release_capability;
8119 case 2: return GNU_release_shared_capability;
8120 case 3: return CXX11_clang_release_shared_capability;
8121 case 4: return GNU_release_generic_capability;
8122 case 5: return CXX11_clang_release_generic_capability;
8123 case 6: return GNU_unlock_function;
8124 case 7: return CXX11_clang_unlock_function;
8125 }
8126 }
8127 bool isShared() const { return SpellingListIndex == 2 ||
8128 SpellingListIndex == 3; }
8129 bool isGeneric() const { return SpellingListIndex == 4 ||
8130 SpellingListIndex == 5 ||
8131 SpellingListIndex == 6 ||
8132 SpellingListIndex == 7; }
8133 typedef Expr ** args_iterator;
8134 args_iterator args_begin() const { return args_; }
8135 args_iterator args_end() const { return args_ + args_Size; }
8136 unsigned args_size() const { return args_Size; }
8137 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
8138
8139
8140
8141
8142 static bool classof(const Attr *A) { return A->getKind() == attr::ReleaseCapability; }
8143};
8144
8145class RenderScriptKernelAttr : public Attr {
8146public:
8147 static RenderScriptKernelAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8148 auto *A = new (Ctx) RenderScriptKernelAttr(Loc, Ctx, 0);
8149 A->setImplicit(true);
8150 return A;
8151 }
8152
8153 RenderScriptKernelAttr(SourceRange R, ASTContext &Ctx
8154 , unsigned SI
8155 )
8156 : Attr(attr::RenderScriptKernel, R, SI, false)
8157 {
8158 }
8159
8160 RenderScriptKernelAttr *clone(ASTContext &C) const;
8161 void printPretty(raw_ostream &OS,
8162 const PrintingPolicy &Policy) const;
8163 const char *getSpelling() const;
8164
8165
8166 static bool classof(const Attr *A) { return A->getKind() == attr::RenderScriptKernel; }
8167};
8168
8169class ReqdWorkGroupSizeAttr : public InheritableAttr {
8170unsigned xDim;
8171
8172unsigned yDim;
8173
8174unsigned zDim;
8175
8176public:
8177 static ReqdWorkGroupSizeAttr *CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Loc = SourceRange()) {
8178 auto *A = new (Ctx) ReqdWorkGroupSizeAttr(Loc, Ctx, XDim, YDim, ZDim, 0);
8179 A->setImplicit(true);
8180 return A;
8181 }
8182
8183 ReqdWorkGroupSizeAttr(SourceRange R, ASTContext &Ctx
8184 , unsigned XDim
8185 , unsigned YDim
8186 , unsigned ZDim
8187 , unsigned SI
8188 )
8189 : InheritableAttr(attr::ReqdWorkGroupSize, R, SI, false, false)
8190 , xDim(XDim)
8191 , yDim(YDim)
8192 , zDim(ZDim)
8193 {
8194 }
8195
8196 ReqdWorkGroupSizeAttr *clone(ASTContext &C) const;
8197 void printPretty(raw_ostream &OS,
8198 const PrintingPolicy &Policy) const;
8199 const char *getSpelling() const;
8200 unsigned getXDim() const {
8201 return xDim;
8202 }
8203
8204 unsigned getYDim() const {
8205 return yDim;
8206 }
8207
8208 unsigned getZDim() const {
8209 return zDim;
8210 }
8211
8212
8213
8214 static bool classof(const Attr *A) { return A->getKind() == attr::ReqdWorkGroupSize; }
8215};
8216
8217class RequireConstantInitAttr : public InheritableAttr {
8218public:
8219 static RequireConstantInitAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8220 auto *A = new (Ctx) RequireConstantInitAttr(Loc, Ctx, 0);
8221 A->setImplicit(true);
8222 return A;
8223 }
8224
8225 RequireConstantInitAttr(SourceRange R, ASTContext &Ctx
8226 , unsigned SI
8227 )
8228 : InheritableAttr(attr::RequireConstantInit, R, SI, false, false)
8229 {
8230 }
8231
8232 RequireConstantInitAttr *clone(ASTContext &C) const;
8233 void printPretty(raw_ostream &OS,
8234 const PrintingPolicy &Policy) const;
8235 const char *getSpelling() const;
8236
8237
8238 static bool classof(const Attr *A) { return A->getKind() == attr::RequireConstantInit; }
8239};
8240
8241class RequiresCapabilityAttr : public InheritableAttr {
8242 unsigned args_Size;
8243 Expr * *args_;
8244
8245public:
8246 enum Spelling {
8247 GNU_requires_capability = 0,
8248 CXX11_clang_requires_capability = 1,
8249 GNU_exclusive_locks_required = 2,
8250 CXX11_clang_exclusive_locks_required = 3,
8251 GNU_requires_shared_capability = 4,
8252 CXX11_clang_requires_shared_capability = 5,
8253 GNU_shared_locks_required = 6,
8254 CXX11_clang_shared_locks_required = 7
8255 };
8256
8257 static RequiresCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
8258 auto *A = new (Ctx) RequiresCapabilityAttr(Loc, Ctx, Args, ArgsSize, S);
8259 A->setImplicit(true);
8260 return A;
8261 }
8262
8263 RequiresCapabilityAttr(SourceRange R, ASTContext &Ctx
8264 , Expr * *Args, unsigned ArgsSize
8265 , unsigned SI
8266 )
8267 : InheritableAttr(attr::RequiresCapability, R, SI, true, true)
8268 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
8269 {
8270 std::copy(Args, Args + args_Size, args_);
8271 }
8272
8273 RequiresCapabilityAttr(SourceRange R, ASTContext &Ctx
8274 , unsigned SI
8275 )
8276 : InheritableAttr(attr::RequiresCapability, R, SI, true, true)
8277 , args_Size(0), args_(nullptr)
8278 {
8279 }
8280
8281 RequiresCapabilityAttr *clone(ASTContext &C) const;
8282 void printPretty(raw_ostream &OS,
8283 const PrintingPolicy &Policy) const;
8284 const char *getSpelling() const;
8285 Spelling getSemanticSpelling() const {
8286 switch (SpellingListIndex) {
8287 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 8287)
;
8288 case 0: return GNU_requires_capability;
8289 case 1: return CXX11_clang_requires_capability;
8290 case 2: return GNU_exclusive_locks_required;
8291 case 3: return CXX11_clang_exclusive_locks_required;
8292 case 4: return GNU_requires_shared_capability;
8293 case 5: return CXX11_clang_requires_shared_capability;
8294 case 6: return GNU_shared_locks_required;
8295 case 7: return CXX11_clang_shared_locks_required;
8296 }
8297 }
8298 bool isShared() const { return SpellingListIndex == 4 ||
8299 SpellingListIndex == 5 ||
8300 SpellingListIndex == 6 ||
8301 SpellingListIndex == 7; }
8302 typedef Expr ** args_iterator;
8303 args_iterator args_begin() const { return args_; }
8304 args_iterator args_end() const { return args_ + args_Size; }
8305 unsigned args_size() const { return args_Size; }
8306 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
8307
8308
8309
8310
8311 static bool classof(const Attr *A) { return A->getKind() == attr::RequiresCapability; }
8312};
8313
8314class RestrictAttr : public InheritableAttr {
8315public:
8316 enum Spelling {
8317 Declspec_restrict = 0,
8318 GNU_malloc = 1,
8319 CXX11_gnu_malloc = 2
8320 };
8321
8322 static RestrictAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
8323 auto *A = new (Ctx) RestrictAttr(Loc, Ctx, S);
8324 A->setImplicit(true);
8325 return A;
8326 }
8327
8328 RestrictAttr(SourceRange R, ASTContext &Ctx
8329 , unsigned SI
8330 )
8331 : InheritableAttr(attr::Restrict, R, SI, false, false)
8332 {
8333 }
8334
8335 RestrictAttr *clone(ASTContext &C) const;
8336 void printPretty(raw_ostream &OS,
8337 const PrintingPolicy &Policy) const;
8338 const char *getSpelling() const;
8339 Spelling getSemanticSpelling() const {
8340 switch (SpellingListIndex) {
8341 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 8341)
;
8342 case 0: return Declspec_restrict;
8343 case 1: return GNU_malloc;
8344 case 2: return CXX11_gnu_malloc;
8345 }
8346 }
8347
8348
8349 static bool classof(const Attr *A) { return A->getKind() == attr::Restrict; }
8350};
8351
8352class ReturnTypestateAttr : public InheritableAttr {
8353public:
8354 enum ConsumedState {
8355 Unknown,
8356 Consumed,
8357 Unconsumed
8358 };
8359private:
8360 ConsumedState state;
8361
8362public:
8363 static ReturnTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState State, SourceRange Loc = SourceRange()) {
8364 auto *A = new (Ctx) ReturnTypestateAttr(Loc, Ctx, State, 0);
8365 A->setImplicit(true);
8366 return A;
8367 }
8368
8369 ReturnTypestateAttr(SourceRange R, ASTContext &Ctx
8370 , ConsumedState State
8371 , unsigned SI
8372 )
8373 : InheritableAttr(attr::ReturnTypestate, R, SI, false, false)
8374 , state(State)
8375 {
8376 }
8377
8378 ReturnTypestateAttr *clone(ASTContext &C) const;
8379 void printPretty(raw_ostream &OS,
8380 const PrintingPolicy &Policy) const;
8381 const char *getSpelling() const;
8382 ConsumedState getState() const {
8383 return state;
8384 }
8385
8386 static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
8387 Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
8388 .Case("unknown", ReturnTypestateAttr::Unknown)
8389 .Case("consumed", ReturnTypestateAttr::Consumed)
8390 .Case("unconsumed", ReturnTypestateAttr::Unconsumed)
8391 .Default(Optional<ConsumedState>());
8392 if (R) {
8393 Out = *R;
8394 return true;
8395 }
8396 return false;
8397 }
8398
8399 static const char *ConvertConsumedStateToStr(ConsumedState Val) {
8400 switch(Val) {
8401 case ReturnTypestateAttr::Unknown: return "unknown";
8402 case ReturnTypestateAttr::Consumed: return "consumed";
8403 case ReturnTypestateAttr::Unconsumed: return "unconsumed";
8404 }
8405 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 8405)
;
8406 }
8407
8408
8409 static bool classof(const Attr *A) { return A->getKind() == attr::ReturnTypestate; }
8410};
8411
8412class ReturnsNonNullAttr : public InheritableAttr {
8413public:
8414 static ReturnsNonNullAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8415 auto *A = new (Ctx) ReturnsNonNullAttr(Loc, Ctx, 0);
8416 A->setImplicit(true);
8417 return A;
8418 }
8419
8420 ReturnsNonNullAttr(SourceRange R, ASTContext &Ctx
8421 , unsigned SI
8422 )
8423 : InheritableAttr(attr::ReturnsNonNull, R, SI, false, false)
8424 {
8425 }
8426
8427 ReturnsNonNullAttr *clone(ASTContext &C) const;
8428 void printPretty(raw_ostream &OS,
8429 const PrintingPolicy &Policy) const;
8430 const char *getSpelling() const;
8431
8432
8433 static bool classof(const Attr *A) { return A->getKind() == attr::ReturnsNonNull; }
8434};
8435
8436class ReturnsTwiceAttr : public InheritableAttr {
8437public:
8438 static ReturnsTwiceAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8439 auto *A = new (Ctx) ReturnsTwiceAttr(Loc, Ctx, 0);
8440 A->setImplicit(true);
8441 return A;
8442 }
8443
8444 ReturnsTwiceAttr(SourceRange R, ASTContext &Ctx
8445 , unsigned SI
8446 )
8447 : InheritableAttr(attr::ReturnsTwice, R, SI, false, false)
8448 {
8449 }
8450
8451 ReturnsTwiceAttr *clone(ASTContext &C) const;
8452 void printPretty(raw_ostream &OS,
8453 const PrintingPolicy &Policy) const;
8454 const char *getSpelling() const;
8455
8456
8457 static bool classof(const Attr *A) { return A->getKind() == attr::ReturnsTwice; }
8458};
8459
8460class SPtrAttr : public TypeAttr {
8461public:
8462 static SPtrAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8463 auto *A = new (Ctx) SPtrAttr(Loc, Ctx, 0);
8464 A->setImplicit(true);
8465 return A;
8466 }
8467
8468 SPtrAttr(SourceRange R, ASTContext &Ctx
8469 , unsigned SI
8470 )
8471 : TypeAttr(attr::SPtr, R, SI, false)
8472 {
8473 }
8474
8475 SPtrAttr *clone(ASTContext &C) const;
8476 void printPretty(raw_ostream &OS,
8477 const PrintingPolicy &Policy) const;
8478 const char *getSpelling() const;
8479
8480
8481 static bool classof(const Attr *A) { return A->getKind() == attr::SPtr; }
8482};
8483
8484class ScopedLockableAttr : public InheritableAttr {
8485public:
8486 static ScopedLockableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8487 auto *A = new (Ctx) ScopedLockableAttr(Loc, Ctx, 0);
8488 A->setImplicit(true);
8489 return A;
8490 }
8491
8492 ScopedLockableAttr(SourceRange R, ASTContext &Ctx
8493 , unsigned SI
8494 )
8495 : InheritableAttr(attr::ScopedLockable, R, SI, false, false)
8496 {
8497 }
8498
8499 ScopedLockableAttr *clone(ASTContext &C) const;
8500 void printPretty(raw_ostream &OS,
8501 const PrintingPolicy &Policy) const;
8502 const char *getSpelling() const;
8503
8504
8505 static bool classof(const Attr *A) { return A->getKind() == attr::ScopedLockable; }
8506};
8507
8508class SectionAttr : public InheritableAttr {
8509unsigned nameLength;
8510char *name;
8511
8512public:
8513 enum Spelling {
8514 GNU_section = 0,
8515 CXX11_gnu_section = 1,
8516 Declspec_allocate = 2
8517 };
8518
8519 static SectionAttr *CreateImplicit(ASTContext &Ctx, Spelling S, llvm::StringRef Name, SourceRange Loc = SourceRange()) {
8520 auto *A = new (Ctx) SectionAttr(Loc, Ctx, Name, S);
8521 A->setImplicit(true);
8522 return A;
8523 }
8524
8525 SectionAttr(SourceRange R, ASTContext &Ctx
8526 , llvm::StringRef Name
8527 , unsigned SI
8528 )
8529 : InheritableAttr(attr::Section, R, SI, false, false)
8530 , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
8531 {
8532 if (!Name.empty())
8533 std::memcpy(name, Name.data(), nameLength);
8534 }
8535
8536 SectionAttr *clone(ASTContext &C) const;
8537 void printPretty(raw_ostream &OS,
8538 const PrintingPolicy &Policy) const;
8539 const char *getSpelling() const;
8540 Spelling getSemanticSpelling() const {
8541 switch (SpellingListIndex) {
8542 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 8542)
;
8543 case 0: return GNU_section;
8544 case 1: return CXX11_gnu_section;
8545 case 2: return Declspec_allocate;
8546 }
8547 }
8548 llvm::StringRef getName() const {
8549 return llvm::StringRef(name, nameLength);
8550 }
8551 unsigned getNameLength() const {
8552 return nameLength;
8553 }
8554 void setName(ASTContext &C, llvm::StringRef S) {
8555 nameLength = S.size();
8556 this->name = new (C, 1) char [nameLength];
8557 if (!S.empty())
8558 std::memcpy(this->name, S.data(), nameLength);
8559 }
8560
8561
8562
8563 static bool classof(const Attr *A) { return A->getKind() == attr::Section; }
8564};
8565
8566class SelectAnyAttr : public InheritableAttr {
8567public:
8568 static SelectAnyAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8569 auto *A = new (Ctx) SelectAnyAttr(Loc, Ctx, 0);
8570 A->setImplicit(true);
8571 return A;
8572 }
8573
8574 SelectAnyAttr(SourceRange R, ASTContext &Ctx
8575 , unsigned SI
8576 )
8577 : InheritableAttr(attr::SelectAny, R, SI, false, false)
8578 {
8579 }
8580
8581 SelectAnyAttr *clone(ASTContext &C) const;
8582 void printPretty(raw_ostream &OS,
8583 const PrintingPolicy &Policy) const;
8584 const char *getSpelling() const;
8585
8586
8587 static bool classof(const Attr *A) { return A->getKind() == attr::SelectAny; }
8588};
8589
8590class SentinelAttr : public InheritableAttr {
8591int sentinel;
8592
8593int nullPos;
8594
8595public:
8596 static SentinelAttr *CreateImplicit(ASTContext &Ctx, int Sentinel, int NullPos, SourceRange Loc = SourceRange()) {
8597 auto *A = new (Ctx) SentinelAttr(Loc, Ctx, Sentinel, NullPos, 0);
8598 A->setImplicit(true);
8599 return A;
8600 }
8601
8602 SentinelAttr(SourceRange R, ASTContext &Ctx
8603 , int Sentinel
8604 , int NullPos
8605 , unsigned SI
8606 )
8607 : InheritableAttr(attr::Sentinel, R, SI, false, false)
8608 , sentinel(Sentinel)
8609 , nullPos(NullPos)
8610 {
8611 }
8612
8613 SentinelAttr(SourceRange R, ASTContext &Ctx
8614 , unsigned SI
8615 )
8616 : InheritableAttr(attr::Sentinel, R, SI, false, false)
8617 , sentinel()
8618 , nullPos()
8619 {
8620 }
8621
8622 SentinelAttr *clone(ASTContext &C) const;
8623 void printPretty(raw_ostream &OS,
8624 const PrintingPolicy &Policy) const;
8625 const char *getSpelling() const;
8626 int getSentinel() const {
8627 return sentinel;
8628 }
8629
8630 static const int DefaultSentinel = 0;
8631
8632 int getNullPos() const {
8633 return nullPos;
8634 }
8635
8636 static const int DefaultNullPos = 0;
8637
8638
8639
8640 static bool classof(const Attr *A) { return A->getKind() == attr::Sentinel; }
8641};
8642
8643class SetTypestateAttr : public InheritableAttr {
8644public:
8645 enum ConsumedState {
8646 Unknown,
8647 Consumed,
8648 Unconsumed
8649 };
8650private:
8651 ConsumedState newState;
8652
8653public:
8654 static SetTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState NewState, SourceRange Loc = SourceRange()) {
8655 auto *A = new (Ctx) SetTypestateAttr(Loc, Ctx, NewState, 0);
8656 A->setImplicit(true);
8657 return A;
8658 }
8659
8660 SetTypestateAttr(SourceRange R, ASTContext &Ctx
8661 , ConsumedState NewState
8662 , unsigned SI
8663 )
8664 : InheritableAttr(attr::SetTypestate, R, SI, false, false)
8665 , newState(NewState)
8666 {
8667 }
8668
8669 SetTypestateAttr *clone(ASTContext &C) const;
8670 void printPretty(raw_ostream &OS,
8671 const PrintingPolicy &Policy) const;
8672 const char *getSpelling() const;
8673 ConsumedState getNewState() const {
8674 return newState;
8675 }
8676
8677 static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
8678 Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
8679 .Case("unknown", SetTypestateAttr::Unknown)
8680 .Case("consumed", SetTypestateAttr::Consumed)
8681 .Case("unconsumed", SetTypestateAttr::Unconsumed)
8682 .Default(Optional<ConsumedState>());
8683 if (R) {
8684 Out = *R;
8685 return true;
8686 }
8687 return false;
8688 }
8689
8690 static const char *ConvertConsumedStateToStr(ConsumedState Val) {
8691 switch(Val) {
8692 case SetTypestateAttr::Unknown: return "unknown";
8693 case SetTypestateAttr::Consumed: return "consumed";
8694 case SetTypestateAttr::Unconsumed: return "unconsumed";
8695 }
8696 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 8696)
;
8697 }
8698
8699
8700 static bool classof(const Attr *A) { return A->getKind() == attr::SetTypestate; }
8701};
8702
8703class SharedTrylockFunctionAttr : public InheritableAttr {
8704Expr * successValue;
8705
8706 unsigned args_Size;
8707 Expr * *args_;
8708
8709public:
8710 static SharedTrylockFunctionAttr *CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
8711 auto *A = new (Ctx) SharedTrylockFunctionAttr(Loc, Ctx, SuccessValue, Args, ArgsSize, 0);
8712 A->setImplicit(true);
8713 return A;
8714 }
8715
8716 SharedTrylockFunctionAttr(SourceRange R, ASTContext &Ctx
8717 , Expr * SuccessValue
8718 , Expr * *Args, unsigned ArgsSize
8719 , unsigned SI
8720 )
8721 : InheritableAttr(attr::SharedTrylockFunction, R, SI, true, true)
8722 , successValue(SuccessValue)
8723 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
8724 {
8725 std::copy(Args, Args + args_Size, args_);
8726 }
8727
8728 SharedTrylockFunctionAttr(SourceRange R, ASTContext &Ctx
8729 , Expr * SuccessValue
8730 , unsigned SI
8731 )
8732 : InheritableAttr(attr::SharedTrylockFunction, R, SI, true, true)
8733 , successValue(SuccessValue)
8734 , args_Size(0), args_(nullptr)
8735 {
8736 }
8737
8738 SharedTrylockFunctionAttr *clone(ASTContext &C) const;
8739 void printPretty(raw_ostream &OS,
8740 const PrintingPolicy &Policy) const;
8741 const char *getSpelling() const;
8742 Expr * getSuccessValue() const {
8743 return successValue;
8744 }
8745
8746 typedef Expr ** args_iterator;
8747 args_iterator args_begin() const { return args_; }
8748 args_iterator args_end() const { return args_ + args_Size; }
8749 unsigned args_size() const { return args_Size; }
8750 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
8751
8752
8753
8754
8755 static bool classof(const Attr *A) { return A->getKind() == attr::SharedTrylockFunction; }
8756};
8757
8758class SpeculativeLoadHardeningAttr : public InheritableAttr {
8759public:
8760 static SpeculativeLoadHardeningAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8761 auto *A = new (Ctx) SpeculativeLoadHardeningAttr(Loc, Ctx, 0);
8762 A->setImplicit(true);
8763 return A;
8764 }
8765
8766 SpeculativeLoadHardeningAttr(SourceRange R, ASTContext &Ctx
8767 , unsigned SI
8768 )
8769 : InheritableAttr(attr::SpeculativeLoadHardening, R, SI, false, false)
8770 {
8771 }
8772
8773 SpeculativeLoadHardeningAttr *clone(ASTContext &C) const;
8774 void printPretty(raw_ostream &OS,
8775 const PrintingPolicy &Policy) const;
8776 const char *getSpelling() const;
8777
8778
8779 static bool classof(const Attr *A) { return A->getKind() == attr::SpeculativeLoadHardening; }
8780};
8781
8782class StdCallAttr : public InheritableAttr {
8783public:
8784 static StdCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8785 auto *A = new (Ctx) StdCallAttr(Loc, Ctx, 0);
8786 A->setImplicit(true);
8787 return A;
8788 }
8789
8790 StdCallAttr(SourceRange R, ASTContext &Ctx
8791 , unsigned SI
8792 )
8793 : InheritableAttr(attr::StdCall, R, SI, false, false)
8794 {
8795 }
8796
8797 StdCallAttr *clone(ASTContext &C) const;
8798 void printPretty(raw_ostream &OS,
8799 const PrintingPolicy &Policy) const;
8800 const char *getSpelling() const;
8801
8802
8803 static bool classof(const Attr *A) { return A->getKind() == attr::StdCall; }
8804};
8805
8806class SuppressAttr : public StmtAttr {
8807 unsigned diagnosticIdentifiers_Size;
8808 StringRef *diagnosticIdentifiers_;
8809
8810public:
8811 static SuppressAttr *CreateImplicit(ASTContext &Ctx, StringRef *DiagnosticIdentifiers, unsigned DiagnosticIdentifiersSize, SourceRange Loc = SourceRange()) {
8812 auto *A = new (Ctx) SuppressAttr(Loc, Ctx, DiagnosticIdentifiers, DiagnosticIdentifiersSize, 0);
8813 A->setImplicit(true);
8814 return A;
8815 }
8816
8817 SuppressAttr(SourceRange R, ASTContext &Ctx
8818 , StringRef *DiagnosticIdentifiers, unsigned DiagnosticIdentifiersSize
8819 , unsigned SI
8820 )
8821 : StmtAttr(attr::Suppress, R, SI, false)
8822 , diagnosticIdentifiers_Size(DiagnosticIdentifiersSize), diagnosticIdentifiers_(new (Ctx, 16) StringRef[diagnosticIdentifiers_Size])
8823 {
8824 for (size_t I = 0, E = diagnosticIdentifiers_Size; I != E;
8825 ++I) {
8826 StringRef Ref = DiagnosticIdentifiers[I];
8827 if (!Ref.empty()) {
8828 char *Mem = new (Ctx, 1) char[Ref.size()];
8829 std::memcpy(Mem, Ref.data(), Ref.size());
8830 diagnosticIdentifiers_[I] = StringRef(Mem, Ref.size());
8831 }
8832 }
8833 }
8834
8835 SuppressAttr(SourceRange R, ASTContext &Ctx
8836 , unsigned SI
8837 )
8838 : StmtAttr(attr::Suppress, R, SI, false)
8839 , diagnosticIdentifiers_Size(0), diagnosticIdentifiers_(nullptr)
8840 {
8841 }
8842
8843 SuppressAttr *clone(ASTContext &C) const;
8844 void printPretty(raw_ostream &OS,
8845 const PrintingPolicy &Policy) const;
8846 const char *getSpelling() const;
8847 typedef StringRef* diagnosticIdentifiers_iterator;
8848 diagnosticIdentifiers_iterator diagnosticIdentifiers_begin() const { return diagnosticIdentifiers_; }
8849 diagnosticIdentifiers_iterator diagnosticIdentifiers_end() const { return diagnosticIdentifiers_ + diagnosticIdentifiers_Size; }
8850 unsigned diagnosticIdentifiers_size() const { return diagnosticIdentifiers_Size; }
8851 llvm::iterator_range<diagnosticIdentifiers_iterator> diagnosticIdentifiers() const { return llvm::make_range(diagnosticIdentifiers_begin(), diagnosticIdentifiers_end()); }
8852
8853
8854
8855
8856 static bool classof(const Attr *A) { return A->getKind() == attr::Suppress; }
8857};
8858
8859class SwiftCallAttr : public InheritableAttr {
8860public:
8861 static SwiftCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8862 auto *A = new (Ctx) SwiftCallAttr(Loc, Ctx, 0);
8863 A->setImplicit(true);
8864 return A;
8865 }
8866
8867 SwiftCallAttr(SourceRange R, ASTContext &Ctx
8868 , unsigned SI
8869 )
8870 : InheritableAttr(attr::SwiftCall, R, SI, false, false)
8871 {
8872 }
8873
8874 SwiftCallAttr *clone(ASTContext &C) const;
8875 void printPretty(raw_ostream &OS,
8876 const PrintingPolicy &Policy) const;
8877 const char *getSpelling() const;
8878
8879
8880 static bool classof(const Attr *A) { return A->getKind() == attr::SwiftCall; }
8881};
8882
8883class SwiftContextAttr : public ParameterABIAttr {
8884public:
8885 static SwiftContextAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8886 auto *A = new (Ctx) SwiftContextAttr(Loc, Ctx, 0);
8887 A->setImplicit(true);
8888 return A;
8889 }
8890
8891 SwiftContextAttr(SourceRange R, ASTContext &Ctx
8892 , unsigned SI
8893 )
8894 : ParameterABIAttr(attr::SwiftContext, R, SI, false, false)
8895 {
8896 }
8897
8898 SwiftContextAttr *clone(ASTContext &C) const;
8899 void printPretty(raw_ostream &OS,
8900 const PrintingPolicy &Policy) const;
8901 const char *getSpelling() const;
8902
8903
8904 static bool classof(const Attr *A) { return A->getKind() == attr::SwiftContext; }
8905};
8906
8907class SwiftErrorResultAttr : public ParameterABIAttr {
8908public:
8909 static SwiftErrorResultAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8910 auto *A = new (Ctx) SwiftErrorResultAttr(Loc, Ctx, 0);
8911 A->setImplicit(true);
8912 return A;
8913 }
8914
8915 SwiftErrorResultAttr(SourceRange R, ASTContext &Ctx
8916 , unsigned SI
8917 )
8918 : ParameterABIAttr(attr::SwiftErrorResult, R, SI, false, false)
8919 {
8920 }
8921
8922 SwiftErrorResultAttr *clone(ASTContext &C) const;
8923 void printPretty(raw_ostream &OS,
8924 const PrintingPolicy &Policy) const;
8925 const char *getSpelling() const;
8926
8927
8928 static bool classof(const Attr *A) { return A->getKind() == attr::SwiftErrorResult; }
8929};
8930
8931class SwiftIndirectResultAttr : public ParameterABIAttr {
8932public:
8933 static SwiftIndirectResultAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8934 auto *A = new (Ctx) SwiftIndirectResultAttr(Loc, Ctx, 0);
8935 A->setImplicit(true);
8936 return A;
8937 }
8938
8939 SwiftIndirectResultAttr(SourceRange R, ASTContext &Ctx
8940 , unsigned SI
8941 )
8942 : ParameterABIAttr(attr::SwiftIndirectResult, R, SI, false, false)
8943 {
8944 }
8945
8946 SwiftIndirectResultAttr *clone(ASTContext &C) const;
8947 void printPretty(raw_ostream &OS,
8948 const PrintingPolicy &Policy) const;
8949 const char *getSpelling() const;
8950
8951
8952 static bool classof(const Attr *A) { return A->getKind() == attr::SwiftIndirectResult; }
8953};
8954
8955class SysVABIAttr : public InheritableAttr {
8956public:
8957 static SysVABIAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
8958 auto *A = new (Ctx) SysVABIAttr(Loc, Ctx, 0);
8959 A->setImplicit(true);
8960 return A;
8961 }
8962
8963 SysVABIAttr(SourceRange R, ASTContext &Ctx
8964 , unsigned SI
8965 )
8966 : InheritableAttr(attr::SysVABI, R, SI, false, false)
8967 {
8968 }
8969
8970 SysVABIAttr *clone(ASTContext &C) const;
8971 void printPretty(raw_ostream &OS,
8972 const PrintingPolicy &Policy) const;
8973 const char *getSpelling() const;
8974
8975
8976 static bool classof(const Attr *A) { return A->getKind() == attr::SysVABI; }
8977};
8978
8979class TLSModelAttr : public InheritableAttr {
8980unsigned modelLength;
8981char *model;
8982
8983public:
8984 static TLSModelAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Model, SourceRange Loc = SourceRange()) {
8985 auto *A = new (Ctx) TLSModelAttr(Loc, Ctx, Model, 0);
8986 A->setImplicit(true);
8987 return A;
8988 }
8989
8990 TLSModelAttr(SourceRange R, ASTContext &Ctx
8991 , llvm::StringRef Model
8992 , unsigned SI
8993 )
8994 : InheritableAttr(attr::TLSModel, R, SI, false, false)
8995 , modelLength(Model.size()),model(new (Ctx, 1) char[modelLength])
8996 {
8997 if (!Model.empty())
8998 std::memcpy(model, Model.data(), modelLength);
8999 }
9000
9001 TLSModelAttr *clone(ASTContext &C) const;
9002 void printPretty(raw_ostream &OS,
9003 const PrintingPolicy &Policy) const;
9004 const char *getSpelling() const;
9005 llvm::StringRef getModel() const {
9006 return llvm::StringRef(model, modelLength);
9007 }
9008 unsigned getModelLength() const {
9009 return modelLength;
9010 }
9011 void setModel(ASTContext &C, llvm::StringRef S) {
9012 modelLength = S.size();
9013 this->model = new (C, 1) char [modelLength];
9014 if (!S.empty())
9015 std::memcpy(this->model, S.data(), modelLength);
9016 }
9017
9018
9019
9020 static bool classof(const Attr *A) { return A->getKind() == attr::TLSModel; }
9021};
9022
9023class TargetAttr : public InheritableAttr {
9024unsigned featuresStrLength;
9025char *featuresStr;
9026
9027public:
9028 static TargetAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef FeaturesStr, SourceRange Loc = SourceRange()) {
9029 auto *A = new (Ctx) TargetAttr(Loc, Ctx, FeaturesStr, 0);
9030 A->setImplicit(true);
9031 return A;
9032 }
9033
9034 TargetAttr(SourceRange R, ASTContext &Ctx
9035 , llvm::StringRef FeaturesStr
9036 , unsigned SI
9037 )
9038 : InheritableAttr(attr::Target, R, SI, false, false)
9039 , featuresStrLength(FeaturesStr.size()),featuresStr(new (Ctx, 1) char[featuresStrLength])
9040 {
9041 if (!FeaturesStr.empty())
9042 std::memcpy(featuresStr, FeaturesStr.data(), featuresStrLength);
9043 }
9044
9045 TargetAttr *clone(ASTContext &C) const;
9046 void printPretty(raw_ostream &OS,
9047 const PrintingPolicy &Policy) const;
9048 const char *getSpelling() const;
9049 llvm::StringRef getFeaturesStr() const {
9050 return llvm::StringRef(featuresStr, featuresStrLength);
9051 }
9052 unsigned getFeaturesStrLength() const {
9053 return featuresStrLength;
9054 }
9055 void setFeaturesStr(ASTContext &C, llvm::StringRef S) {
9056 featuresStrLength = S.size();
9057 this->featuresStr = new (C, 1) char [featuresStrLength];
9058 if (!S.empty())
9059 std::memcpy(this->featuresStr, S.data(), featuresStrLength);
9060 }
9061
9062
9063 struct ParsedTargetAttr {
9064 std::vector<std::string> Features;
9065 StringRef Architecture;
9066 bool DuplicateArchitecture = false;
9067 bool operator ==(const ParsedTargetAttr &Other) const {
9068 return DuplicateArchitecture == Other.DuplicateArchitecture &&
9069 Architecture == Other.Architecture && Features == Other.Features;
9070 }
9071 };
9072 ParsedTargetAttr parse() const {
9073 return parse(getFeaturesStr());
9074 }
9075
9076 StringRef getArchitecture() const {
9077 StringRef Features = getFeaturesStr();
9078 if (Features == "default") return {};
9079
9080 SmallVector<StringRef, 1> AttrFeatures;
9081 Features.split(AttrFeatures, ",");
9082
9083 for (auto &Feature : AttrFeatures) {
9084 Feature = Feature.trim();
9085 if (Feature.startswith("arch="))
9086 return Feature.drop_front(sizeof("arch=") - 1);
9087 }
9088 return "";
9089 }
9090
9091 // Gets the list of features as simple string-refs with no +/- or 'no-'.
9092 // Only adds the items to 'Out' that are additions.
9093 void getAddedFeatures(llvm::SmallVectorImpl<StringRef> &Out) const {
9094 StringRef Features = getFeaturesStr();
9095 if (Features == "default") return;
9096
9097 SmallVector<StringRef, 1> AttrFeatures;
9098 Features.split(AttrFeatures, ",");
9099
9100 for (auto &Feature : AttrFeatures) {
9101 Feature = Feature.trim();
9102
9103 if (!Feature.startswith("no-") && !Feature.startswith("arch=") &&
9104 !Feature.startswith("fpmath=") && !Feature.startswith("tune="))
9105 Out.push_back(Feature);
9106 }
9107 }
9108
9109 template<class Compare>
9110 ParsedTargetAttr parse(Compare cmp) const {
9111 ParsedTargetAttr Attrs = parse();
9112 llvm::sort(std::begin(Attrs.Features), std::end(Attrs.Features), cmp);
9113 return Attrs;
9114 }
9115
9116 bool isDefaultVersion() const { return getFeaturesStr() == "default"; }
9117
9118 static ParsedTargetAttr parse(StringRef Features) {
9119 ParsedTargetAttr Ret;
9120 if (Features == "default") return Ret;
9121 SmallVector<StringRef, 1> AttrFeatures;
9122 Features.split(AttrFeatures, ",");
9123
9124 // Grab the various features and prepend a "+" to turn on the feature to
9125 // the backend and add them to our existing set of features.
9126 for (auto &Feature : AttrFeatures) {
9127 // Go ahead and trim whitespace rather than either erroring or
9128 // accepting it weirdly.
9129 Feature = Feature.trim();
9130
9131 // We don't support cpu tuning this way currently.
9132 // TODO: Support the fpmath option. It will require checking
9133 // overall feature validity for the function with the rest of the
9134 // attributes on the function.
9135 if (Feature.startswith("fpmath=") || Feature.startswith("tune="))
9136 continue;
9137
9138 // While we're here iterating check for a different target cpu.
9139 if (Feature.startswith("arch=")) {
9140 if (!Ret.Architecture.empty())
9141 Ret.DuplicateArchitecture = true;
9142 else
9143 Ret.Architecture = Feature.split("=").second.trim();
9144 } else if (Feature.startswith("no-"))
9145 Ret.Features.push_back("-" + Feature.split("-").second.str());
9146 else
9147 Ret.Features.push_back("+" + Feature.str());
9148 }
9149 return Ret;
9150 }
9151
9152
9153 static bool classof(const Attr *A) { return A->getKind() == attr::Target; }
9154};
9155
9156class TestTypestateAttr : public InheritableAttr {
9157public:
9158 enum ConsumedState {
9159 Consumed,
9160 Unconsumed
9161 };
9162private:
9163 ConsumedState testState;
9164
9165public:
9166 static TestTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState TestState, SourceRange Loc = SourceRange()) {
9167 auto *A = new (Ctx) TestTypestateAttr(Loc, Ctx, TestState, 0);
9168 A->setImplicit(true);
9169 return A;
9170 }
9171
9172 TestTypestateAttr(SourceRange R, ASTContext &Ctx
9173 , ConsumedState TestState
9174 , unsigned SI
9175 )
9176 : InheritableAttr(attr::TestTypestate, R, SI, false, false)
9177 , testState(TestState)
9178 {
9179 }
9180
9181 TestTypestateAttr *clone(ASTContext &C) const;
9182 void printPretty(raw_ostream &OS,
9183 const PrintingPolicy &Policy) const;
9184 const char *getSpelling() const;
9185 ConsumedState getTestState() const {
9186 return testState;
9187 }
9188
9189 static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
9190 Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
9191 .Case("consumed", TestTypestateAttr::Consumed)
9192 .Case("unconsumed", TestTypestateAttr::Unconsumed)
9193 .Default(Optional<ConsumedState>());
9194 if (R) {
9195 Out = *R;
9196 return true;
9197 }
9198 return false;
9199 }
9200
9201 static const char *ConvertConsumedStateToStr(ConsumedState Val) {
9202 switch(Val) {
9203 case TestTypestateAttr::Consumed: return "consumed";
9204 case TestTypestateAttr::Unconsumed: return "unconsumed";
9205 }
9206 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 9206)
;
9207 }
9208
9209
9210 static bool classof(const Attr *A) { return A->getKind() == attr::TestTypestate; }
9211};
9212
9213class ThisCallAttr : public InheritableAttr {
9214public:
9215 static ThisCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9216 auto *A = new (Ctx) ThisCallAttr(Loc, Ctx, 0);
9217 A->setImplicit(true);
9218 return A;
9219 }
9220
9221 ThisCallAttr(SourceRange R, ASTContext &Ctx
9222 , unsigned SI
9223 )
9224 : InheritableAttr(attr::ThisCall, R, SI, false, false)
9225 {
9226 }
9227
9228 ThisCallAttr *clone(ASTContext &C) const;
9229 void printPretty(raw_ostream &OS,
9230 const PrintingPolicy &Policy) const;
9231 const char *getSpelling() const;
9232
9233
9234 static bool classof(const Attr *A) { return A->getKind() == attr::ThisCall; }
9235};
9236
9237class ThreadAttr : public Attr {
9238public:
9239 static ThreadAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9240 auto *A = new (Ctx) ThreadAttr(Loc, Ctx, 0);
9241 A->setImplicit(true);
9242 return A;
9243 }
9244
9245 ThreadAttr(SourceRange R, ASTContext &Ctx
9246 , unsigned SI
9247 )
9248 : Attr(attr::Thread, R, SI, false)
9249 {
9250 }
9251
9252 ThreadAttr *clone(ASTContext &C) const;
9253 void printPretty(raw_ostream &OS,
9254 const PrintingPolicy &Policy) const;
9255 const char *getSpelling() const;
9256
9257
9258 static bool classof(const Attr *A) { return A->getKind() == attr::Thread; }
9259};
9260
9261class TransparentUnionAttr : public InheritableAttr {
9262public:
9263 static TransparentUnionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9264 auto *A = new (Ctx) TransparentUnionAttr(Loc, Ctx, 0);
9265 A->setImplicit(true);
9266 return A;
9267 }
9268
9269 TransparentUnionAttr(SourceRange R, ASTContext &Ctx
9270 , unsigned SI
9271 )
9272 : InheritableAttr(attr::TransparentUnion, R, SI, false, false)
9273 {
9274 }
9275
9276 TransparentUnionAttr *clone(ASTContext &C) const;
9277 void printPretty(raw_ostream &OS,
9278 const PrintingPolicy &Policy) const;
9279 const char *getSpelling() const;
9280
9281
9282 static bool classof(const Attr *A) { return A->getKind() == attr::TransparentUnion; }
9283};
9284
9285class TrivialABIAttr : public InheritableAttr {
9286public:
9287 static TrivialABIAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9288 auto *A = new (Ctx) TrivialABIAttr(Loc, Ctx, 0);
9289 A->setImplicit(true);
9290 return A;
9291 }
9292
9293 TrivialABIAttr(SourceRange R, ASTContext &Ctx
9294 , unsigned SI
9295 )
9296 : InheritableAttr(attr::TrivialABI, R, SI, false, false)
9297 {
9298 }
9299
9300 TrivialABIAttr *clone(ASTContext &C) const;
9301 void printPretty(raw_ostream &OS,
9302 const PrintingPolicy &Policy) const;
9303 const char *getSpelling() const;
9304
9305
9306 static bool classof(const Attr *A) { return A->getKind() == attr::TrivialABI; }
9307};
9308
9309class TryAcquireCapabilityAttr : public InheritableAttr {
9310Expr * successValue;
9311
9312 unsigned args_Size;
9313 Expr * *args_;
9314
9315public:
9316 enum Spelling {
9317 GNU_try_acquire_capability = 0,
9318 CXX11_clang_try_acquire_capability = 1,
9319 GNU_try_acquire_shared_capability = 2,
9320 CXX11_clang_try_acquire_shared_capability = 3
9321 };
9322
9323 static TryAcquireCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
9324 auto *A = new (Ctx) TryAcquireCapabilityAttr(Loc, Ctx, SuccessValue, Args, ArgsSize, S);
9325 A->setImplicit(true);
9326 return A;
9327 }
9328
9329 TryAcquireCapabilityAttr(SourceRange R, ASTContext &Ctx
9330 , Expr * SuccessValue
9331 , Expr * *Args, unsigned ArgsSize
9332 , unsigned SI
9333 )
9334 : InheritableAttr(attr::TryAcquireCapability, R, SI, true, true)
9335 , successValue(SuccessValue)
9336 , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
9337 {
9338 std::copy(Args, Args + args_Size, args_);
9339 }
9340
9341 TryAcquireCapabilityAttr(SourceRange R, ASTContext &Ctx
9342 , Expr * SuccessValue
9343 , unsigned SI
9344 )
9345 : InheritableAttr(attr::TryAcquireCapability, R, SI, true, true)
9346 , successValue(SuccessValue)
9347 , args_Size(0), args_(nullptr)
9348 {
9349 }
9350
9351 TryAcquireCapabilityAttr *clone(ASTContext &C) const;
9352 void printPretty(raw_ostream &OS,
9353 const PrintingPolicy &Policy) const;
9354 const char *getSpelling() const;
9355 Spelling getSemanticSpelling() const {
9356 switch (SpellingListIndex) {
9357 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 9357)
;
9358 case 0: return GNU_try_acquire_capability;
9359 case 1: return CXX11_clang_try_acquire_capability;
9360 case 2: return GNU_try_acquire_shared_capability;
9361 case 3: return CXX11_clang_try_acquire_shared_capability;
9362 }
9363 }
9364 bool isShared() const { return SpellingListIndex == 2 ||
9365 SpellingListIndex == 3; }
9366 Expr * getSuccessValue() const {
9367 return successValue;
9368 }
9369
9370 typedef Expr ** args_iterator;
9371 args_iterator args_begin() const { return args_; }
9372 args_iterator args_end() const { return args_ + args_Size; }
9373 unsigned args_size() const { return args_Size; }
9374 llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
9375
9376
9377
9378
9379 static bool classof(const Attr *A) { return A->getKind() == attr::TryAcquireCapability; }
9380};
9381
9382class TypeNonNullAttr : public TypeAttr {
9383public:
9384 static TypeNonNullAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9385 auto *A = new (Ctx) TypeNonNullAttr(Loc, Ctx, 0);
9386 A->setImplicit(true);
9387 return A;
9388 }
9389
9390 TypeNonNullAttr(SourceRange R, ASTContext &Ctx
9391 , unsigned SI
9392 )
9393 : TypeAttr(attr::TypeNonNull, R, SI, false)
9394 {
9395 }
9396
9397 TypeNonNullAttr *clone(ASTContext &C) const;
9398 void printPretty(raw_ostream &OS,
9399 const PrintingPolicy &Policy) const;
9400 const char *getSpelling() const;
9401
9402
9403 static bool classof(const Attr *A) { return A->getKind() == attr::TypeNonNull; }
9404};
9405
9406class TypeNullUnspecifiedAttr : public TypeAttr {
9407public:
9408 static TypeNullUnspecifiedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9409 auto *A = new (Ctx) TypeNullUnspecifiedAttr(Loc, Ctx, 0);
9410 A->setImplicit(true);
9411 return A;
9412 }
9413
9414 TypeNullUnspecifiedAttr(SourceRange R, ASTContext &Ctx
9415 , unsigned SI
9416 )
9417 : TypeAttr(attr::TypeNullUnspecified, R, SI, false)
9418 {
9419 }
9420
9421 TypeNullUnspecifiedAttr *clone(ASTContext &C) const;
9422 void printPretty(raw_ostream &OS,
9423 const PrintingPolicy &Policy) const;
9424 const char *getSpelling() const;
9425
9426
9427 static bool classof(const Attr *A) { return A->getKind() == attr::TypeNullUnspecified; }
9428};
9429
9430class TypeNullableAttr : public TypeAttr {
9431public:
9432 static TypeNullableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9433 auto *A = new (Ctx) TypeNullableAttr(Loc, Ctx, 0);
9434 A->setImplicit(true);
9435 return A;
9436 }
9437
9438 TypeNullableAttr(SourceRange R, ASTContext &Ctx
9439 , unsigned SI
9440 )
9441 : TypeAttr(attr::TypeNullable, R, SI, false)
9442 {
9443 }
9444
9445 TypeNullableAttr *clone(ASTContext &C) const;
9446 void printPretty(raw_ostream &OS,
9447 const PrintingPolicy &Policy) const;
9448 const char *getSpelling() const;
9449
9450
9451 static bool classof(const Attr *A) { return A->getKind() == attr::TypeNullable; }
9452};
9453
9454class TypeTagForDatatypeAttr : public InheritableAttr {
9455IdentifierInfo * argumentKind;
9456
9457TypeSourceInfo * matchingCType;
9458
9459bool layoutCompatible;
9460
9461bool mustBeNull;
9462
9463public:
9464 static TypeTagForDatatypeAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * ArgumentKind, TypeSourceInfo * MatchingCType, bool LayoutCompatible, bool MustBeNull, SourceRange Loc = SourceRange()) {
9465 auto *A = new (Ctx) TypeTagForDatatypeAttr(Loc, Ctx, ArgumentKind, MatchingCType, LayoutCompatible, MustBeNull, 0);
9466 A->setImplicit(true);
9467 return A;
9468 }
9469
9470 TypeTagForDatatypeAttr(SourceRange R, ASTContext &Ctx
9471 , IdentifierInfo * ArgumentKind
9472 , TypeSourceInfo * MatchingCType
9473 , bool LayoutCompatible
9474 , bool MustBeNull
9475 , unsigned SI
9476 )
9477 : InheritableAttr(attr::TypeTagForDatatype, R, SI, false, false)
9478 , argumentKind(ArgumentKind)
9479 , matchingCType(MatchingCType)
9480 , layoutCompatible(LayoutCompatible)
9481 , mustBeNull(MustBeNull)
9482 {
9483 }
9484
9485 TypeTagForDatatypeAttr *clone(ASTContext &C) const;
9486 void printPretty(raw_ostream &OS,
9487 const PrintingPolicy &Policy) const;
9488 const char *getSpelling() const;
9489 IdentifierInfo * getArgumentKind() const {
9490 return argumentKind;
9491 }
9492
9493 QualType getMatchingCType() const {
9494 return matchingCType->getType();
9495 } TypeSourceInfo * getMatchingCTypeLoc() const {
9496 return matchingCType;
9497 }
9498
9499 bool getLayoutCompatible() const {
9500 return layoutCompatible;
9501 }
9502
9503 bool getMustBeNull() const {
9504 return mustBeNull;
9505 }
9506
9507
9508
9509 static bool classof(const Attr *A) { return A->getKind() == attr::TypeTagForDatatype; }
9510};
9511
9512class TypeVisibilityAttr : public InheritableAttr {
9513public:
9514 enum VisibilityType {
9515 Default,
9516 Hidden,
9517 Protected
9518 };
9519private:
9520 VisibilityType visibility;
9521
9522public:
9523 static TypeVisibilityAttr *CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, SourceRange Loc = SourceRange()) {
9524 auto *A = new (Ctx) TypeVisibilityAttr(Loc, Ctx, Visibility, 0);
9525 A->setImplicit(true);
9526 return A;
9527 }
9528
9529 TypeVisibilityAttr(SourceRange R, ASTContext &Ctx
9530 , VisibilityType Visibility
9531 , unsigned SI
9532 )
9533 : InheritableAttr(attr::TypeVisibility, R, SI, false, false)
9534 , visibility(Visibility)
9535 {
9536 }
9537
9538 TypeVisibilityAttr *clone(ASTContext &C) const;
9539 void printPretty(raw_ostream &OS,
9540 const PrintingPolicy &Policy) const;
9541 const char *getSpelling() const;
9542 VisibilityType getVisibility() const {
9543 return visibility;
9544 }
9545
9546 static bool ConvertStrToVisibilityType(StringRef Val, VisibilityType &Out) {
9547 Optional<VisibilityType> R = llvm::StringSwitch<Optional<VisibilityType>>(Val)
9548 .Case("default", TypeVisibilityAttr::Default)
9549 .Case("hidden", TypeVisibilityAttr::Hidden)
9550 .Case("internal", TypeVisibilityAttr::Hidden)
9551 .Case("protected", TypeVisibilityAttr::Protected)
9552 .Default(Optional<VisibilityType>());
9553 if (R) {
9554 Out = *R;
9555 return true;
9556 }
9557 return false;
9558 }
9559
9560 static const char *ConvertVisibilityTypeToStr(VisibilityType Val) {
9561 switch(Val) {
9562 case TypeVisibilityAttr::Default: return "default";
9563 case TypeVisibilityAttr::Hidden: return "hidden";
9564 case TypeVisibilityAttr::Protected: return "protected";
9565 }
9566 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 9566)
;
9567 }
9568
9569
9570 static bool classof(const Attr *A) { return A->getKind() == attr::TypeVisibility; }
9571};
9572
9573class UPtrAttr : public TypeAttr {
9574public:
9575 static UPtrAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9576 auto *A = new (Ctx) UPtrAttr(Loc, Ctx, 0);
9577 A->setImplicit(true);
9578 return A;
9579 }
9580
9581 UPtrAttr(SourceRange R, ASTContext &Ctx
9582 , unsigned SI
9583 )
9584 : TypeAttr(attr::UPtr, R, SI, false)
9585 {
9586 }
9587
9588 UPtrAttr *clone(ASTContext &C) const;
9589 void printPretty(raw_ostream &OS,
9590 const PrintingPolicy &Policy) const;
9591 const char *getSpelling() const;
9592
9593
9594 static bool classof(const Attr *A) { return A->getKind() == attr::UPtr; }
9595};
9596
9597class UnavailableAttr : public InheritableAttr {
9598unsigned messageLength;
9599char *message;
9600
9601public:
9602 enum ImplicitReason {
9603 IR_None,
9604 IR_ARCForbiddenType,
9605 IR_ForbiddenWeak,
9606 IR_ARCForbiddenConversion,
9607 IR_ARCInitReturnsUnrelated,
9608 IR_ARCFieldWithOwnership
9609 };
9610private:
9611 ImplicitReason implicitReason;
9612
9613public:
9614 static UnavailableAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, ImplicitReason ImplicitReason, SourceRange Loc = SourceRange()) {
9615 auto *A = new (Ctx) UnavailableAttr(Loc, Ctx, Message, ImplicitReason, 0);
9616 A->setImplicit(true);
9617 return A;
9618 }
9619
9620 static UnavailableAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, SourceRange Loc = SourceRange()) {
9621 auto *A = new (Ctx) UnavailableAttr(Loc, Ctx, Message, 0);
9622 A->setImplicit(true);
9623 return A;
9624 }
9625
9626 UnavailableAttr(SourceRange R, ASTContext &Ctx
9627 , llvm::StringRef Message
9628 , ImplicitReason ImplicitReason
9629 , unsigned SI
9630 )
9631 : InheritableAttr(attr::Unavailable, R, SI, false, false)
9632 , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
9633 , implicitReason(ImplicitReason)
9634 {
9635 if (!Message.empty())
9636 std::memcpy(message, Message.data(), messageLength);
9637 }
9638
9639 UnavailableAttr(SourceRange R, ASTContext &Ctx
9640 , llvm::StringRef Message
9641 , unsigned SI
9642 )
9643 : InheritableAttr(attr::Unavailable, R, SI, false, false)
9644 , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
9645 , implicitReason(ImplicitReason(0))
9646 {
9647 if (!Message.empty())
9648 std::memcpy(message, Message.data(), messageLength);
9649 }
9650
9651 UnavailableAttr(SourceRange R, ASTContext &Ctx
9652 , unsigned SI
9653 )
9654 : InheritableAttr(attr::Unavailable, R, SI, false, false)
9655 , messageLength(0),message(nullptr)
9656 , implicitReason(ImplicitReason(0))
9657 {
9658 }
9659
9660 UnavailableAttr *clone(ASTContext &C) const;
9661 void printPretty(raw_ostream &OS,
9662 const PrintingPolicy &Policy) const;
9663 const char *getSpelling() const;
9664 llvm::StringRef getMessage() const {
9665 return llvm::StringRef(message, messageLength);
9666 }
9667 unsigned getMessageLength() const {
9668 return messageLength;
9669 }
9670 void setMessage(ASTContext &C, llvm::StringRef S) {
9671 messageLength = S.size();
9672 this->message = new (C, 1) char [messageLength];
9673 if (!S.empty())
9674 std::memcpy(this->message, S.data(), messageLength);
9675 }
9676
9677 ImplicitReason getImplicitReason() const {
9678 return implicitReason;
9679 }
9680
9681
9682
9683 static bool classof(const Attr *A) { return A->getKind() == attr::Unavailable; }
9684};
9685
9686class UninitializedAttr : public InheritableAttr {
9687public:
9688 static UninitializedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9689 auto *A = new (Ctx) UninitializedAttr(Loc, Ctx, 0);
9690 A->setImplicit(true);
9691 return A;
9692 }
9693
9694 UninitializedAttr(SourceRange R, ASTContext &Ctx
9695 , unsigned SI
9696 )
9697 : InheritableAttr(attr::Uninitialized, R, SI, false, false)
9698 {
9699 }
9700
9701 UninitializedAttr *clone(ASTContext &C) const;
9702 void printPretty(raw_ostream &OS,
9703 const PrintingPolicy &Policy) const;
9704 const char *getSpelling() const;
9705
9706
9707 static bool classof(const Attr *A) { return A->getKind() == attr::Uninitialized; }
9708};
9709
9710class UnusedAttr : public InheritableAttr {
9711public:
9712 enum Spelling {
9713 CXX11_maybe_unused = 0,
9714 GNU_unused = 1,
9715 CXX11_gnu_unused = 2,
9716 C2x_maybe_unused = 3
9717 };
9718
9719 static UnusedAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
9720 auto *A = new (Ctx) UnusedAttr(Loc, Ctx, S);
9721 A->setImplicit(true);
9722 return A;
9723 }
9724
9725 UnusedAttr(SourceRange R, ASTContext &Ctx
9726 , unsigned SI
9727 )
9728 : InheritableAttr(attr::Unused, R, SI, false, false)
9729 {
9730 }
9731
9732 UnusedAttr *clone(ASTContext &C) const;
9733 void printPretty(raw_ostream &OS,
9734 const PrintingPolicy &Policy) const;
9735 const char *getSpelling() const;
9736 Spelling getSemanticSpelling() const {
9737 switch (SpellingListIndex) {
9738 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 9738)
;
9739 case 0: return CXX11_maybe_unused;
9740 case 1: return GNU_unused;
9741 case 2: return CXX11_gnu_unused;
9742 case 3: return C2x_maybe_unused;
9743 }
9744 }
9745
9746
9747 static bool classof(const Attr *A) { return A->getKind() == attr::Unused; }
9748};
9749
9750class UsedAttr : public InheritableAttr {
9751public:
9752 static UsedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9753 auto *A = new (Ctx) UsedAttr(Loc, Ctx, 0);
9754 A->setImplicit(true);
9755 return A;
9756 }
9757
9758 UsedAttr(SourceRange R, ASTContext &Ctx
9759 , unsigned SI
9760 )
9761 : InheritableAttr(attr::Used, R, SI, false, false)
9762 {
9763 }
9764
9765 UsedAttr *clone(ASTContext &C) const;
9766 void printPretty(raw_ostream &OS,
9767 const PrintingPolicy &Policy) const;
9768 const char *getSpelling() const;
9769
9770
9771 static bool classof(const Attr *A) { return A->getKind() == attr::Used; }
9772};
9773
9774class UuidAttr : public InheritableAttr {
9775unsigned guidLength;
9776char *guid;
9777
9778public:
9779 static UuidAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Guid, SourceRange Loc = SourceRange()) {
9780 auto *A = new (Ctx) UuidAttr(Loc, Ctx, Guid, 0);
9781 A->setImplicit(true);
9782 return A;
9783 }
9784
9785 UuidAttr(SourceRange R, ASTContext &Ctx
9786 , llvm::StringRef Guid
9787 , unsigned SI
9788 )
9789 : InheritableAttr(attr::Uuid, R, SI, false, false)
9790 , guidLength(Guid.size()),guid(new (Ctx, 1) char[guidLength])
9791 {
9792 if (!Guid.empty())
9793 std::memcpy(guid, Guid.data(), guidLength);
9794 }
9795
9796 UuidAttr *clone(ASTContext &C) const;
9797 void printPretty(raw_ostream &OS,
9798 const PrintingPolicy &Policy) const;
9799 const char *getSpelling() const;
9800 llvm::StringRef getGuid() const {
9801 return llvm::StringRef(guid, guidLength);
9802 }
9803 unsigned getGuidLength() const {
9804 return guidLength;
9805 }
9806 void setGuid(ASTContext &C, llvm::StringRef S) {
9807 guidLength = S.size();
9808 this->guid = new (C, 1) char [guidLength];
9809 if (!S.empty())
9810 std::memcpy(this->guid, S.data(), guidLength);
9811 }
9812
9813
9814
9815 static bool classof(const Attr *A) { return A->getKind() == attr::Uuid; }
9816};
9817
9818class VecReturnAttr : public InheritableAttr {
9819public:
9820 static VecReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9821 auto *A = new (Ctx) VecReturnAttr(Loc, Ctx, 0);
9822 A->setImplicit(true);
9823 return A;
9824 }
9825
9826 VecReturnAttr(SourceRange R, ASTContext &Ctx
9827 , unsigned SI
9828 )
9829 : InheritableAttr(attr::VecReturn, R, SI, false, false)
9830 {
9831 }
9832
9833 VecReturnAttr *clone(ASTContext &C) const;
9834 void printPretty(raw_ostream &OS,
9835 const PrintingPolicy &Policy) const;
9836 const char *getSpelling() const;
9837
9838
9839 static bool classof(const Attr *A) { return A->getKind() == attr::VecReturn; }
9840};
9841
9842class VecTypeHintAttr : public InheritableAttr {
9843TypeSourceInfo * typeHint;
9844
9845public:
9846 static VecTypeHintAttr *CreateImplicit(ASTContext &Ctx, TypeSourceInfo * TypeHint, SourceRange Loc = SourceRange()) {
9847 auto *A = new (Ctx) VecTypeHintAttr(Loc, Ctx, TypeHint, 0);
9848 A->setImplicit(true);
9849 return A;
9850 }
9851
9852 VecTypeHintAttr(SourceRange R, ASTContext &Ctx
9853 , TypeSourceInfo * TypeHint
9854 , unsigned SI
9855 )
9856 : InheritableAttr(attr::VecTypeHint, R, SI, false, false)
9857 , typeHint(TypeHint)
9858 {
9859 }
9860
9861 VecTypeHintAttr *clone(ASTContext &C) const;
9862 void printPretty(raw_ostream &OS,
9863 const PrintingPolicy &Policy) const;
9864 const char *getSpelling() const;
9865 QualType getTypeHint() const {
9866 return typeHint->getType();
9867 } TypeSourceInfo * getTypeHintLoc() const {
9868 return typeHint;
9869 }
9870
9871
9872
9873 static bool classof(const Attr *A) { return A->getKind() == attr::VecTypeHint; }
9874};
9875
9876class VectorCallAttr : public InheritableAttr {
9877public:
9878 static VectorCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9879 auto *A = new (Ctx) VectorCallAttr(Loc, Ctx, 0);
9880 A->setImplicit(true);
9881 return A;
9882 }
9883
9884 VectorCallAttr(SourceRange R, ASTContext &Ctx
9885 , unsigned SI
9886 )
9887 : InheritableAttr(attr::VectorCall, R, SI, false, false)
9888 {
9889 }
9890
9891 VectorCallAttr *clone(ASTContext &C) const;
9892 void printPretty(raw_ostream &OS,
9893 const PrintingPolicy &Policy) const;
9894 const char *getSpelling() const;
9895
9896
9897 static bool classof(const Attr *A) { return A->getKind() == attr::VectorCall; }
9898};
9899
9900class VisibilityAttr : public InheritableAttr {
9901public:
9902 enum VisibilityType {
9903 Default,
9904 Hidden,
9905 Protected
9906 };
9907private:
9908 VisibilityType visibility;
9909
9910public:
9911 static VisibilityAttr *CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, SourceRange Loc = SourceRange()) {
9912 auto *A = new (Ctx) VisibilityAttr(Loc, Ctx, Visibility, 0);
9913 A->setImplicit(true);
9914 return A;
9915 }
9916
9917 VisibilityAttr(SourceRange R, ASTContext &Ctx
9918 , VisibilityType Visibility
9919 , unsigned SI
9920 )
9921 : InheritableAttr(attr::Visibility, R, SI, false, false)
9922 , visibility(Visibility)
9923 {
9924 }
9925
9926 VisibilityAttr *clone(ASTContext &C) const;
9927 void printPretty(raw_ostream &OS,
9928 const PrintingPolicy &Policy) const;
9929 const char *getSpelling() const;
9930 VisibilityType getVisibility() const {
9931 return visibility;
9932 }
9933
9934 static bool ConvertStrToVisibilityType(StringRef Val, VisibilityType &Out) {
9935 Optional<VisibilityType> R = llvm::StringSwitch<Optional<VisibilityType>>(Val)
9936 .Case("default", VisibilityAttr::Default)
9937 .Case("hidden", VisibilityAttr::Hidden)
9938 .Case("internal", VisibilityAttr::Hidden)
9939 .Case("protected", VisibilityAttr::Protected)
9940 .Default(Optional<VisibilityType>());
9941 if (R) {
9942 Out = *R;
9943 return true;
9944 }
9945 return false;
9946 }
9947
9948 static const char *ConvertVisibilityTypeToStr(VisibilityType Val) {
9949 switch(Val) {
9950 case VisibilityAttr::Default: return "default";
9951 case VisibilityAttr::Hidden: return "hidden";
9952 case VisibilityAttr::Protected: return "protected";
9953 }
9954 llvm_unreachable("No enumerator with that value")::llvm::llvm_unreachable_internal("No enumerator with that value"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 9954)
;
9955 }
9956
9957
9958 static bool classof(const Attr *A) { return A->getKind() == attr::Visibility; }
9959};
9960
9961class WarnUnusedAttr : public InheritableAttr {
9962public:
9963 static WarnUnusedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
9964 auto *A = new (Ctx) WarnUnusedAttr(Loc, Ctx, 0);
9965 A->setImplicit(true);
9966 return A;
9967 }
9968
9969 WarnUnusedAttr(SourceRange R, ASTContext &Ctx
9970 , unsigned SI
9971 )
9972 : InheritableAttr(attr::WarnUnused, R, SI, false, false)
9973 {
9974 }
9975
9976 WarnUnusedAttr *clone(ASTContext &C) const;
9977 void printPretty(raw_ostream &OS,
9978 const PrintingPolicy &Policy) const;
9979 const char *getSpelling() const;
9980
9981
9982 static bool classof(const Attr *A) { return A->getKind() == attr::WarnUnused; }
9983};
9984
9985class WarnUnusedResultAttr : public InheritableAttr {
9986public:
9987 enum Spelling {
9988 CXX11_nodiscard = 0,
9989 C2x_nodiscard = 1,
9990 CXX11_clang_warn_unused_result = 2,
9991 GNU_warn_unused_result = 3,
9992 CXX11_gnu_warn_unused_result = 4
9993 };
9994
9995 static WarnUnusedResultAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
9996 auto *A = new (Ctx) WarnUnusedResultAttr(Loc, Ctx, S);
9997 A->setImplicit(true);
9998 return A;
9999 }
10000
10001 WarnUnusedResultAttr(SourceRange R, ASTContext &Ctx
10002 , unsigned SI
10003 )
10004 : InheritableAttr(attr::WarnUnusedResult, R, SI, false, false)
10005 {
10006 }
10007
10008 WarnUnusedResultAttr *clone(ASTContext &C) const;
10009 void printPretty(raw_ostream &OS,
10010 const PrintingPolicy &Policy) const;
10011 const char *getSpelling() const;
10012 Spelling getSemanticSpelling() const {
10013 switch (SpellingListIndex) {
10014 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 10014)
;
10015 case 0: return CXX11_nodiscard;
10016 case 1: return C2x_nodiscard;
10017 case 2: return CXX11_clang_warn_unused_result;
10018 case 3: return GNU_warn_unused_result;
10019 case 4: return CXX11_gnu_warn_unused_result;
10020 }
10021 }
10022
10023
10024 static bool classof(const Attr *A) { return A->getKind() == attr::WarnUnusedResult; }
10025};
10026
10027class WeakAttr : public InheritableAttr {
10028public:
10029 static WeakAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
10030 auto *A = new (Ctx) WeakAttr(Loc, Ctx, 0);
10031 A->setImplicit(true);
10032 return A;
10033 }
10034
10035 WeakAttr(SourceRange R, ASTContext &Ctx
10036 , unsigned SI
10037 )
10038 : InheritableAttr(attr::Weak, R, SI, false, false)
10039 {
10040 }
10041
10042 WeakAttr *clone(ASTContext &C) const;
10043 void printPretty(raw_ostream &OS,
10044 const PrintingPolicy &Policy) const;
10045 const char *getSpelling() const;
10046
10047
10048 static bool classof(const Attr *A) { return A->getKind() == attr::Weak; }
10049};
10050
10051class WeakImportAttr : public InheritableAttr {
10052public:
10053 static WeakImportAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
10054 auto *A = new (Ctx) WeakImportAttr(Loc, Ctx, 0);
10055 A->setImplicit(true);
10056 return A;
10057 }
10058
10059 WeakImportAttr(SourceRange R, ASTContext &Ctx
10060 , unsigned SI
10061 )
10062 : InheritableAttr(attr::WeakImport, R, SI, false, false)
10063 {
10064 }
10065
10066 WeakImportAttr *clone(ASTContext &C) const;
10067 void printPretty(raw_ostream &OS,
10068 const PrintingPolicy &Policy) const;
10069 const char *getSpelling() const;
10070
10071
10072 static bool classof(const Attr *A) { return A->getKind() == attr::WeakImport; }
10073};
10074
10075class WeakRefAttr : public InheritableAttr {
10076unsigned aliaseeLength;
10077char *aliasee;
10078
10079public:
10080 static WeakRefAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Loc = SourceRange()) {
10081 auto *A = new (Ctx) WeakRefAttr(Loc, Ctx, Aliasee, 0);
10082 A->setImplicit(true);
10083 return A;
10084 }
10085
10086 WeakRefAttr(SourceRange R, ASTContext &Ctx
10087 , llvm::StringRef Aliasee
10088 , unsigned SI
10089 )
10090 : InheritableAttr(attr::WeakRef, R, SI, false, false)
10091 , aliaseeLength(Aliasee.size()),aliasee(new (Ctx, 1) char[aliaseeLength])
10092 {
10093 if (!Aliasee.empty())
10094 std::memcpy(aliasee, Aliasee.data(), aliaseeLength);
10095 }
10096
10097 WeakRefAttr(SourceRange R, ASTContext &Ctx
10098 , unsigned SI
10099 )
10100 : InheritableAttr(attr::WeakRef, R, SI, false, false)
10101 , aliaseeLength(0),aliasee(nullptr)
10102 {
10103 }
10104
10105 WeakRefAttr *clone(ASTContext &C) const;
10106 void printPretty(raw_ostream &OS,
10107 const PrintingPolicy &Policy) const;
10108 const char *getSpelling() const;
10109 llvm::StringRef getAliasee() const {
10110 return llvm::StringRef(aliasee, aliaseeLength);
10111 }
10112 unsigned getAliaseeLength() const {
10113 return aliaseeLength;
10114 }
10115 void setAliasee(ASTContext &C, llvm::StringRef S) {
10116 aliaseeLength = S.size();
10117 this->aliasee = new (C, 1) char [aliaseeLength];
10118 if (!S.empty())
10119 std::memcpy(this->aliasee, S.data(), aliaseeLength);
10120 }
10121
10122
10123
10124 static bool classof(const Attr *A) { return A->getKind() == attr::WeakRef; }
10125};
10126
10127class WebAssemblyImportModuleAttr : public InheritableAttr {
10128unsigned importModuleLength;
10129char *importModule;
10130
10131public:
10132 static WebAssemblyImportModuleAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef ImportModule, SourceRange Loc = SourceRange()) {
10133 auto *A = new (Ctx) WebAssemblyImportModuleAttr(Loc, Ctx, ImportModule, 0);
10134 A->setImplicit(true);
10135 return A;
10136 }
10137
10138 WebAssemblyImportModuleAttr(SourceRange R, ASTContext &Ctx
10139 , llvm::StringRef ImportModule
10140 , unsigned SI
10141 )
10142 : InheritableAttr(attr::WebAssemblyImportModule, R, SI, false, false)
10143 , importModuleLength(ImportModule.size()),importModule(new (Ctx, 1) char[importModuleLength])
10144 {
10145 if (!ImportModule.empty())
10146 std::memcpy(importModule, ImportModule.data(), importModuleLength);
10147 }
10148
10149 WebAssemblyImportModuleAttr *clone(ASTContext &C) const;
10150 void printPretty(raw_ostream &OS,
10151 const PrintingPolicy &Policy) const;
10152 const char *getSpelling() const;
10153 llvm::StringRef getImportModule() const {
10154 return llvm::StringRef(importModule, importModuleLength);
10155 }
10156 unsigned getImportModuleLength() const {
10157 return importModuleLength;
10158 }
10159 void setImportModule(ASTContext &C, llvm::StringRef S) {
10160 importModuleLength = S.size();
10161 this->importModule = new (C, 1) char [importModuleLength];
10162 if (!S.empty())
10163 std::memcpy(this->importModule, S.data(), importModuleLength);
10164 }
10165
10166
10167
10168 static bool classof(const Attr *A) { return A->getKind() == attr::WebAssemblyImportModule; }
10169};
10170
10171class WebAssemblyImportNameAttr : public InheritableAttr {
10172unsigned importNameLength;
10173char *importName;
10174
10175public:
10176 static WebAssemblyImportNameAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef ImportName, SourceRange Loc = SourceRange()) {
10177 auto *A = new (Ctx) WebAssemblyImportNameAttr(Loc, Ctx, ImportName, 0);
10178 A->setImplicit(true);
10179 return A;
10180 }
10181
10182 WebAssemblyImportNameAttr(SourceRange R, ASTContext &Ctx
10183 , llvm::StringRef ImportName
10184 , unsigned SI
10185 )
10186 : InheritableAttr(attr::WebAssemblyImportName, R, SI, false, false)
10187 , importNameLength(ImportName.size()),importName(new (Ctx, 1) char[importNameLength])
10188 {
10189 if (!ImportName.empty())
10190 std::memcpy(importName, ImportName.data(), importNameLength);
10191 }
10192
10193 WebAssemblyImportNameAttr *clone(ASTContext &C) const;
10194 void printPretty(raw_ostream &OS,
10195 const PrintingPolicy &Policy) const;
10196 const char *getSpelling() const;
10197 llvm::StringRef getImportName() const {
10198 return llvm::StringRef(importName, importNameLength);
10199 }
10200 unsigned getImportNameLength() const {
10201 return importNameLength;
10202 }
10203 void setImportName(ASTContext &C, llvm::StringRef S) {
10204 importNameLength = S.size();
10205 this->importName = new (C, 1) char [importNameLength];
10206 if (!S.empty())
10207 std::memcpy(this->importName, S.data(), importNameLength);
10208 }
10209
10210
10211
10212 static bool classof(const Attr *A) { return A->getKind() == attr::WebAssemblyImportName; }
10213};
10214
10215class WorkGroupSizeHintAttr : public InheritableAttr {
10216unsigned xDim;
10217
10218unsigned yDim;
10219
10220unsigned zDim;
10221
10222public:
10223 static WorkGroupSizeHintAttr *CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Loc = SourceRange()) {
10224 auto *A = new (Ctx) WorkGroupSizeHintAttr(Loc, Ctx, XDim, YDim, ZDim, 0);
10225 A->setImplicit(true);
10226 return A;
10227 }
10228
10229 WorkGroupSizeHintAttr(SourceRange R, ASTContext &Ctx
10230 , unsigned XDim
10231 , unsigned YDim
10232 , unsigned ZDim
10233 , unsigned SI
10234 )
10235 : InheritableAttr(attr::WorkGroupSizeHint, R, SI, false, false)
10236 , xDim(XDim)
10237 , yDim(YDim)
10238 , zDim(ZDim)
10239 {
10240 }
10241
10242 WorkGroupSizeHintAttr *clone(ASTContext &C) const;
10243 void printPretty(raw_ostream &OS,
10244 const PrintingPolicy &Policy) const;
10245 const char *getSpelling() const;
10246 unsigned getXDim() const {
10247 return xDim;
10248 }
10249
10250 unsigned getYDim() const {
10251 return yDim;
10252 }
10253
10254 unsigned getZDim() const {
10255 return zDim;
10256 }
10257
10258
10259
10260 static bool classof(const Attr *A) { return A->getKind() == attr::WorkGroupSizeHint; }
10261};
10262
10263class X86ForceAlignArgPointerAttr : public InheritableAttr {
10264public:
10265 static X86ForceAlignArgPointerAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
10266 auto *A = new (Ctx) X86ForceAlignArgPointerAttr(Loc, Ctx, 0);
10267 A->setImplicit(true);
10268 return A;
10269 }
10270
10271 X86ForceAlignArgPointerAttr(SourceRange R, ASTContext &Ctx
10272 , unsigned SI
10273 )
10274 : InheritableAttr(attr::X86ForceAlignArgPointer, R, SI, false, false)
10275 {
10276 }
10277
10278 X86ForceAlignArgPointerAttr *clone(ASTContext &C) const;
10279 void printPretty(raw_ostream &OS,
10280 const PrintingPolicy &Policy) const;
10281 const char *getSpelling() const;
10282
10283
10284 static bool classof(const Attr *A) { return A->getKind() == attr::X86ForceAlignArgPointer; }
10285};
10286
10287class XRayInstrumentAttr : public InheritableAttr {
10288public:
10289 enum Spelling {
10290 GNU_xray_always_instrument = 0,
10291 CXX11_clang_xray_always_instrument = 1,
10292 C2x_clang_xray_always_instrument = 2,
10293 GNU_xray_never_instrument = 3,
10294 CXX11_clang_xray_never_instrument = 4,
10295 C2x_clang_xray_never_instrument = 5
10296 };
10297
10298 static XRayInstrumentAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
10299 auto *A = new (Ctx) XRayInstrumentAttr(Loc, Ctx, S);
10300 A->setImplicit(true);
10301 return A;
10302 }
10303
10304 XRayInstrumentAttr(SourceRange R, ASTContext &Ctx
10305 , unsigned SI
10306 )
10307 : InheritableAttr(attr::XRayInstrument, R, SI, false, false)
10308 {
10309 }
10310
10311 XRayInstrumentAttr *clone(ASTContext &C) const;
10312 void printPretty(raw_ostream &OS,
10313 const PrintingPolicy &Policy) const;
10314 const char *getSpelling() const;
10315 Spelling getSemanticSpelling() const {
10316 switch (SpellingListIndex) {
10317 default: llvm_unreachable("Unknown spelling list index")::llvm::llvm_unreachable_internal("Unknown spelling list index"
, "/build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include/clang/AST/Attrs.inc"
, 10317)
;
10318 case 0: return GNU_xray_always_instrument;
10319 case 1: return CXX11_clang_xray_always_instrument;
10320 case 2: return C2x_clang_xray_always_instrument;
10321 case 3: return GNU_xray_never_instrument;
10322 case 4: return CXX11_clang_xray_never_instrument;
10323 case 5: return C2x_clang_xray_never_instrument;
10324 }
10325 }
10326 bool alwaysXRayInstrument() const { return SpellingListIndex == 0 ||
10327 SpellingListIndex == 1 ||
10328 SpellingListIndex == 2; }
10329 bool neverXRayInstrument() const { return SpellingListIndex == 3 ||
10330 SpellingListIndex == 4 ||
10331 SpellingListIndex == 5; }
10332
10333
10334 static bool classof(const Attr *A) { return A->getKind() == attr::XRayInstrument; }
10335};
10336
10337class XRayLogArgsAttr : public InheritableAttr {
10338unsigned argumentCount;
10339
10340public:
10341 static XRayLogArgsAttr *CreateImplicit(ASTContext &Ctx, unsigned ArgumentCount, SourceRange Loc = SourceRange()) {
10342 auto *A = new (Ctx) XRayLogArgsAttr(Loc, Ctx, ArgumentCount, 0);
10343 A->setImplicit(true);
10344 return A;
10345 }
10346
10347 XRayLogArgsAttr(SourceRange R, ASTContext &Ctx
10348 , unsigned ArgumentCount
10349 , unsigned SI
10350 )
10351 : InheritableAttr(attr::XRayLogArgs, R, SI, false, false)
10352 , argumentCount(ArgumentCount)
10353 {
10354 }
10355
10356 XRayLogArgsAttr *clone(ASTContext &C) const;
10357 void printPretty(raw_ostream &OS,
10358 const PrintingPolicy &Policy) const;
10359 const char *getSpelling() const;
10360 unsigned getArgumentCount() const {
10361 return argumentCount;
10362 }
10363
10364
10365
10366 static bool classof(const Attr *A) { return A->getKind() == attr::XRayLogArgs; }
10367};
10368
10369#endif // LLVM_CLANG_ATTR_CLASSES_INC