1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "CGCall.h" |
15 | #include "ABIInfo.h" |
16 | #include "CGBlocks.h" |
17 | #include "CGCXXABI.h" |
18 | #include "CGCleanup.h" |
19 | #include "CodeGenFunction.h" |
20 | #include "CodeGenModule.h" |
21 | #include "TargetInfo.h" |
22 | #include "clang/AST/Decl.h" |
23 | #include "clang/AST/DeclCXX.h" |
24 | #include "clang/AST/DeclObjC.h" |
25 | #include "clang/Basic/CodeGenOptions.h" |
26 | #include "clang/Basic/TargetBuiltins.h" |
27 | #include "clang/Basic/TargetInfo.h" |
28 | #include "clang/CodeGen/CGFunctionInfo.h" |
29 | #include "clang/CodeGen/SwiftCallingConv.h" |
30 | #include "llvm/ADT/StringExtras.h" |
31 | #include "llvm/Transforms/Utils/Local.h" |
32 | #include "llvm/Analysis/ValueTracking.h" |
33 | #include "llvm/IR/Attributes.h" |
34 | #include "llvm/IR/CallingConv.h" |
35 | #include "llvm/IR/DataLayout.h" |
36 | #include "llvm/IR/InlineAsm.h" |
37 | #include "llvm/IR/IntrinsicInst.h" |
38 | #include "llvm/IR/Intrinsics.h" |
39 | using namespace clang; |
40 | using namespace CodeGen; |
41 | |
42 | |
43 | |
44 | unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) { |
45 | switch (CC) { |
46 | default: return llvm::CallingConv::C; |
47 | case CC_X86StdCall: return llvm::CallingConv::X86_StdCall; |
48 | case CC_X86FastCall: return llvm::CallingConv::X86_FastCall; |
49 | case CC_X86RegCall: return llvm::CallingConv::X86_RegCall; |
50 | case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall; |
51 | case CC_Win64: return llvm::CallingConv::Win64; |
52 | case CC_X86_64SysV: return llvm::CallingConv::X86_64_SysV; |
53 | case CC_AAPCS: return llvm::CallingConv::ARM_AAPCS; |
54 | case CC_AAPCS_VFP: return llvm::CallingConv::ARM_AAPCS_VFP; |
55 | case CC_IntelOclBicc: return llvm::CallingConv::Intel_OCL_BI; |
56 | |
57 | case CC_X86Pascal: return llvm::CallingConv::C; |
58 | |
59 | case CC_X86VectorCall: return llvm::CallingConv::X86_VectorCall; |
60 | case CC_AArch64VectorCall: return llvm::CallingConv::AArch64_VectorCall; |
61 | case CC_SpirFunction: return llvm::CallingConv::SPIR_FUNC; |
62 | case CC_OpenCLKernel: return CGM.getTargetCodeGenInfo().getOpenCLKernelCallingConv(); |
63 | case CC_PreserveMost: return llvm::CallingConv::PreserveMost; |
64 | case CC_PreserveAll: return llvm::CallingConv::PreserveAll; |
65 | case CC_Swift: return llvm::CallingConv::Swift; |
66 | } |
67 | } |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | CanQualType CodeGenTypes::DeriveThisType(const CXXRecordDecl *RD, |
74 | const CXXMethodDecl *MD) { |
75 | QualType RecTy; |
76 | if (RD) |
77 | RecTy = Context.getTagDeclType(RD)->getCanonicalTypeInternal(); |
78 | else |
79 | RecTy = Context.VoidTy; |
80 | |
81 | if (MD) |
82 | RecTy = Context.getAddrSpaceQualType(RecTy, MD->getMethodQualifiers().getAddressSpace()); |
83 | return Context.getPointerType(CanQualType::CreateUnsafe(RecTy)); |
84 | } |
85 | |
86 | |
87 | static CanQual<FunctionProtoType> GetFormalType(const CXXMethodDecl *MD) { |
88 | return MD->getType()->getCanonicalTypeUnqualified() |
89 | .getAs<FunctionProtoType>(); |
90 | } |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | static CanQualType GetReturnType(QualType RetTy) { |
97 | return RetTy->getCanonicalTypeUnqualified().getUnqualifiedType(); |
98 | } |
99 | |
100 | |
101 | |
102 | const CGFunctionInfo & |
103 | CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) { |
104 | |
105 | |
106 | return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(), |
107 | , |
108 | , None, |
109 | FTNP->getExtInfo(), {}, RequiredArgs(0)); |
110 | } |
111 | |
112 | static void addExtParameterInfosForCall( |
113 | llvm::SmallVectorImpl<FunctionProtoType::ExtParameterInfo> ¶mInfos, |
114 | const FunctionProtoType *proto, |
115 | unsigned prefixArgs, |
116 | unsigned totalArgs) { |
117 | hasExtParameterInfos()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 117, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(proto->hasExtParameterInfos()); |
118 | assert(paramInfos.size() <= prefixArgs); |
119 | getNumParams() + prefixArgs <= totalArgs", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 119, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(proto->getNumParams() + prefixArgs <= totalArgs); |
120 | |
121 | paramInfos.reserve(totalArgs); |
122 | |
123 | |
124 | paramInfos.resize(prefixArgs); |
125 | |
126 | |
127 | for (const auto &ParamInfo : proto->getExtParameterInfos()) { |
128 | paramInfos.push_back(ParamInfo); |
129 | |
130 | if (ParamInfo.hasPassObjectSize()) |
131 | paramInfos.emplace_back(); |
132 | } |
133 | |
134 | (0) . __assert_fail ("paramInfos.size() <= totalArgs && \"Did we forget to insert pass_object_size args?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 135, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(paramInfos.size() <= totalArgs && |
135 | (0) . __assert_fail ("paramInfos.size() <= totalArgs && \"Did we forget to insert pass_object_size args?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 135, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Did we forget to insert pass_object_size args?"); |
136 | |
137 | paramInfos.resize(totalArgs); |
138 | } |
139 | |
140 | |
141 | |
142 | static void appendParameterTypes(const CodeGenTypes &CGT, |
143 | SmallVectorImpl<CanQualType> &prefix, |
144 | SmallVectorImpl<FunctionProtoType::ExtParameterInfo> ¶mInfos, |
145 | CanQual<FunctionProtoType> FPT) { |
146 | |
147 | if (!FPT->hasExtParameterInfos()) { |
148 | (0) . __assert_fail ("paramInfos.empty() && \"We have paramInfos, but the prototype doesn't?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 149, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(paramInfos.empty() && |
149 | (0) . __assert_fail ("paramInfos.empty() && \"We have paramInfos, but the prototype doesn't?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 149, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "We have paramInfos, but the prototype doesn't?"); |
150 | prefix.append(FPT->param_type_begin(), FPT->param_type_end()); |
151 | return; |
152 | } |
153 | |
154 | unsigned PrefixSize = prefix.size(); |
155 | |
156 | |
157 | |
158 | prefix.reserve(prefix.size() + FPT->getNumParams()); |
159 | |
160 | auto ExtInfos = FPT->getExtParameterInfos(); |
161 | getNumParams()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 161, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ExtInfos.size() == FPT->getNumParams()); |
162 | for (unsigned I = 0, E = FPT->getNumParams(); I != E; ++I) { |
163 | prefix.push_back(FPT->getParamType(I)); |
164 | if (ExtInfos[I].hasPassObjectSize()) |
165 | prefix.push_back(CGT.getContext().getSizeType()); |
166 | } |
167 | |
168 | addExtParameterInfosForCall(paramInfos, FPT.getTypePtr(), PrefixSize, |
169 | prefix.size()); |
170 | } |
171 | |
172 | |
173 | |
174 | static const CGFunctionInfo & |
175 | arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod, |
176 | SmallVectorImpl<CanQualType> &prefix, |
177 | CanQual<FunctionProtoType> FTP) { |
178 | SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos; |
179 | RequiredArgs Required = RequiredArgs::forPrototypePlus(FTP, prefix.size()); |
180 | |
181 | appendParameterTypes(CGT, prefix, paramInfos, FTP); |
182 | CanQualType resultType = FTP->getReturnType().getUnqualifiedType(); |
183 | |
184 | return CGT.arrangeLLVMFunctionInfo(resultType, instanceMethod, |
185 | , prefix, |
186 | FTP->getExtInfo(), paramInfos, |
187 | Required); |
188 | } |
189 | |
190 | |
191 | |
192 | const CGFunctionInfo & |
193 | CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP) { |
194 | SmallVector<CanQualType, 16> argTypes; |
195 | return ::arrangeLLVMFunctionInfo(*this, , argTypes, |
196 | FTP); |
197 | } |
198 | |
199 | static CallingConv getCallingConventionForDecl(const Decl *D, bool IsWindows) { |
200 | |
201 | if (D->hasAttr<StdCallAttr>()) |
202 | return CC_X86StdCall; |
203 | |
204 | if (D->hasAttr<FastCallAttr>()) |
205 | return CC_X86FastCall; |
206 | |
207 | if (D->hasAttr<RegCallAttr>()) |
208 | return CC_X86RegCall; |
209 | |
210 | if (D->hasAttr<ThisCallAttr>()) |
211 | return CC_X86ThisCall; |
212 | |
213 | if (D->hasAttr<VectorCallAttr>()) |
214 | return CC_X86VectorCall; |
215 | |
216 | if (D->hasAttr<PascalAttr>()) |
217 | return CC_X86Pascal; |
218 | |
219 | if (PcsAttr *PCS = D->getAttr<PcsAttr>()) |
220 | return (PCS->getPCS() == PcsAttr::AAPCS ? CC_AAPCS : CC_AAPCS_VFP); |
221 | |
222 | if (D->hasAttr<AArch64VectorPcsAttr>()) |
223 | return CC_AArch64VectorCall; |
224 | |
225 | if (D->hasAttr<IntelOclBiccAttr>()) |
226 | return CC_IntelOclBicc; |
227 | |
228 | if (D->hasAttr<MSABIAttr>()) |
229 | return IsWindows ? CC_C : CC_Win64; |
230 | |
231 | if (D->hasAttr<SysVABIAttr>()) |
232 | return IsWindows ? CC_X86_64SysV : CC_C; |
233 | |
234 | if (D->hasAttr<PreserveMostAttr>()) |
235 | return CC_PreserveMost; |
236 | |
237 | if (D->hasAttr<PreserveAllAttr>()) |
238 | return CC_PreserveAll; |
239 | |
240 | return CC_C; |
241 | } |
242 | |
243 | |
244 | |
245 | |
246 | |
247 | |
248 | |
249 | const CGFunctionInfo & |
250 | CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD, |
251 | const FunctionProtoType *FTP, |
252 | const CXXMethodDecl *MD) { |
253 | SmallVector<CanQualType, 16> argTypes; |
254 | |
255 | |
256 | argTypes.push_back(DeriveThisType(RD, MD)); |
257 | |
258 | return ::arrangeLLVMFunctionInfo( |
259 | *this, true, argTypes, |
260 | FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>()); |
261 | } |
262 | |
263 | |
264 | static void setCUDAKernelCallingConvention(CanQualType &FTy, CodeGenModule &CGM, |
265 | const FunctionDecl *FD) { |
266 | if (FD->hasAttr<CUDAGlobalAttr>()) { |
267 | const FunctionType *FT = FTy->getAs<FunctionType>(); |
268 | CGM.getTargetCodeGenInfo().setCUDAKernelCallingConvention(FT); |
269 | FTy = FT->getCanonicalTypeUnqualified(); |
270 | } |
271 | } |
272 | |
273 | |
274 | |
275 | |
276 | |
277 | const CGFunctionInfo & |
278 | CodeGenTypes::arrangeCXXMethodDeclaration(const CXXMethodDecl *MD) { |
279 | (0) . __assert_fail ("!isa(MD) && \"wrong method for constructors!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 279, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isa<CXXConstructorDecl>(MD) && "wrong method for constructors!"); |
280 | (0) . __assert_fail ("!isa(MD) && \"wrong method for destructors!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 280, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isa<CXXDestructorDecl>(MD) && "wrong method for destructors!"); |
281 | |
282 | CanQualType FT = GetFormalType(MD).getAs<Type>(); |
283 | setCUDAKernelCallingConvention(FT, CGM, MD); |
284 | auto prototype = FT.getAs<FunctionProtoType>(); |
285 | |
286 | if (MD->isInstance()) { |
287 | |
288 | const CXXRecordDecl *ThisType = TheCXXABI.getThisArgumentTypeForMethod(MD); |
289 | return arrangeCXXMethodType(ThisType, prototype.getTypePtr(), MD); |
290 | } |
291 | |
292 | return arrangeFreeFunctionType(prototype); |
293 | } |
294 | |
295 | bool CodeGenTypes::inheritingCtorHasParams( |
296 | const InheritedConstructor &Inherited, CXXCtorType Type) { |
297 | |
298 | |
299 | return Type == Ctor_Complete || |
300 | !Inherited.getShadowDecl()->constructsVirtualBase() || |
301 | !Target.getCXXABI().hasConstructorVariants(); |
302 | } |
303 | |
304 | const CGFunctionInfo & |
305 | CodeGenTypes::arrangeCXXStructorDeclaration(GlobalDecl GD) { |
306 | auto *MD = cast<CXXMethodDecl>(GD.getDecl()); |
307 | |
308 | SmallVector<CanQualType, 16> argTypes; |
309 | SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos; |
310 | argTypes.push_back(DeriveThisType(MD->getParent(), MD)); |
311 | |
312 | bool PassParams = true; |
313 | |
314 | if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) { |
315 | |
316 | |
317 | if (auto Inherited = CD->getInheritedConstructor()) |
318 | PassParams = inheritingCtorHasParams(Inherited, GD.getCtorType()); |
319 | } |
320 | |
321 | CanQual<FunctionProtoType> FTP = GetFormalType(MD); |
322 | |
323 | |
324 | if (PassParams) |
325 | appendParameterTypes(*this, argTypes, paramInfos, FTP); |
326 | |
327 | CGCXXABI::AddedStructorArgs AddedArgs = |
328 | TheCXXABI.buildStructorSignature(GD, argTypes); |
329 | if (!paramInfos.empty()) { |
330 | |
331 | if (AddedArgs.Prefix) |
332 | paramInfos.insert(paramInfos.begin() + 1, AddedArgs.Prefix, |
333 | FunctionProtoType::ExtParameterInfo{}); |
334 | if (AddedArgs.Suffix) |
335 | paramInfos.append(AddedArgs.Suffix, |
336 | FunctionProtoType::ExtParameterInfo{}); |
337 | } |
338 | |
339 | RequiredArgs required = |
340 | (PassParams && MD->isVariadic() ? RequiredArgs(argTypes.size()) |
341 | : RequiredArgs::All); |
342 | |
343 | FunctionType::ExtInfo extInfo = FTP->getExtInfo(); |
344 | CanQualType resultType = TheCXXABI.HasThisReturn(GD) |
345 | ? argTypes.front() |
346 | : TheCXXABI.hasMostDerivedReturn(GD) |
347 | ? CGM.getContext().VoidPtrTy |
348 | : Context.VoidTy; |
349 | return arrangeLLVMFunctionInfo(resultType, , |
350 | , argTypes, extInfo, |
351 | paramInfos, required); |
352 | } |
353 | |
354 | static SmallVector<CanQualType, 16> |
355 | getArgTypesForCall(ASTContext &ctx, const CallArgList &args) { |
356 | SmallVector<CanQualType, 16> argTypes; |
357 | for (auto &arg : args) |
358 | argTypes.push_back(ctx.getCanonicalParamType(arg.Ty)); |
359 | return argTypes; |
360 | } |
361 | |
362 | static SmallVector<CanQualType, 16> |
363 | getArgTypesForDeclaration(ASTContext &ctx, const FunctionArgList &args) { |
364 | SmallVector<CanQualType, 16> argTypes; |
365 | for (auto &arg : args) |
366 | argTypes.push_back(ctx.getCanonicalParamType(arg->getType())); |
367 | return argTypes; |
368 | } |
369 | |
370 | static llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> |
371 | getExtParameterInfosForCall(const FunctionProtoType *proto, |
372 | unsigned prefixArgs, unsigned totalArgs) { |
373 | llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> result; |
374 | if (proto->hasExtParameterInfos()) { |
375 | addExtParameterInfosForCall(result, proto, prefixArgs, totalArgs); |
376 | } |
377 | return result; |
378 | } |
379 | |
380 | |
381 | |
382 | |
383 | |
384 | |
385 | |
386 | |
387 | |
388 | const CGFunctionInfo & |
389 | CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args, |
390 | const CXXConstructorDecl *D, |
391 | CXXCtorType CtorKind, |
392 | unsigned , |
393 | unsigned , |
394 | bool PassProtoArgs) { |
395 | |
396 | SmallVector<CanQualType, 16> ArgTypes; |
397 | for (const auto &Arg : args) |
398 | ArgTypes.push_back(Context.getCanonicalParamType(Arg.Ty)); |
399 | |
400 | |
401 | unsigned TotalPrefixArgs = 1 + ExtraPrefixArgs; |
402 | |
403 | CanQual<FunctionProtoType> FPT = GetFormalType(D); |
404 | RequiredArgs Required = PassProtoArgs |
405 | ? RequiredArgs::forPrototypePlus( |
406 | FPT, TotalPrefixArgs + ExtraSuffixArgs) |
407 | : RequiredArgs::All; |
408 | |
409 | GlobalDecl GD(D, CtorKind); |
410 | CanQualType ResultType = TheCXXABI.HasThisReturn(GD) |
411 | ? ArgTypes.front() |
412 | : TheCXXABI.hasMostDerivedReturn(GD) |
413 | ? CGM.getContext().VoidPtrTy |
414 | : Context.VoidTy; |
415 | |
416 | FunctionType::ExtInfo Info = FPT->getExtInfo(); |
417 | llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> ParamInfos; |
418 | |
419 | |
420 | if (PassProtoArgs && FPT->hasExtParameterInfos()) { |
421 | |
422 | addExtParameterInfosForCall(ParamInfos, FPT.getTypePtr(), TotalPrefixArgs, |
423 | ArgTypes.size()); |
424 | } |
425 | return arrangeLLVMFunctionInfo(ResultType, , |
426 | , ArgTypes, Info, |
427 | ParamInfos, Required); |
428 | } |
429 | |
430 | |
431 | |
432 | const CGFunctionInfo & |
433 | CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) { |
434 | if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) |
435 | if (MD->isInstance()) |
436 | return arrangeCXXMethodDeclaration(MD); |
437 | |
438 | CanQualType FTy = FD->getType()->getCanonicalTypeUnqualified(); |
439 | |
440 | (FTy)", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 440, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<FunctionType>(FTy)); |
441 | setCUDAKernelCallingConvention(FTy, CGM, FD); |
442 | |
443 | |
444 | |
445 | if (CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>()) { |
446 | return arrangeLLVMFunctionInfo( |
447 | noProto->getReturnType(), , |
448 | , None, noProto->getExtInfo(), {},RequiredArgs::All); |
449 | } |
450 | |
451 | return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>()); |
452 | } |
453 | |
454 | |
455 | |
456 | const CGFunctionInfo & |
457 | CodeGenTypes::arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD) { |
458 | |
459 | |
460 | return arrangeObjCMessageSendSignature(MD, MD->getSelfDecl()->getType()); |
461 | } |
462 | |
463 | |
464 | |
465 | |
466 | |
467 | |
468 | |
469 | const CGFunctionInfo & |
470 | CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, |
471 | QualType receiverType) { |
472 | SmallVector<CanQualType, 16> argTys; |
473 | SmallVector<FunctionProtoType::ExtParameterInfo, 4> extParamInfos(2); |
474 | argTys.push_back(Context.getCanonicalParamType(receiverType)); |
475 | argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType())); |
476 | |
477 | for (const auto *I : MD->parameters()) { |
478 | argTys.push_back(Context.getCanonicalParamType(I->getType())); |
479 | auto extParamInfo = FunctionProtoType::ExtParameterInfo().withIsNoEscape( |
480 | I->hasAttr<NoEscapeAttr>()); |
481 | extParamInfos.push_back(extParamInfo); |
482 | } |
483 | |
484 | FunctionType::ExtInfo einfo; |
485 | bool IsWindows = getContext().getTargetInfo().getTriple().isOSWindows(); |
486 | einfo = einfo.withCallingConv(getCallingConventionForDecl(MD, IsWindows)); |
487 | |
488 | if (getContext().getLangOpts().ObjCAutoRefCount && |
489 | MD->hasAttr<NSReturnsRetainedAttr>()) |
490 | einfo = einfo.withProducesResult(true); |
491 | |
492 | RequiredArgs required = |
493 | (MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All); |
494 | |
495 | return arrangeLLVMFunctionInfo( |
496 | GetReturnType(MD->getReturnType()), , |
497 | , argTys, einfo, extParamInfos, required); |
498 | } |
499 | |
500 | const CGFunctionInfo & |
501 | CodeGenTypes::arrangeUnprototypedObjCMessageSend(QualType returnType, |
502 | const CallArgList &args) { |
503 | auto argTypes = getArgTypesForCall(Context, args); |
504 | FunctionType::ExtInfo einfo; |
505 | |
506 | return arrangeLLVMFunctionInfo( |
507 | GetReturnType(returnType), , |
508 | , argTypes, einfo, {}, RequiredArgs::All); |
509 | } |
510 | |
511 | const CGFunctionInfo & |
512 | CodeGenTypes::arrangeGlobalDeclaration(GlobalDecl GD) { |
513 | |
514 | const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); |
515 | |
516 | if (isa<CXXConstructorDecl>(GD.getDecl()) || |
517 | isa<CXXDestructorDecl>(GD.getDecl())) |
518 | return arrangeCXXStructorDeclaration(GD); |
519 | |
520 | return arrangeFunctionDeclaration(FD); |
521 | } |
522 | |
523 | |
524 | |
525 | |
526 | |
527 | |
528 | const CGFunctionInfo & |
529 | CodeGenTypes::arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD) { |
530 | (0) . __assert_fail ("MD->isVirtual() && \"only methods have thunks\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 530, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(MD->isVirtual() && "only methods have thunks"); |
531 | CanQual<FunctionProtoType> FTP = GetFormalType(MD); |
532 | CanQualType ArgTys[] = {DeriveThisType(MD->getParent(), MD)}; |
533 | return arrangeLLVMFunctionInfo(Context.VoidTy, , |
534 | , ArgTys, |
535 | FTP->getExtInfo(), {}, RequiredArgs(1)); |
536 | } |
537 | |
538 | const CGFunctionInfo & |
539 | CodeGenTypes::arrangeMSCtorClosure(const CXXConstructorDecl *CD, |
540 | CXXCtorType CT) { |
541 | assert(CT == Ctor_CopyingClosure || CT == Ctor_DefaultClosure); |
542 | |
543 | CanQual<FunctionProtoType> FTP = GetFormalType(CD); |
544 | SmallVector<CanQualType, 2> ArgTys; |
545 | const CXXRecordDecl *RD = CD->getParent(); |
546 | ArgTys.push_back(DeriveThisType(RD, CD)); |
547 | if (CT == Ctor_CopyingClosure) |
548 | ArgTys.push_back(*FTP->param_type_begin()); |
549 | if (RD->getNumVBases() > 0) |
550 | ArgTys.push_back(Context.IntTy); |
551 | CallingConv CC = Context.getDefaultCallingConvention( |
552 | , ); |
553 | return arrangeLLVMFunctionInfo(Context.VoidTy, , |
554 | , ArgTys, |
555 | FunctionType::ExtInfo(CC), {}, |
556 | RequiredArgs::All); |
557 | } |
558 | |
559 | |
560 | |
561 | static const CGFunctionInfo & |
562 | arrangeFreeFunctionLikeCall(CodeGenTypes &CGT, |
563 | CodeGenModule &CGM, |
564 | const CallArgList &args, |
565 | const FunctionType *fnType, |
566 | unsigned , |
567 | bool chainCall) { |
568 | = numExtraRequiredArgs", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 568, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(args.size() >= numExtraRequiredArgs); |
569 | |
570 | llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos; |
571 | |
572 | |
573 | RequiredArgs required = RequiredArgs::All; |
574 | |
575 | |
576 | |
577 | if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fnType)) { |
578 | if (proto->isVariadic()) |
579 | required = RequiredArgs::forPrototypePlus(proto, numExtraRequiredArgs); |
580 | |
581 | if (proto->hasExtParameterInfos()) |
582 | addExtParameterInfosForCall(paramInfos, proto, numExtraRequiredArgs, |
583 | args.size()); |
584 | |
585 | |
586 | |
587 | |
588 | |
589 | } else if (CGM.getTargetCodeGenInfo() |
590 | .isNoProtoCallVariadic(args, |
591 | cast<FunctionNoProtoType>(fnType))) { |
592 | required = RequiredArgs(args.size()); |
593 | } |
594 | |
595 | |
596 | SmallVector<CanQualType, 16> argTypes; |
597 | for (const auto &arg : args) |
598 | argTypes.push_back(CGT.getContext().getCanonicalParamType(arg.Ty)); |
599 | return CGT.arrangeLLVMFunctionInfo(GetReturnType(fnType->getReturnType()), |
600 | , chainCall, |
601 | argTypes, fnType->getExtInfo(), paramInfos, |
602 | required); |
603 | } |
604 | |
605 | |
606 | |
607 | |
608 | |
609 | const CGFunctionInfo & |
610 | CodeGenTypes::arrangeFreeFunctionCall(const CallArgList &args, |
611 | const FunctionType *fnType, |
612 | bool chainCall) { |
613 | return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType, |
614 | chainCall ? 1 : 0, chainCall); |
615 | } |
616 | |
617 | |
618 | |
619 | const CGFunctionInfo & |
620 | CodeGenTypes::arrangeBlockFunctionCall(const CallArgList &args, |
621 | const FunctionType *fnType) { |
622 | return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType, 1, |
623 | ); |
624 | } |
625 | |
626 | const CGFunctionInfo & |
627 | CodeGenTypes::arrangeBlockFunctionDeclaration(const FunctionProtoType *proto, |
628 | const FunctionArgList ¶ms) { |
629 | auto paramInfos = getExtParameterInfosForCall(proto, 1, params.size()); |
630 | auto argTypes = getArgTypesForDeclaration(Context, params); |
631 | |
632 | return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()), |
633 | false, false, |
634 | argTypes, proto->getExtInfo(), paramInfos, |
635 | RequiredArgs::forPrototypePlus(proto, 1)); |
636 | } |
637 | |
638 | const CGFunctionInfo & |
639 | CodeGenTypes::arrangeBuiltinFunctionCall(QualType resultType, |
640 | const CallArgList &args) { |
641 | |
642 | SmallVector<CanQualType, 16> argTypes; |
643 | for (const auto &Arg : args) |
644 | argTypes.push_back(Context.getCanonicalParamType(Arg.Ty)); |
645 | return arrangeLLVMFunctionInfo( |
646 | GetReturnType(resultType), , |
647 | , argTypes, FunctionType::ExtInfo(), |
648 | {}, RequiredArgs::All); |
649 | } |
650 | |
651 | const CGFunctionInfo & |
652 | CodeGenTypes::arrangeBuiltinFunctionDeclaration(QualType resultType, |
653 | const FunctionArgList &args) { |
654 | auto argTypes = getArgTypesForDeclaration(Context, args); |
655 | |
656 | return arrangeLLVMFunctionInfo( |
657 | GetReturnType(resultType), , , |
658 | argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All); |
659 | } |
660 | |
661 | const CGFunctionInfo & |
662 | CodeGenTypes::arrangeBuiltinFunctionDeclaration(CanQualType resultType, |
663 | ArrayRef<CanQualType> argTypes) { |
664 | return arrangeLLVMFunctionInfo( |
665 | resultType, , , |
666 | argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All); |
667 | } |
668 | |
669 | |
670 | |
671 | |
672 | |
673 | const CGFunctionInfo & |
674 | CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args, |
675 | const FunctionProtoType *proto, |
676 | RequiredArgs required, |
677 | unsigned numPrefixArgs) { |
678 | (0) . __assert_fail ("numPrefixArgs + 1 <= args.size() && \"Emitting a call with less args than the required prefix?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 679, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(numPrefixArgs + 1 <= args.size() && |
679 | (0) . __assert_fail ("numPrefixArgs + 1 <= args.size() && \"Emitting a call with less args than the required prefix?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 679, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Emitting a call with less args than the required prefix?"); |
680 | |
681 | |
682 | auto paramInfos = |
683 | getExtParameterInfosForCall(proto, numPrefixArgs + 1, args.size()); |
684 | |
685 | |
686 | auto argTypes = getArgTypesForCall(Context, args); |
687 | |
688 | FunctionType::ExtInfo info = proto->getExtInfo(); |
689 | return arrangeLLVMFunctionInfo( |
690 | GetReturnType(proto->getReturnType()), , |
691 | , argTypes, info, paramInfos, required); |
692 | } |
693 | |
694 | const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() { |
695 | return arrangeLLVMFunctionInfo( |
696 | getContext().VoidTy, , , |
697 | None, FunctionType::ExtInfo(), {}, RequiredArgs::All); |
698 | } |
699 | |
700 | const CGFunctionInfo & |
701 | CodeGenTypes::arrangeCall(const CGFunctionInfo &signature, |
702 | const CallArgList &args) { |
703 | assert(signature.arg_size() <= args.size()); |
704 | if (signature.arg_size() == args.size()) |
705 | return signature; |
706 | |
707 | SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos; |
708 | auto sigParamInfos = signature.getExtParameterInfos(); |
709 | if (!sigParamInfos.empty()) { |
710 | paramInfos.append(sigParamInfos.begin(), sigParamInfos.end()); |
711 | paramInfos.resize(args.size()); |
712 | } |
713 | |
714 | auto argTypes = getArgTypesForCall(Context, args); |
715 | |
716 | assert(signature.getRequiredArgs().allowsOptionalArgs()); |
717 | return arrangeLLVMFunctionInfo(signature.getReturnType(), |
718 | signature.isInstanceMethod(), |
719 | signature.isChainCall(), |
720 | argTypes, |
721 | signature.getExtInfo(), |
722 | paramInfos, |
723 | signature.getRequiredArgs()); |
724 | } |
725 | |
726 | namespace clang { |
727 | namespace CodeGen { |
728 | void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI); |
729 | } |
730 | } |
731 | |
732 | |
733 | |
734 | |
735 | const CGFunctionInfo & |
736 | CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType, |
737 | bool instanceMethod, |
738 | bool chainCall, |
739 | ArrayRef<CanQualType> argTypes, |
740 | FunctionType::ExtInfo info, |
741 | ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos, |
742 | RequiredArgs required) { |
743 | assert(llvm::all_of(argTypes, |
744 | [](CanQualType T) { return T.isCanonicalAsParam(); })); |
745 | |
746 | |
747 | llvm::FoldingSetNodeID ID; |
748 | CGFunctionInfo::Profile(ID, instanceMethod, chainCall, info, paramInfos, |
749 | required, resultType, argTypes); |
750 | |
751 | void *insertPos = nullptr; |
752 | CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos); |
753 | if (FI) |
754 | return *FI; |
755 | |
756 | unsigned CC = ClangCallConvToLLVMCallConv(info.getCC()); |
757 | |
758 | |
759 | FI = CGFunctionInfo::create(CC, instanceMethod, chainCall, info, |
760 | paramInfos, resultType, argTypes, required); |
761 | FunctionInfos.InsertNode(FI, insertPos); |
762 | |
763 | bool inserted = FunctionsBeingProcessed.insert(FI).second; |
764 | (void)inserted; |
765 | (0) . __assert_fail ("inserted && \"Recursively being processed?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 765, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(inserted && "Recursively being processed?"); |
766 | |
767 | |
768 | if (CC == llvm::CallingConv::SPIR_KERNEL) { |
769 | |
770 | |
771 | computeSPIRKernelABIInfo(CGM, *FI); |
772 | } else if (info.getCC() == CC_Swift) { |
773 | swiftcall::computeABIInfo(CGM, *FI); |
774 | } else { |
775 | getABIInfo().computeInfo(*FI); |
776 | } |
777 | |
778 | |
779 | |
780 | |
781 | ABIArgInfo &retInfo = FI->getReturnInfo(); |
782 | if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == nullptr) |
783 | retInfo.setCoerceToType(ConvertType(FI->getReturnType())); |
784 | |
785 | for (auto &I : FI->arguments()) |
786 | if (I.info.canHaveCoerceToType() && I.info.getCoerceToType() == nullptr) |
787 | I.info.setCoerceToType(ConvertType(I.type)); |
788 | |
789 | bool erased = FunctionsBeingProcessed.erase(FI); (void)erased; |
790 | (0) . __assert_fail ("erased && \"Not in set?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 790, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(erased && "Not in set?"); |
791 | |
792 | return *FI; |
793 | } |
794 | |
795 | CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC, |
796 | bool instanceMethod, |
797 | bool chainCall, |
798 | const FunctionType::ExtInfo &info, |
799 | ArrayRef<ExtParameterInfo> paramInfos, |
800 | CanQualType resultType, |
801 | ArrayRef<CanQualType> argTypes, |
802 | RequiredArgs required) { |
803 | assert(paramInfos.empty() || paramInfos.size() == argTypes.size()); |
804 | assert(!required.allowsOptionalArgs() || |
805 | required.getNumRequiredArgs() <= argTypes.size()); |
806 | |
807 | void *buffer = |
808 | operator new(totalSizeToAlloc<ArgInfo, ExtParameterInfo>( |
809 | argTypes.size() + 1, paramInfos.size())); |
810 | |
811 | CGFunctionInfo *FI = new(buffer) CGFunctionInfo(); |
812 | FI->CallingConvention = llvmCC; |
813 | FI->EffectiveCallingConvention = llvmCC; |
814 | FI->ASTCallingConvention = info.getCC(); |
815 | FI->InstanceMethod = instanceMethod; |
816 | FI->ChainCall = chainCall; |
817 | FI->NoReturn = info.getNoReturn(); |
818 | FI->ReturnsRetained = info.getProducesResult(); |
819 | FI->NoCallerSavedRegs = info.getNoCallerSavedRegs(); |
820 | FI->NoCfCheck = info.getNoCfCheck(); |
821 | FI->Required = required; |
822 | FI->HasRegParm = info.getHasRegParm(); |
823 | FI->RegParm = info.getRegParm(); |
824 | FI->ArgStruct = nullptr; |
825 | FI->ArgStructAlign = 0; |
826 | FI->NumArgs = argTypes.size(); |
827 | FI->HasExtParameterInfos = !paramInfos.empty(); |
828 | FI->getArgsBuffer()[0].type = resultType; |
829 | for (unsigned i = 0, e = argTypes.size(); i != e; ++i) |
830 | FI->getArgsBuffer()[i + 1].type = argTypes[i]; |
831 | for (unsigned i = 0, e = paramInfos.size(); i != e; ++i) |
832 | FI->getExtParameterInfosBuffer()[i] = paramInfos[i]; |
833 | return FI; |
834 | } |
835 | |
836 | |
837 | |
838 | namespace { |
839 | |
840 | |
841 | |
842 | struct TypeExpansion { |
843 | enum TypeExpansionKind { |
844 | |
845 | TEK_ConstantArray, |
846 | |
847 | |
848 | TEK_Record, |
849 | |
850 | TEK_Complex, |
851 | |
852 | TEK_None |
853 | }; |
854 | |
855 | const TypeExpansionKind Kind; |
856 | |
857 | TypeExpansion(TypeExpansionKind K) : Kind(K) {} |
858 | virtual ~TypeExpansion() {} |
859 | }; |
860 | |
861 | struct ConstantArrayExpansion : TypeExpansion { |
862 | QualType EltTy; |
863 | uint64_t NumElts; |
864 | |
865 | ConstantArrayExpansion(QualType EltTy, uint64_t NumElts) |
866 | : TypeExpansion(TEK_ConstantArray), EltTy(EltTy), NumElts(NumElts) {} |
867 | static bool classof(const TypeExpansion *TE) { |
868 | return TE->Kind == TEK_ConstantArray; |
869 | } |
870 | }; |
871 | |
872 | struct RecordExpansion : TypeExpansion { |
873 | SmallVector<const CXXBaseSpecifier *, 1> Bases; |
874 | |
875 | SmallVector<const FieldDecl *, 1> Fields; |
876 | |
877 | RecordExpansion(SmallVector<const CXXBaseSpecifier *, 1> &&Bases, |
878 | SmallVector<const FieldDecl *, 1> &&Fields) |
879 | : TypeExpansion(TEK_Record), Bases(std::move(Bases)), |
880 | Fields(std::move(Fields)) {} |
881 | static bool classof(const TypeExpansion *TE) { |
882 | return TE->Kind == TEK_Record; |
883 | } |
884 | }; |
885 | |
886 | struct ComplexExpansion : TypeExpansion { |
887 | QualType EltTy; |
888 | |
889 | ComplexExpansion(QualType EltTy) : TypeExpansion(TEK_Complex), EltTy(EltTy) {} |
890 | static bool classof(const TypeExpansion *TE) { |
891 | return TE->Kind == TEK_Complex; |
892 | } |
893 | }; |
894 | |
895 | struct NoExpansion : TypeExpansion { |
896 | NoExpansion() : TypeExpansion(TEK_None) {} |
897 | static bool classof(const TypeExpansion *TE) { |
898 | return TE->Kind == TEK_None; |
899 | } |
900 | }; |
901 | } |
902 | |
903 | static std::unique_ptr<TypeExpansion> |
904 | getTypeExpansion(QualType Ty, const ASTContext &Context) { |
905 | if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { |
906 | return llvm::make_unique<ConstantArrayExpansion>( |
907 | AT->getElementType(), AT->getSize().getZExtValue()); |
908 | } |
909 | if (const RecordType *RT = Ty->getAs<RecordType>()) { |
910 | SmallVector<const CXXBaseSpecifier *, 1> Bases; |
911 | SmallVector<const FieldDecl *, 1> Fields; |
912 | const RecordDecl *RD = RT->getDecl(); |
913 | (0) . __assert_fail ("!RD->hasFlexibleArrayMember() && \"Cannot expand structure with flexible array.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 914, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!RD->hasFlexibleArrayMember() && |
914 | (0) . __assert_fail ("!RD->hasFlexibleArrayMember() && \"Cannot expand structure with flexible array.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 914, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Cannot expand structure with flexible array."); |
915 | if (RD->isUnion()) { |
916 | |
917 | |
918 | const FieldDecl *LargestFD = nullptr; |
919 | CharUnits UnionSize = CharUnits::Zero(); |
920 | |
921 | for (const auto *FD : RD->fields()) { |
922 | if (FD->isZeroLengthBitField(Context)) |
923 | continue; |
924 | (0) . __assert_fail ("!FD->isBitField() && \"Cannot expand structure with bit-field members.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 925, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!FD->isBitField() && |
925 | (0) . __assert_fail ("!FD->isBitField() && \"Cannot expand structure with bit-field members.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 925, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Cannot expand structure with bit-field members."); |
926 | CharUnits FieldSize = Context.getTypeSizeInChars(FD->getType()); |
927 | if (UnionSize < FieldSize) { |
928 | UnionSize = FieldSize; |
929 | LargestFD = FD; |
930 | } |
931 | } |
932 | if (LargestFD) |
933 | Fields.push_back(LargestFD); |
934 | } else { |
935 | if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { |
936 | (0) . __assert_fail ("!CXXRD->isDynamicClass() && \"cannot expand vtable pointers in dynamic classes\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 937, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!CXXRD->isDynamicClass() && |
937 | (0) . __assert_fail ("!CXXRD->isDynamicClass() && \"cannot expand vtable pointers in dynamic classes\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 937, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "cannot expand vtable pointers in dynamic classes"); |
938 | for (const CXXBaseSpecifier &BS : CXXRD->bases()) |
939 | Bases.push_back(&BS); |
940 | } |
941 | |
942 | for (const auto *FD : RD->fields()) { |
943 | if (FD->isZeroLengthBitField(Context)) |
944 | continue; |
945 | (0) . __assert_fail ("!FD->isBitField() && \"Cannot expand structure with bit-field members.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 946, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!FD->isBitField() && |
946 | (0) . __assert_fail ("!FD->isBitField() && \"Cannot expand structure with bit-field members.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 946, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Cannot expand structure with bit-field members."); |
947 | Fields.push_back(FD); |
948 | } |
949 | } |
950 | return llvm::make_unique<RecordExpansion>(std::move(Bases), |
951 | std::move(Fields)); |
952 | } |
953 | if (const ComplexType *CT = Ty->getAs<ComplexType>()) { |
954 | return llvm::make_unique<ComplexExpansion>(CT->getElementType()); |
955 | } |
956 | return llvm::make_unique<NoExpansion>(); |
957 | } |
958 | |
959 | static int getExpansionSize(QualType Ty, const ASTContext &Context) { |
960 | auto Exp = getTypeExpansion(Ty, Context); |
961 | if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) { |
962 | return CAExp->NumElts * getExpansionSize(CAExp->EltTy, Context); |
963 | } |
964 | if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) { |
965 | int Res = 0; |
966 | for (auto BS : RExp->Bases) |
967 | Res += getExpansionSize(BS->getType(), Context); |
968 | for (auto FD : RExp->Fields) |
969 | Res += getExpansionSize(FD->getType(), Context); |
970 | return Res; |
971 | } |
972 | if (isa<ComplexExpansion>(Exp.get())) |
973 | return 2; |
974 | (Exp.get())", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 974, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<NoExpansion>(Exp.get())); |
975 | return 1; |
976 | } |
977 | |
978 | void |
979 | CodeGenTypes::getExpandedTypes(QualType Ty, |
980 | SmallVectorImpl<llvm::Type *>::iterator &TI) { |
981 | auto Exp = getTypeExpansion(Ty, Context); |
982 | if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) { |
983 | for (int i = 0, n = CAExp->NumElts; i < n; i++) { |
984 | getExpandedTypes(CAExp->EltTy, TI); |
985 | } |
986 | } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) { |
987 | for (auto BS : RExp->Bases) |
988 | getExpandedTypes(BS->getType(), TI); |
989 | for (auto FD : RExp->Fields) |
990 | getExpandedTypes(FD->getType(), TI); |
991 | } else if (auto CExp = dyn_cast<ComplexExpansion>(Exp.get())) { |
992 | llvm::Type *EltTy = ConvertType(CExp->EltTy); |
993 | *TI++ = EltTy; |
994 | *TI++ = EltTy; |
995 | } else { |
996 | (Exp.get())", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 996, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<NoExpansion>(Exp.get())); |
997 | *TI++ = ConvertType(Ty); |
998 | } |
999 | } |
1000 | |
1001 | static void forConstantArrayExpansion(CodeGenFunction &CGF, |
1002 | ConstantArrayExpansion *CAE, |
1003 | Address BaseAddr, |
1004 | llvm::function_ref<void(Address)> Fn) { |
1005 | CharUnits EltSize = CGF.getContext().getTypeSizeInChars(CAE->EltTy); |
1006 | CharUnits EltAlign = |
1007 | BaseAddr.getAlignment().alignmentOfArrayElement(EltSize); |
1008 | |
1009 | for (int i = 0, n = CAE->NumElts; i < n; i++) { |
1010 | llvm::Value *EltAddr = |
1011 | CGF.Builder.CreateConstGEP2_32(nullptr, BaseAddr.getPointer(), 0, i); |
1012 | Fn(Address(EltAddr, EltAlign)); |
1013 | } |
1014 | } |
1015 | |
1016 | void CodeGenFunction::ExpandTypeFromArgs( |
1017 | QualType Ty, LValue LV, SmallVectorImpl<llvm::Value *>::iterator &AI) { |
1018 | (0) . __assert_fail ("LV.isSimple() && \"Unexpected non-simple lvalue during struct expansion.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 1019, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LV.isSimple() && |
1019 | (0) . __assert_fail ("LV.isSimple() && \"Unexpected non-simple lvalue during struct expansion.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 1019, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Unexpected non-simple lvalue during struct expansion."); |
1020 | |
1021 | auto Exp = getTypeExpansion(Ty, getContext()); |
1022 | if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) { |
1023 | forConstantArrayExpansion(*this, CAExp, LV.getAddress(), |
1024 | [&](Address EltAddr) { |
1025 | LValue LV = MakeAddrLValue(EltAddr, CAExp->EltTy); |
1026 | ExpandTypeFromArgs(CAExp->EltTy, LV, AI); |
1027 | }); |
1028 | } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) { |
1029 | Address This = LV.getAddress(); |
1030 | for (const CXXBaseSpecifier *BS : RExp->Bases) { |
1031 | |
1032 | Address Base = |
1033 | GetAddressOfBaseClass(This, Ty->getAsCXXRecordDecl(), &BS, &BS + 1, |
1034 | , SourceLocation()); |
1035 | LValue SubLV = MakeAddrLValue(Base, BS->getType()); |
1036 | |
1037 | |
1038 | ExpandTypeFromArgs(BS->getType(), SubLV, AI); |
1039 | } |
1040 | for (auto FD : RExp->Fields) { |
1041 | |
1042 | LValue SubLV = EmitLValueForFieldInitialization(LV, FD); |
1043 | ExpandTypeFromArgs(FD->getType(), SubLV, AI); |
1044 | } |
1045 | } else if (isa<ComplexExpansion>(Exp.get())) { |
1046 | auto realValue = *AI++; |
1047 | auto imagValue = *AI++; |
1048 | EmitStoreOfComplex(ComplexPairTy(realValue, imagValue), LV, true); |
1049 | } else { |
1050 | (Exp.get())", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 1050, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<NoExpansion>(Exp.get())); |
1051 | EmitStoreThroughLValue(RValue::get(*AI++), LV); |
1052 | } |
1053 | } |
1054 | |
1055 | void CodeGenFunction::ExpandTypeToArgs( |
1056 | QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy, |
1057 | SmallVectorImpl<llvm::Value *> &IRCallArgs, unsigned &IRCallArgPos) { |
1058 | auto Exp = getTypeExpansion(Ty, getContext()); |
1059 | if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) { |
1060 | Address Addr = Arg.hasLValue() ? Arg.getKnownLValue().getAddress() |
1061 | : Arg.getKnownRValue().getAggregateAddress(); |
1062 | forConstantArrayExpansion( |
1063 | *this, CAExp, Addr, [&](Address EltAddr) { |
1064 | CallArg EltArg = CallArg( |
1065 | convertTempToRValue(EltAddr, CAExp->EltTy, SourceLocation()), |
1066 | CAExp->EltTy); |
1067 | ExpandTypeToArgs(CAExp->EltTy, EltArg, IRFuncTy, IRCallArgs, |
1068 | IRCallArgPos); |
1069 | }); |
1070 | } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) { |
1071 | Address This = Arg.hasLValue() ? Arg.getKnownLValue().getAddress() |
1072 | : Arg.getKnownRValue().getAggregateAddress(); |
1073 | for (const CXXBaseSpecifier *BS : RExp->Bases) { |
1074 | |
1075 | Address Base = |
1076 | GetAddressOfBaseClass(This, Ty->getAsCXXRecordDecl(), &BS, &BS + 1, |
1077 | , SourceLocation()); |
1078 | CallArg BaseArg = CallArg(RValue::getAggregate(Base), BS->getType()); |
1079 | |
1080 | |
1081 | ExpandTypeToArgs(BS->getType(), BaseArg, IRFuncTy, IRCallArgs, |
1082 | IRCallArgPos); |
1083 | } |
1084 | |
1085 | LValue LV = MakeAddrLValue(This, Ty); |
1086 | for (auto FD : RExp->Fields) { |
1087 | CallArg FldArg = |
1088 | CallArg(EmitRValueForField(LV, FD, SourceLocation()), FD->getType()); |
1089 | ExpandTypeToArgs(FD->getType(), FldArg, IRFuncTy, IRCallArgs, |
1090 | IRCallArgPos); |
1091 | } |
1092 | } else if (isa<ComplexExpansion>(Exp.get())) { |
1093 | ComplexPairTy CV = Arg.getKnownRValue().getComplexVal(); |
1094 | IRCallArgs[IRCallArgPos++] = CV.first; |
1095 | IRCallArgs[IRCallArgPos++] = CV.second; |
1096 | } else { |
1097 | (Exp.get())", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 1097, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<NoExpansion>(Exp.get())); |
1098 | auto RV = Arg.getKnownRValue(); |
1099 | (0) . __assert_fail ("RV.isScalar() && \"Unexpected non-scalar rvalue during struct expansion.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 1100, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(RV.isScalar() && |
1100 | (0) . __assert_fail ("RV.isScalar() && \"Unexpected non-scalar rvalue during struct expansion.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 1100, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Unexpected non-scalar rvalue during struct expansion."); |
1101 | |
1102 | |
1103 | llvm::Value *V = RV.getScalarVal(); |
1104 | if (IRCallArgPos < IRFuncTy->getNumParams() && |
1105 | V->getType() != IRFuncTy->getParamType(IRCallArgPos)) |
1106 | V = Builder.CreateBitCast(V, IRFuncTy->getParamType(IRCallArgPos)); |
1107 | |
1108 | IRCallArgs[IRCallArgPos++] = V; |
1109 | } |
1110 | } |
1111 | |
1112 | |
1113 | static Address CreateTempAllocaForCoercion(CodeGenFunction &CGF, llvm::Type *Ty, |
1114 | CharUnits MinAlign) { |
1115 | |
1116 | auto PrefAlign = CGF.CGM.getDataLayout().getPrefTypeAlignment(Ty); |
1117 | CharUnits Align = std::max(MinAlign, CharUnits::fromQuantity(PrefAlign)); |
1118 | |
1119 | return CGF.CreateTempAlloca(Ty, Align); |
1120 | } |
1121 | |
1122 | |
1123 | |
1124 | |
1125 | |
1126 | static Address |
1127 | EnterStructPointerForCoercedAccess(Address SrcPtr, |
1128 | llvm::StructType *SrcSTy, |
1129 | uint64_t DstSize, CodeGenFunction &CGF) { |
1130 | |
1131 | if (SrcSTy->getNumElements() == 0) return SrcPtr; |
1132 | |
1133 | llvm::Type *FirstElt = SrcSTy->getElementType(0); |
1134 | |
1135 | |
1136 | |
1137 | |
1138 | |
1139 | uint64_t FirstEltSize = |
1140 | CGF.CGM.getDataLayout().getTypeStoreSize(FirstElt); |
1141 | if (FirstEltSize < DstSize && |
1142 | FirstEltSize < CGF.CGM.getDataLayout().getTypeStoreSize(SrcSTy)) |
1143 | return SrcPtr; |
1144 | |
1145 | |
1146 | SrcPtr = CGF.Builder.CreateStructGEP(SrcPtr, 0, "coerce.dive"); |
1147 | |
1148 | |
1149 | llvm::Type *SrcTy = SrcPtr.getElementType(); |
1150 | if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) |
1151 | return EnterStructPointerForCoercedAccess(SrcPtr, SrcSTy, DstSize, CGF); |
1152 | |
1153 | return SrcPtr; |
1154 | } |
1155 | |
1156 | |
1157 | |
1158 | |
1159 | |
1160 | |
1161 | |
1162 | |
1163 | static llvm::Value *CoerceIntOrPtrToIntOrPtr(llvm::Value *Val, |
1164 | llvm::Type *Ty, |
1165 | CodeGenFunction &CGF) { |
1166 | if (Val->getType() == Ty) |
1167 | return Val; |
1168 | |
1169 | if (isa<llvm::PointerType>(Val->getType())) { |
1170 | |
1171 | if (isa<llvm::PointerType>(Ty)) |
1172 | return CGF.Builder.CreateBitCast(Val, Ty, "coerce.val"); |
1173 | |
1174 | |
1175 | Val = CGF.Builder.CreatePtrToInt(Val, CGF.IntPtrTy, "coerce.val.pi"); |
1176 | } |
1177 | |
1178 | llvm::Type *DestIntTy = Ty; |
1179 | if (isa<llvm::PointerType>(DestIntTy)) |
1180 | DestIntTy = CGF.IntPtrTy; |
1181 | |
1182 | if (Val->getType() != DestIntTy) { |
1183 | const llvm::DataLayout &DL = CGF.CGM.getDataLayout(); |
1184 | if (DL.isBigEndian()) { |
1185 | |
1186 | |
1187 | uint64_t SrcSize = DL.getTypeSizeInBits(Val->getType()); |
1188 | uint64_t DstSize = DL.getTypeSizeInBits(DestIntTy); |
1189 | |
1190 | if (SrcSize > DstSize) { |
1191 | Val = CGF.Builder.CreateLShr(Val, SrcSize - DstSize, "coerce.highbits"); |
1192 | Val = CGF.Builder.CreateTrunc(Val, DestIntTy, "coerce.val.ii"); |
1193 | } else { |
1194 | Val = CGF.Builder.CreateZExt(Val, DestIntTy, "coerce.val.ii"); |
1195 | Val = CGF.Builder.CreateShl(Val, DstSize - SrcSize, "coerce.highbits"); |
1196 | } |
1197 | } else { |
1198 | |
1199 | Val = CGF.Builder.CreateIntCast(Val, DestIntTy, false, "coerce.val.ii"); |
1200 | } |
1201 | } |
1202 | |
1203 | if (isa<llvm::PointerType>(Ty)) |
1204 | Val = CGF.Builder.CreateIntToPtr(Val, Ty, "coerce.val.ip"); |
1205 | return Val; |
1206 | } |
1207 | |
1208 | |
1209 | |
1210 | |
1211 | |
1212 | |
1213 | |
1214 | |
1215 | |
1216 | |
1217 | static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty, |
1218 | CodeGenFunction &CGF) { |
1219 | llvm::Type *SrcTy = Src.getElementType(); |
1220 | |
1221 | |
1222 | if (SrcTy == Ty) |
1223 | return CGF.Builder.CreateLoad(Src); |
1224 | |
1225 | uint64_t DstSize = CGF.CGM.getDataLayout().getTypeAllocSize(Ty); |
1226 | |
1227 | if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) { |
1228 | Src = EnterStructPointerForCoercedAccess(Src, SrcSTy, DstSize, CGF); |
1229 | SrcTy = Src.getType()->getElementType(); |
1230 | } |
1231 | |
1232 | uint64_t SrcSize = CGF.CGM.getDataLayout().getTypeAllocSize(SrcTy); |
1233 | |
1234 | |
1235 | |
1236 | if ((isa<llvm::IntegerType>(Ty) || isa<llvm::PointerType>(Ty)) && |
1237 | (isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy))) { |
1238 | llvm::Value *Load = CGF.Builder.CreateLoad(Src); |
1239 | return CoerceIntOrPtrToIntOrPtr(Load, Ty, CGF); |
1240 | } |
1241 | |
1242 | |
1243 | if (SrcSize >= DstSize) { |
1244 | |
1245 | |
1246 | |
1247 | |
1248 | |
1249 | |
1250 | Src = CGF.Builder.CreateBitCast(Src, |
1251 | Ty->getPointerTo(Src.getAddressSpace())); |
1252 | return CGF.Builder.CreateLoad(Src); |
1253 | } |
1254 | |
1255 | |
1256 | Address Tmp = CreateTempAllocaForCoercion(CGF, Ty, Src.getAlignment()); |
1257 | Address Casted = CGF.Builder.CreateElementBitCast(Tmp,CGF.Int8Ty); |
1258 | Address SrcCasted = CGF.Builder.CreateElementBitCast(Src,CGF.Int8Ty); |
1259 | CGF.Builder.CreateMemCpy(Casted, SrcCasted, |
1260 | llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize), |
1261 | false); |
1262 | return CGF.Builder.CreateLoad(Tmp); |
1263 | } |
1264 | |
1265 | |
1266 | |
1267 | |
1268 | |
1269 | static void BuildAggStore(CodeGenFunction &CGF, llvm::Value *Val, |
1270 | Address Dest, bool DestIsVolatile) { |
1271 | |
1272 | if (llvm::StructType *STy = |
1273 | dyn_cast<llvm::StructType>(Val->getType())) { |
1274 | for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { |
1275 | Address EltPtr = CGF.Builder.CreateStructGEP(Dest, i); |
1276 | llvm::Value *Elt = CGF.Builder.CreateExtractValue(Val, i); |
1277 | CGF.Builder.CreateStore(Elt, EltPtr, DestIsVolatile); |
1278 | } |
1279 | } else { |
1280 | CGF.Builder.CreateStore(Val, Dest, DestIsVolatile); |
1281 | } |
1282 | } |
1283 | |
1284 | |
1285 | |
1286 | |
1287 | |
1288 | |
1289 | |
1290 | static void CreateCoercedStore(llvm::Value *Src, |
1291 | Address Dst, |
1292 | bool DstIsVolatile, |
1293 | CodeGenFunction &CGF) { |
1294 | llvm::Type *SrcTy = Src->getType(); |
1295 | llvm::Type *DstTy = Dst.getType()->getElementType(); |
1296 | if (SrcTy == DstTy) { |
1297 | CGF.Builder.CreateStore(Src, Dst, DstIsVolatile); |
1298 | return; |
1299 | } |
1300 | |
1301 | uint64_t SrcSize = CGF.CGM.getDataLayout().getTypeAllocSize(SrcTy); |
1302 | |
1303 | if (llvm::StructType *DstSTy = dyn_cast<llvm::StructType>(DstTy)) { |
1304 | Dst = EnterStructPointerForCoercedAccess(Dst, DstSTy, SrcSize, CGF); |
1305 | DstTy = Dst.getType()->getElementType(); |
1306 | } |
1307 | |
1308 | |
1309 | |
1310 | if ((isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy)) && |
1311 | (isa<llvm::IntegerType>(DstTy) || isa<llvm::PointerType>(DstTy))) { |
1312 | Src = CoerceIntOrPtrToIntOrPtr(Src, DstTy, CGF); |
1313 | CGF.Builder.CreateStore(Src, Dst, DstIsVolatile); |
1314 | return; |
1315 | } |
1316 | |
1317 | uint64_t DstSize = CGF.CGM.getDataLayout().getTypeAllocSize(DstTy); |
1318 | |
1319 | |
1320 | if (SrcSize <= DstSize) { |
1321 | Dst = CGF.Builder.CreateElementBitCast(Dst, SrcTy); |
1322 | BuildAggStore(CGF, Src, Dst, DstIsVolatile); |
1323 | } else { |
1324 | |
1325 | |
1326 | |
1327 | |
1328 | |
1329 | |
1330 | |
1331 | |
1332 | |
1333 | Address Tmp = CreateTempAllocaForCoercion(CGF, SrcTy, Dst.getAlignment()); |
1334 | CGF.Builder.CreateStore(Src, Tmp); |
1335 | Address Casted = CGF.Builder.CreateElementBitCast(Tmp,CGF.Int8Ty); |
1336 | Address DstCasted = CGF.Builder.CreateElementBitCast(Dst,CGF.Int8Ty); |
1337 | CGF.Builder.CreateMemCpy(DstCasted, Casted, |
1338 | llvm::ConstantInt::get(CGF.IntPtrTy, DstSize), |
1339 | false); |
1340 | } |
1341 | } |
1342 | |
1343 | static Address emitAddressAtOffset(CodeGenFunction &CGF, Address addr, |
1344 | const ABIArgInfo &info) { |
1345 | if (unsigned offset = info.getDirectOffset()) { |
1346 | addr = CGF.Builder.CreateElementBitCast(addr, CGF.Int8Ty); |
1347 | addr = CGF.Builder.CreateConstInBoundsByteGEP(addr, |
1348 | CharUnits::fromQuantity(offset)); |
1349 | addr = CGF.Builder.CreateElementBitCast(addr, info.getCoerceToType()); |
1350 | } |
1351 | return addr; |
1352 | } |
1353 | |
1354 | namespace { |
1355 | |
1356 | |
1357 | |
1358 | class ClangToLLVMArgMapping { |
1359 | static const unsigned InvalidIndex = ~0U; |
1360 | unsigned InallocaArgNo; |
1361 | unsigned SRetArgNo; |
1362 | unsigned TotalIRArgs; |
1363 | |
1364 | |
1365 | struct IRArgs { |
1366 | unsigned PaddingArgIndex; |
1367 | |
1368 | |
1369 | unsigned FirstArgIndex; |
1370 | unsigned NumberOfArgs; |
1371 | |
1372 | IRArgs() |
1373 | : PaddingArgIndex(InvalidIndex), FirstArgIndex(InvalidIndex), |
1374 | NumberOfArgs(0) {} |
1375 | }; |
1376 | |
1377 | SmallVector<IRArgs, 8> ArgInfo; |
1378 | |
1379 | public: |
1380 | ClangToLLVMArgMapping(const ASTContext &Context, const CGFunctionInfo &FI, |
1381 | bool OnlyRequiredArgs = false) |
1382 | : InallocaArgNo(InvalidIndex), SRetArgNo(InvalidIndex), TotalIRArgs(0), |
1383 | ArgInfo(OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size()) { |
1384 | construct(Context, FI, OnlyRequiredArgs); |
1385 | } |
1386 | |
1387 | bool hasInallocaArg() const { return InallocaArgNo != InvalidIndex; } |
1388 | unsigned getInallocaArgNo() const { |
1389 | assert(hasInallocaArg()); |
1390 | return InallocaArgNo; |
1391 | } |
1392 | |
1393 | bool hasSRetArg() const { return SRetArgNo != InvalidIndex; } |
1394 | unsigned getSRetArgNo() const { |
1395 | assert(hasSRetArg()); |
1396 | return SRetArgNo; |
1397 | } |
1398 | |
1399 | unsigned totalIRArgs() const { return TotalIRArgs; } |
1400 | |
1401 | bool hasPaddingArg(unsigned ArgNo) const { |
1402 | assert(ArgNo < ArgInfo.size()); |
1403 | return ArgInfo[ArgNo].PaddingArgIndex != InvalidIndex; |
1404 | } |
1405 | unsigned getPaddingArgNo(unsigned ArgNo) const { |
1406 | assert(hasPaddingArg(ArgNo)); |
1407 | return ArgInfo[ArgNo].PaddingArgIndex; |
1408 | } |
1409 | |
1410 | |
1411 | |
1412 | std::pair<unsigned, unsigned> getIRArgs(unsigned ArgNo) const { |
1413 | assert(ArgNo < ArgInfo.size()); |
1414 | return std::make_pair(ArgInfo[ArgNo].FirstArgIndex, |
1415 | ArgInfo[ArgNo].NumberOfArgs); |
1416 | } |
1417 | |
1418 | private: |
1419 | void construct(const ASTContext &Context, const CGFunctionInfo &FI, |
1420 | bool OnlyRequiredArgs); |
1421 | }; |
1422 | |
1423 | void ClangToLLVMArgMapping::construct(const ASTContext &Context, |
1424 | const CGFunctionInfo &FI, |
1425 | bool OnlyRequiredArgs) { |
1426 | unsigned IRArgNo = 0; |
1427 | bool SwapThisWithSRet = false; |
1428 | const ABIArgInfo &RetAI = FI.getReturnInfo(); |
1429 | |
1430 | if (RetAI.getKind() == ABIArgInfo::Indirect) { |
1431 | SwapThisWithSRet = RetAI.isSRetAfterThis(); |
1432 | SRetArgNo = SwapThisWithSRet ? 1 : IRArgNo++; |
1433 | } |
1434 | |
1435 | unsigned ArgNo = 0; |
1436 | unsigned NumArgs = OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size(); |
1437 | for (CGFunctionInfo::const_arg_iterator I = FI.arg_begin(); ArgNo < NumArgs; |
1438 | ++I, ++ArgNo) { |
1439 | assert(I != FI.arg_end()); |
1440 | QualType ArgType = I->type; |
1441 | const ABIArgInfo &AI = I->info; |
1442 | |
1443 | auto &IRArgs = ArgInfo[ArgNo]; |
1444 | |
1445 | if (AI.getPaddingType()) |
1446 | IRArgs.PaddingArgIndex = IRArgNo++; |
1447 | |
1448 | switch (AI.getKind()) { |
1449 | case ABIArgInfo::Extend: |
1450 | case ABIArgInfo::Direct: { |
1451 | |
1452 | llvm::StructType *STy = dyn_cast<llvm::StructType>(AI.getCoerceToType()); |
1453 | if (AI.isDirect() && AI.getCanBeFlattened() && STy) { |
1454 | IRArgs.NumberOfArgs = STy->getNumElements(); |
1455 | } else { |
1456 | IRArgs.NumberOfArgs = 1; |
1457 | } |
1458 | break; |
1459 | } |
1460 | case ABIArgInfo::Indirect: |
1461 | IRArgs.NumberOfArgs = 1; |
1462 | break; |
1463 | case ABIArgInfo::Ignore: |
1464 | case ABIArgInfo::InAlloca: |
1465 | |
1466 | IRArgs.NumberOfArgs = 0; |
1467 | break; |
1468 | case ABIArgInfo::CoerceAndExpand: |
1469 | IRArgs.NumberOfArgs = AI.getCoerceAndExpandTypeSequence().size(); |
1470 | break; |
1471 | case ABIArgInfo::Expand: |
1472 | IRArgs.NumberOfArgs = getExpansionSize(ArgType, Context); |
1473 | break; |
1474 | } |
1475 | |
1476 | if (IRArgs.NumberOfArgs > 0) { |
1477 | IRArgs.FirstArgIndex = IRArgNo; |
1478 | IRArgNo += IRArgs.NumberOfArgs; |
1479 | } |
1480 | |
1481 | |
1482 | |
1483 | if (IRArgNo == 1 && SwapThisWithSRet) |
1484 | IRArgNo++; |
1485 | } |
1486 | assert(ArgNo == ArgInfo.size()); |
1487 | |
1488 | if (FI.usesInAlloca()) |
1489 | InallocaArgNo = IRArgNo++; |
1490 | |
1491 | TotalIRArgs = IRArgNo; |
1492 | } |
1493 | } |
1494 | |
1495 | |
1496 | |
1497 | bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) { |
1498 | const auto &RI = FI.getReturnInfo(); |
1499 | return RI.isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet()); |
1500 | } |
1501 | |
1502 | bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) { |
1503 | return ReturnTypeUsesSRet(FI) && |
1504 | getTargetCodeGenInfo().doesReturnSlotInterfereWithArgs(); |
1505 | } |
1506 | |
1507 | bool CodeGenModule::ReturnTypeUsesFPRet(QualType ResultType) { |
1508 | if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) { |
1509 | switch (BT->getKind()) { |
1510 | default: |
1511 | return false; |
1512 | case BuiltinType::Float: |
1513 | return getTarget().useObjCFPRetForRealType(TargetInfo::Float); |
1514 | case BuiltinType::Double: |
1515 | return getTarget().useObjCFPRetForRealType(TargetInfo::Double); |
1516 | case BuiltinType::LongDouble: |
1517 | return getTarget().useObjCFPRetForRealType(TargetInfo::LongDouble); |
1518 | } |
1519 | } |
1520 | |
1521 | return false; |
1522 | } |
1523 | |
1524 | bool CodeGenModule::ReturnTypeUsesFP2Ret(QualType ResultType) { |
1525 | if (const ComplexType *CT = ResultType->getAs<ComplexType>()) { |
1526 | if (const BuiltinType *BT = CT->getElementType()->getAs<BuiltinType>()) { |
1527 | if (BT->getKind() == BuiltinType::LongDouble) |
1528 | return getTarget().useObjCFP2RetForComplexLongDouble(); |
1529 | } |
1530 | } |
1531 | |
1532 | return false; |
1533 | } |
1534 | |
1535 | llvm::FunctionType *CodeGenTypes::GetFunctionType(GlobalDecl GD) { |
1536 | const CGFunctionInfo &FI = arrangeGlobalDeclaration(GD); |
1537 | return GetFunctionType(FI); |
1538 | } |
1539 | |
1540 | llvm::FunctionType * |
1541 | CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) { |
1542 | |
1543 | bool Inserted = FunctionsBeingProcessed.insert(&FI).second; |
1544 | (void)Inserted; |
1545 | (0) . __assert_fail ("Inserted && \"Recursively being processed?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 1545, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Inserted && "Recursively being processed?"); |
1546 | |
1547 | llvm::Type *resultType = nullptr; |
1548 | const ABIArgInfo &retAI = FI.getReturnInfo(); |
1549 | switch (retAI.getKind()) { |
1550 | case ABIArgInfo::Expand: |
1551 | llvm_unreachable("Invalid ABI kind for return argument"); |
1552 | |
1553 | case ABIArgInfo::Extend: |
1554 | case ABIArgInfo::Direct: |
1555 | resultType = retAI.getCoerceToType(); |
1556 | break; |
1557 | |
1558 | case ABIArgInfo::InAlloca: |
1559 | if (retAI.getInAllocaSRet()) { |
1560 | |
1561 | QualType ret = FI.getReturnType(); |
1562 | llvm::Type *ty = ConvertType(ret); |
1563 | unsigned addressSpace = Context.getTargetAddressSpace(ret); |
1564 | resultType = llvm::PointerType::get(ty, addressSpace); |
1565 | } else { |
1566 | resultType = llvm::Type::getVoidTy(getLLVMContext()); |
1567 | } |
1568 | break; |
1569 | |
1570 | case ABIArgInfo::Indirect: |
1571 | case ABIArgInfo::Ignore: |
1572 | resultType = llvm::Type::getVoidTy(getLLVMContext()); |
1573 | break; |
1574 | |
1575 | case ABIArgInfo::CoerceAndExpand: |
1576 | resultType = retAI.getUnpaddedCoerceAndExpandType(); |
1577 | break; |
1578 | } |
1579 | |
1580 | ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI, true); |
1581 | SmallVector<llvm::Type*, 8> ArgTypes(IRFunctionArgs.totalIRArgs()); |
1582 | |
1583 | |
1584 | if (IRFunctionArgs.hasSRetArg()) { |
1585 | QualType Ret = FI.getReturnType(); |
1586 | llvm::Type *Ty = ConvertType(Ret); |
1587 | unsigned AddressSpace = Context.getTargetAddressSpace(Ret); |
1588 | ArgTypes[IRFunctionArgs.getSRetArgNo()] = |
1589 | llvm::PointerType::get(Ty, AddressSpace); |
1590 | } |
1591 | |
1592 | |
1593 | if (IRFunctionArgs.hasInallocaArg()) { |
1594 | auto ArgStruct = FI.getArgStruct(); |
1595 | assert(ArgStruct); |
1596 | ArgTypes[IRFunctionArgs.getInallocaArgNo()] = ArgStruct->getPointerTo(); |
1597 | } |
1598 | |
1599 | |
1600 | unsigned ArgNo = 0; |
1601 | CGFunctionInfo::const_arg_iterator it = FI.arg_begin(), |
1602 | ie = it + FI.getNumRequiredArgs(); |
1603 | for (; it != ie; ++it, ++ArgNo) { |
1604 | const ABIArgInfo &ArgInfo = it->info; |
1605 | |
1606 | |
1607 | if (IRFunctionArgs.hasPaddingArg(ArgNo)) |
1608 | ArgTypes[IRFunctionArgs.getPaddingArgNo(ArgNo)] = |
1609 | ArgInfo.getPaddingType(); |
1610 | |
1611 | unsigned FirstIRArg, NumIRArgs; |
1612 | std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo); |
1613 | |
1614 | switch (ArgInfo.getKind()) { |
1615 | case ABIArgInfo::Ignore: |
1616 | case ABIArgInfo::InAlloca: |
1617 | assert(NumIRArgs == 0); |
1618 | break; |
1619 | |
1620 | case ABIArgInfo::Indirect: { |
1621 | assert(NumIRArgs == 1); |
1622 | |
1623 | llvm::Type *LTy = ConvertTypeForMem(it->type); |
1624 | ArgTypes[FirstIRArg] = LTy->getPointerTo( |
1625 | CGM.getDataLayout().getAllocaAddrSpace()); |
1626 | break; |
1627 | } |
1628 | |
1629 | case ABIArgInfo::Extend: |
1630 | case ABIArgInfo::Direct: { |
1631 | |
1632 | |
1633 | llvm::Type *argType = ArgInfo.getCoerceToType(); |
1634 | llvm::StructType *st = dyn_cast<llvm::StructType>(argType); |
1635 | if (st && ArgInfo.isDirect() && ArgInfo.getCanBeFlattened()) { |
1636 | getNumElements()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 1636, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(NumIRArgs == st->getNumElements()); |
1637 | for (unsigned i = 0, e = st->getNumElements(); i != e; ++i) |
1638 | ArgTypes[FirstIRArg + i] = st->getElementType(i); |
1639 | } else { |
1640 | assert(NumIRArgs == 1); |
1641 | ArgTypes[FirstIRArg] = argType; |
1642 | } |
1643 | break; |
1644 | } |
1645 | |
1646 | case ABIArgInfo::CoerceAndExpand: { |
1647 | auto ArgTypesIter = ArgTypes.begin() + FirstIRArg; |
1648 | for (auto EltTy : ArgInfo.getCoerceAndExpandTypeSequence()) { |
1649 | *ArgTypesIter++ = EltTy; |
1650 | } |
1651 | assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs); |
1652 | break; |
1653 | } |
1654 | |
1655 | case ABIArgInfo::Expand: |
1656 | auto ArgTypesIter = ArgTypes.begin() + FirstIRArg; |
1657 | getExpandedTypes(it->type, ArgTypesIter); |
1658 | assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs); |
1659 | break; |
1660 | } |
1661 | } |
1662 | |
1663 | bool Erased = FunctionsBeingProcessed.erase(&FI); (void)Erased; |
1664 | (0) . __assert_fail ("Erased && \"Not in set?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 1664, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Erased && "Not in set?"); |
1665 | |
1666 | return llvm::FunctionType::get(resultType, ArgTypes, FI.isVariadic()); |
1667 | } |
1668 | |
1669 | llvm::Type *CodeGenTypes::GetFunctionTypeForVTable(GlobalDecl GD) { |
1670 | const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); |
1671 | const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); |
1672 | |
1673 | if (!isFuncTypeConvertible(FPT)) |
1674 | return llvm::StructType::get(getLLVMContext()); |
1675 | |
1676 | return GetFunctionType(GD); |
1677 | } |
1678 | |
1679 | static void AddAttributesFromFunctionProtoType(ASTContext &Ctx, |
1680 | llvm::AttrBuilder &FuncAttrs, |
1681 | const FunctionProtoType *FPT) { |
1682 | if (!FPT) |
1683 | return; |
1684 | |
1685 | if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) && |
1686 | FPT->isNothrow()) |
1687 | FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); |
1688 | } |
1689 | |
1690 | void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone, |
1691 | bool AttrOnCallSite, |
1692 | llvm::AttrBuilder &FuncAttrs) { |
1693 | |
1694 | if (!HasOptnone) { |
1695 | if (CodeGenOpts.OptimizeSize) |
1696 | FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize); |
1697 | if (CodeGenOpts.OptimizeSize == 2) |
1698 | FuncAttrs.addAttribute(llvm::Attribute::MinSize); |
1699 | } |
1700 | |
1701 | if (CodeGenOpts.DisableRedZone) |
1702 | FuncAttrs.addAttribute(llvm::Attribute::NoRedZone); |
1703 | if (CodeGenOpts.IndirectTlsSegRefs) |
1704 | FuncAttrs.addAttribute("indirect-tls-seg-refs"); |
1705 | if (CodeGenOpts.NoImplicitFloat) |
1706 | FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat); |
1707 | |
1708 | if (AttrOnCallSite) { |
1709 | |
1710 | if (!CodeGenOpts.SimplifyLibCalls || |
1711 | CodeGenOpts.isNoBuiltinFunc(Name.data())) |
1712 | FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin); |
1713 | if (!CodeGenOpts.TrapFuncName.empty()) |
1714 | FuncAttrs.addAttribute("trap-func-name", CodeGenOpts.TrapFuncName); |
1715 | } else { |
1716 | |
1717 | if (!CodeGenOpts.DisableFPElim) { |
1718 | FuncAttrs.addAttribute("no-frame-pointer-elim", "false"); |
1719 | } else if (CodeGenOpts.OmitLeafFramePointer) { |
1720 | FuncAttrs.addAttribute("no-frame-pointer-elim", "false"); |
1721 | FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf"); |
1722 | } else { |
1723 | FuncAttrs.addAttribute("no-frame-pointer-elim", "true"); |
1724 | FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf"); |
1725 | } |
1726 | |
1727 | FuncAttrs.addAttribute("less-precise-fpmad", |
1728 | llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD)); |
1729 | |
1730 | if (CodeGenOpts.NullPointerIsValid) |
1731 | FuncAttrs.addAttribute("null-pointer-is-valid", "true"); |
1732 | if (!CodeGenOpts.FPDenormalMode.empty()) |
1733 | FuncAttrs.addAttribute("denormal-fp-math", CodeGenOpts.FPDenormalMode); |
1734 | |
1735 | FuncAttrs.addAttribute("no-trapping-math", |
1736 | llvm::toStringRef(CodeGenOpts.NoTrappingMath)); |
1737 | |
1738 | |
1739 | |
1740 | if (!CodeGenOpts.StrictFloatCastOverflow) |
1741 | FuncAttrs.addAttribute("strict-float-cast-overflow", "false"); |
1742 | |
1743 | |
1744 | |
1745 | FuncAttrs.addAttribute("no-infs-fp-math", |
1746 | llvm::toStringRef(CodeGenOpts.NoInfsFPMath)); |
1747 | FuncAttrs.addAttribute("no-nans-fp-math", |
1748 | llvm::toStringRef(CodeGenOpts.NoNaNsFPMath)); |
1749 | FuncAttrs.addAttribute("unsafe-fp-math", |
1750 | llvm::toStringRef(CodeGenOpts.UnsafeFPMath)); |
1751 | FuncAttrs.addAttribute("use-soft-float", |
1752 | llvm::toStringRef(CodeGenOpts.SoftFloat)); |
1753 | FuncAttrs.addAttribute("stack-protector-buffer-size", |
1754 | llvm::utostr(CodeGenOpts.SSPBufferSize)); |
1755 | FuncAttrs.addAttribute("no-signed-zeros-fp-math", |
1756 | llvm::toStringRef(CodeGenOpts.NoSignedZeros)); |
1757 | FuncAttrs.addAttribute( |
1758 | "correctly-rounded-divide-sqrt-fp-math", |
1759 | llvm::toStringRef(CodeGenOpts.CorrectlyRoundedDivSqrt)); |
1760 | |
1761 | if (getLangOpts().OpenCL) |
1762 | FuncAttrs.addAttribute("denorms-are-zero", |
1763 | llvm::toStringRef(CodeGenOpts.FlushDenorm)); |
1764 | |
1765 | |
1766 | const std::vector<std::string> &Recips = CodeGenOpts.Reciprocals; |
1767 | if (!Recips.empty()) |
1768 | FuncAttrs.addAttribute("reciprocal-estimates", |
1769 | llvm::join(Recips, ",")); |
1770 | |
1771 | if (!CodeGenOpts.PreferVectorWidth.empty() && |
1772 | CodeGenOpts.PreferVectorWidth != "none") |
1773 | FuncAttrs.addAttribute("prefer-vector-width", |
1774 | CodeGenOpts.PreferVectorWidth); |
1775 | |
1776 | if (CodeGenOpts.StackRealignment) |
1777 | FuncAttrs.addAttribute("stackrealign"); |
1778 | if (CodeGenOpts.Backchain) |
1779 | FuncAttrs.addAttribute("backchain"); |
1780 | |
1781 | if (CodeGenOpts.SpeculativeLoadHardening) |
1782 | FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening); |
1783 | } |
1784 | |
1785 | if (getLangOpts().assumeFunctionsAreConvergent()) { |
1786 | |
1787 | |
1788 | |
1789 | |
1790 | |
1791 | FuncAttrs.addAttribute(llvm::Attribute::Convergent); |
1792 | } |
1793 | |
1794 | if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice) { |
1795 | |
1796 | FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); |
1797 | |
1798 | |
1799 | if (CodeGenOpts.FlushDenorm) |
1800 | FuncAttrs.addAttribute("nvptx-f32ftz", "true"); |
1801 | } |
1802 | |
1803 | for (StringRef Attr : CodeGenOpts.DefaultFunctionAttrs) { |
1804 | StringRef Var, Value; |
1805 | std::tie(Var, Value) = Attr.split('='); |
1806 | FuncAttrs.addAttribute(Var, Value); |
1807 | } |
1808 | } |
1809 | |
1810 | void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) { |
1811 | llvm::AttrBuilder FuncAttrs; |
1812 | ConstructDefaultFnAttrList(F.getName(), |
1813 | F.hasFnAttribute(llvm::Attribute::OptimizeNone), |
1814 | false, FuncAttrs); |
1815 | F.addAttributes(llvm::AttributeList::FunctionIndex, FuncAttrs); |
1816 | } |
1817 | |
1818 | void CodeGenModule::ConstructAttributeList( |
1819 | StringRef Name, const CGFunctionInfo &FI, CGCalleeInfo CalleeInfo, |
1820 | llvm::AttributeList &AttrList, unsigned &CallingConv, bool AttrOnCallSite) { |
1821 | llvm::AttrBuilder FuncAttrs; |
1822 | llvm::AttrBuilder RetAttrs; |
1823 | |
1824 | CallingConv = FI.getEffectiveCallingConvention(); |
1825 | if (FI.isNoReturn()) |
1826 | FuncAttrs.addAttribute(llvm::Attribute::NoReturn); |
1827 | |
1828 | |
1829 | |
1830 | AddAttributesFromFunctionProtoType(getContext(), FuncAttrs, |
1831 | CalleeInfo.getCalleeFunctionProtoType()); |
1832 | |
1833 | const Decl *TargetDecl = CalleeInfo.getCalleeDecl().getDecl(); |
1834 | |
1835 | bool HasOptnone = false; |
1836 | |
1837 | if (TargetDecl) { |
1838 | if (TargetDecl->hasAttr<ReturnsTwiceAttr>()) |
1839 | FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice); |
1840 | if (TargetDecl->hasAttr<NoThrowAttr>()) |
1841 | FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); |
1842 | if (TargetDecl->hasAttr<NoReturnAttr>()) |
1843 | FuncAttrs.addAttribute(llvm::Attribute::NoReturn); |
1844 | if (TargetDecl->hasAttr<ColdAttr>()) |
1845 | FuncAttrs.addAttribute(llvm::Attribute::Cold); |
1846 | if (TargetDecl->hasAttr<NoDuplicateAttr>()) |
1847 | FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate); |
1848 | if (TargetDecl->hasAttr<ConvergentAttr>()) |
1849 | FuncAttrs.addAttribute(llvm::Attribute::Convergent); |
1850 | |
1851 | if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) { |
1852 | AddAttributesFromFunctionProtoType( |
1853 | getContext(), FuncAttrs, Fn->getType()->getAs<FunctionProtoType>()); |
1854 | |
1855 | |
1856 | const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn); |
1857 | if (Fn->isNoReturn() && !(AttrOnCallSite && MD && MD->isVirtual())) |
1858 | FuncAttrs.addAttribute(llvm::Attribute::NoReturn); |
1859 | } |
1860 | |
1861 | |
1862 | if (TargetDecl->hasAttr<ConstAttr>()) { |
1863 | FuncAttrs.addAttribute(llvm::Attribute::ReadNone); |
1864 | FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); |
1865 | } else if (TargetDecl->hasAttr<PureAttr>()) { |
1866 | FuncAttrs.addAttribute(llvm::Attribute::ReadOnly); |
1867 | FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); |
1868 | } else if (TargetDecl->hasAttr<NoAliasAttr>()) { |
1869 | FuncAttrs.addAttribute(llvm::Attribute::ArgMemOnly); |
1870 | FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); |
1871 | } |
1872 | if (TargetDecl->hasAttr<RestrictAttr>()) |
1873 | RetAttrs.addAttribute(llvm::Attribute::NoAlias); |
1874 | if (TargetDecl->hasAttr<ReturnsNonNullAttr>() && |
1875 | !CodeGenOpts.NullPointerIsValid) |
1876 | RetAttrs.addAttribute(llvm::Attribute::NonNull); |
1877 | if (TargetDecl->hasAttr<AnyX86NoCallerSavedRegistersAttr>()) |
1878 | FuncAttrs.addAttribute("no_caller_saved_registers"); |
1879 | if (TargetDecl->hasAttr<AnyX86NoCfCheckAttr>()) |
1880 | FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck); |
1881 | |
1882 | HasOptnone = TargetDecl->hasAttr<OptimizeNoneAttr>(); |
1883 | if (auto *AllocSize = TargetDecl->getAttr<AllocSizeAttr>()) { |
1884 | Optional<unsigned> NumElemsParam; |
1885 | if (AllocSize->getNumElemsParam().isValid()) |
1886 | NumElemsParam = AllocSize->getNumElemsParam().getLLVMIndex(); |
1887 | FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam().getLLVMIndex(), |
1888 | NumElemsParam); |
1889 | } |
1890 | } |
1891 | |
1892 | ConstructDefaultFnAttrList(Name, HasOptnone, AttrOnCallSite, FuncAttrs); |
1893 | |
1894 | |
1895 | |
1896 | |
1897 | if (TargetDecl) { |
1898 | if (TargetDecl->hasAttr<NoSpeculativeLoadHardeningAttr>()) |
1899 | FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening); |
1900 | if (TargetDecl->hasAttr<SpeculativeLoadHardeningAttr>()) |
1901 | FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening); |
1902 | } |
1903 | |
1904 | if (CodeGenOpts.EnableSegmentedStacks && |
1905 | !(TargetDecl && TargetDecl->hasAttr<NoSplitStackAttr>())) |
1906 | FuncAttrs.addAttribute("split-stack"); |
1907 | |
1908 | |
1909 | |
1910 | if (TargetDecl && CodeGenOpts.NoPLT) { |
1911 | if (auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) { |
1912 | if (!Fn->isDefined() && !AttrOnCallSite) { |
1913 | FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind); |
1914 | } |
1915 | } |
1916 | } |
1917 | |
1918 | if (TargetDecl && TargetDecl->hasAttr<OpenCLKernelAttr>()) { |
1919 | if (getLangOpts().OpenCLVersion <= 120) { |
1920 | |
1921 | FuncAttrs.addAttribute("uniform-work-group-size", "true"); |
1922 | } else { |
1923 | |
1924 | |
1925 | |
1926 | |
1927 | |
1928 | FuncAttrs.addAttribute("uniform-work-group-size", |
1929 | llvm::toStringRef(CodeGenOpts.UniformWGSize)); |
1930 | } |
1931 | } |
1932 | |
1933 | if (!AttrOnCallSite) { |
1934 | bool DisableTailCalls = false; |
1935 | |
1936 | if (CodeGenOpts.DisableTailCalls) |
1937 | DisableTailCalls = true; |
1938 | else if (TargetDecl) { |
1939 | if (TargetDecl->hasAttr<DisableTailCallsAttr>() || |
1940 | TargetDecl->hasAttr<AnyX86InterruptAttr>()) |
1941 | DisableTailCalls = true; |
1942 | else if (CodeGenOpts.NoEscapingBlockTailCalls) { |
1943 | if (const auto *BD = dyn_cast<BlockDecl>(TargetDecl)) |
1944 | if (!BD->doesNotEscape()) |
1945 | DisableTailCalls = true; |
1946 | } |
1947 | } |
1948 | |
1949 | FuncAttrs.addAttribute("disable-tail-calls", |
1950 | llvm::toStringRef(DisableTailCalls)); |
1951 | GetCPUAndFeaturesAttributes(CalleeInfo.getCalleeDecl(), FuncAttrs); |
1952 | } |
1953 | |
1954 | ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI); |
1955 | |
1956 | QualType RetTy = FI.getReturnType(); |
1957 | const ABIArgInfo &RetAI = FI.getReturnInfo(); |
1958 | switch (RetAI.getKind()) { |
1959 | case ABIArgInfo::Extend: |
1960 | if (RetAI.isSignExt()) |
1961 | RetAttrs.addAttribute(llvm::Attribute::SExt); |
1962 | else |
1963 | RetAttrs.addAttribute(llvm::Attribute::ZExt); |
1964 | LLVM_FALLTHROUGH; |
1965 | case ABIArgInfo::Direct: |
1966 | if (RetAI.getInReg()) |
1967 | RetAttrs.addAttribute(llvm::Attribute::InReg); |
1968 | break; |
1969 | case ABIArgInfo::Ignore: |
1970 | break; |
1971 | |
1972 | case ABIArgInfo::InAlloca: |
1973 | case ABIArgInfo::Indirect: { |
1974 | |
1975 | FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly) |
1976 | .removeAttribute(llvm::Attribute::ReadNone); |
1977 | break; |
1978 | } |
1979 | |
1980 | case ABIArgInfo::CoerceAndExpand: |
1981 | break; |
1982 | |
1983 | case ABIArgInfo::Expand: |
1984 | llvm_unreachable("Invalid ABI kind for return argument"); |
1985 | } |
1986 | |
1987 | if (const auto *RefTy = RetTy->getAs<ReferenceType>()) { |
1988 | QualType PTy = RefTy->getPointeeType(); |
1989 | if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) |
1990 | RetAttrs.addDereferenceableAttr(getContext().getTypeSizeInChars(PTy) |
1991 | .getQuantity()); |
1992 | else if (getContext().getTargetAddressSpace(PTy) == 0 && |
1993 | !CodeGenOpts.NullPointerIsValid) |
1994 | RetAttrs.addAttribute(llvm::Attribute::NonNull); |
1995 | } |
1996 | |
1997 | bool hasUsedSRet = false; |
1998 | SmallVector<llvm::AttributeSet, 4> ArgAttrs(IRFunctionArgs.totalIRArgs()); |
1999 | |
2000 | |
2001 | if (IRFunctionArgs.hasSRetArg()) { |
2002 | llvm::AttrBuilder SRETAttrs; |
2003 | if (!RetAI.getSuppressSRet()) |
2004 | SRETAttrs.addAttribute(llvm::Attribute::StructRet); |
2005 | hasUsedSRet = true; |
2006 | if (RetAI.getInReg()) |
2007 | SRETAttrs.addAttribute(llvm::Attribute::InReg); |
2008 | ArgAttrs[IRFunctionArgs.getSRetArgNo()] = |
2009 | llvm::AttributeSet::get(getLLVMContext(), SRETAttrs); |
2010 | } |
2011 | |
2012 | |
2013 | if (IRFunctionArgs.hasInallocaArg()) { |
2014 | llvm::AttrBuilder Attrs; |
2015 | Attrs.addAttribute(llvm::Attribute::InAlloca); |
2016 | ArgAttrs[IRFunctionArgs.getInallocaArgNo()] = |
2017 | llvm::AttributeSet::get(getLLVMContext(), Attrs); |
2018 | } |
2019 | |
2020 | unsigned ArgNo = 0; |
2021 | for (CGFunctionInfo::const_arg_iterator I = FI.arg_begin(), |
2022 | E = FI.arg_end(); |
2023 | I != E; ++I, ++ArgNo) { |
2024 | QualType ParamType = I->type; |
2025 | const ABIArgInfo &AI = I->info; |
2026 | llvm::AttrBuilder Attrs; |
2027 | |
2028 | |
2029 | if (IRFunctionArgs.hasPaddingArg(ArgNo)) { |
2030 | if (AI.getPaddingInReg()) { |
2031 | ArgAttrs[IRFunctionArgs.getPaddingArgNo(ArgNo)] = |
2032 | llvm::AttributeSet::get( |
2033 | getLLVMContext(), |
2034 | llvm::AttrBuilder().addAttribute(llvm::Attribute::InReg)); |
2035 | } |
2036 | } |
2037 | |
2038 | |
2039 | |
2040 | |
2041 | switch (AI.getKind()) { |
2042 | case ABIArgInfo::Extend: |
2043 | if (AI.isSignExt()) |
2044 | Attrs.addAttribute(llvm::Attribute::SExt); |
2045 | else |
2046 | Attrs.addAttribute(llvm::Attribute::ZExt); |
2047 | LLVM_FALLTHROUGH; |
2048 | case ABIArgInfo::Direct: |
2049 | if (ArgNo == 0 && FI.isChainCall()) |
2050 | Attrs.addAttribute(llvm::Attribute::Nest); |
2051 | else if (AI.getInReg()) |
2052 | Attrs.addAttribute(llvm::Attribute::InReg); |
2053 | break; |
2054 | |
2055 | case ABIArgInfo::Indirect: { |
2056 | if (AI.getInReg()) |
2057 | Attrs.addAttribute(llvm::Attribute::InReg); |
2058 | |
2059 | if (AI.getIndirectByVal()) |
2060 | Attrs.addAttribute(llvm::Attribute::ByVal); |
2061 | |
2062 | CharUnits Align = AI.getIndirectAlign(); |
2063 | |
2064 | |
2065 | |
2066 | |
2067 | |
2068 | |
2069 | |
2070 | |
2071 | |
2072 | |
2073 | |
2074 | assert(!Align.isZero()); |
2075 | |
2076 | |
2077 | |
2078 | if (AI.getIndirectByVal()) |
2079 | Attrs.addAlignmentAttr(Align.getQuantity()); |
2080 | |
2081 | |
2082 | FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly) |
2083 | .removeAttribute(llvm::Attribute::ReadNone); |
2084 | break; |
2085 | } |
2086 | case ABIArgInfo::Ignore: |
2087 | case ABIArgInfo::Expand: |
2088 | case ABIArgInfo::CoerceAndExpand: |
2089 | break; |
2090 | |
2091 | case ABIArgInfo::InAlloca: |
2092 | |
2093 | FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly) |
2094 | .removeAttribute(llvm::Attribute::ReadNone); |
2095 | continue; |
2096 | } |
2097 | |
2098 | if (const auto *RefTy = ParamType->getAs<ReferenceType>()) { |
2099 | QualType PTy = RefTy->getPointeeType(); |
2100 | if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) |
2101 | Attrs.addDereferenceableAttr(getContext().getTypeSizeInChars(PTy) |
2102 | .getQuantity()); |
2103 | else if (getContext().getTargetAddressSpace(PTy) == 0 && |
2104 | !CodeGenOpts.NullPointerIsValid) |
2105 | Attrs.addAttribute(llvm::Attribute::NonNull); |
2106 | } |
2107 | |
2108 | switch (FI.getExtParameterInfo(ArgNo).getABI()) { |
2109 | case ParameterABI::Ordinary: |
2110 | break; |
2111 | |
2112 | case ParameterABI::SwiftIndirectResult: { |
2113 | |
2114 | |
2115 | if (!hasUsedSRet && RetTy->isVoidType()) { |
2116 | Attrs.addAttribute(llvm::Attribute::StructRet); |
2117 | hasUsedSRet = true; |
2118 | } |
2119 | |
2120 | |
2121 | Attrs.addAttribute(llvm::Attribute::NoAlias); |
2122 | |
2123 | |
2124 | auto PTy = ParamType->getPointeeType(); |
2125 | if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) { |
2126 | auto info = getContext().getTypeInfoInChars(PTy); |
2127 | Attrs.addDereferenceableAttr(info.first.getQuantity()); |
2128 | Attrs.addAttribute(llvm::Attribute::getWithAlignment(getLLVMContext(), |
2129 | info.second.getQuantity())); |
2130 | } |
2131 | break; |
2132 | } |
2133 | |
2134 | case ParameterABI::SwiftErrorResult: |
2135 | Attrs.addAttribute(llvm::Attribute::SwiftError); |
2136 | break; |
2137 | |
2138 | case ParameterABI::SwiftContext: |
2139 | Attrs.addAttribute(llvm::Attribute::SwiftSelf); |
2140 | break; |
2141 | } |
2142 | |
2143 | if (FI.getExtParameterInfo(ArgNo).isNoEscape()) |
2144 | Attrs.addAttribute(llvm::Attribute::NoCapture); |
2145 | |
2146 | if (Attrs.hasAttributes()) { |
2147 | unsigned FirstIRArg, NumIRArgs; |
2148 | std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo); |
2149 | for (unsigned i = 0; i < NumIRArgs; i++) |
2150 | ArgAttrs[FirstIRArg + i] = |
2151 | llvm::AttributeSet::get(getLLVMContext(), Attrs); |
2152 | } |
2153 | } |
2154 | assert(ArgNo == FI.arg_size()); |
2155 | |
2156 | AttrList = llvm::AttributeList::get( |
2157 | getLLVMContext(), llvm::AttributeSet::get(getLLVMContext(), FuncAttrs), |
2158 | llvm::AttributeSet::get(getLLVMContext(), RetAttrs), ArgAttrs); |
2159 | } |
2160 | |
2161 | |
2162 | |
2163 | static llvm::Value *emitArgumentDemotion(CodeGenFunction &CGF, |
2164 | const VarDecl *var, |
2165 | llvm::Value *value) { |
2166 | llvm::Type *varType = CGF.ConvertType(var->getType()); |
2167 | |
2168 | |
2169 | |
2170 | if (value->getType() == varType) return value; |
2171 | |
2172 | (0) . __assert_fail ("(varType->isIntegerTy() || varType->isFloatingPointTy()) && \"unexpected promotion type\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2173, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((varType->isIntegerTy() || varType->isFloatingPointTy()) |
2173 | (0) . __assert_fail ("(varType->isIntegerTy() || varType->isFloatingPointTy()) && \"unexpected promotion type\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2173, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> && "unexpected promotion type"); |
2174 | |
2175 | if (isa<llvm::IntegerType>(varType)) |
2176 | return CGF.Builder.CreateTrunc(value, varType, "arg.unpromote"); |
2177 | |
2178 | return CGF.Builder.CreateFPCast(value, varType, "arg.unpromote"); |
2179 | } |
2180 | |
2181 | |
2182 | |
2183 | static const NonNullAttr *getNonNullAttr(const Decl *FD, const ParmVarDecl *PVD, |
2184 | QualType ArgType, unsigned ArgNo) { |
2185 | |
2186 | |
2187 | |
2188 | |
2189 | |
2190 | |
2191 | |
2192 | if (!ArgType->isAnyPointerType() && !ArgType->isBlockPointerType()) |
2193 | return nullptr; |
2194 | |
2195 | if (PVD) { |
2196 | if (auto ParmNNAttr = PVD->getAttr<NonNullAttr>()) |
2197 | return ParmNNAttr; |
2198 | } |
2199 | |
2200 | if (!FD) |
2201 | return nullptr; |
2202 | for (const auto *NNAttr : FD->specific_attrs<NonNullAttr>()) { |
2203 | if (NNAttr->isNonNull(ArgNo)) |
2204 | return NNAttr; |
2205 | } |
2206 | return nullptr; |
2207 | } |
2208 | |
2209 | namespace { |
2210 | struct CopyBackSwiftError final : EHScopeStack::Cleanup { |
2211 | Address Temp; |
2212 | Address Arg; |
2213 | CopyBackSwiftError(Address temp, Address arg) : Temp(temp), Arg(arg) {} |
2214 | void Emit(CodeGenFunction &CGF, Flags flags) override { |
2215 | llvm::Value *errorValue = CGF.Builder.CreateLoad(Temp); |
2216 | CGF.Builder.CreateStore(errorValue, Arg); |
2217 | } |
2218 | }; |
2219 | } |
2220 | |
2221 | void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, |
2222 | llvm::Function *Fn, |
2223 | const FunctionArgList &Args) { |
2224 | if (CurCodeDecl && CurCodeDecl->hasAttr<NakedAttr>()) |
2225 | |
2226 | return; |
2227 | |
2228 | |
2229 | |
2230 | |
2231 | |
2232 | if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl)) { |
2233 | if (FD->hasImplicitReturnZero()) { |
2234 | QualType RetTy = FD->getReturnType().getUnqualifiedType(); |
2235 | llvm::Type* LLVMTy = CGM.getTypes().ConvertType(RetTy); |
2236 | llvm::Constant* Zero = llvm::Constant::getNullValue(LLVMTy); |
2237 | Builder.CreateStore(Zero, ReturnValue); |
2238 | } |
2239 | } |
2240 | |
2241 | |
2242 | |
2243 | |
2244 | ClangToLLVMArgMapping IRFunctionArgs(CGM.getContext(), FI); |
2245 | |
2246 | SmallVector<llvm::Value *, 16> FnArgs; |
2247 | FnArgs.reserve(IRFunctionArgs.totalIRArgs()); |
2248 | for (auto &Arg : Fn->args()) { |
2249 | FnArgs.push_back(&Arg); |
2250 | } |
2251 | assert(FnArgs.size() == IRFunctionArgs.totalIRArgs()); |
2252 | |
2253 | |
2254 | |
2255 | Address ArgStruct = Address::invalid(); |
2256 | if (IRFunctionArgs.hasInallocaArg()) { |
2257 | ArgStruct = Address(FnArgs[IRFunctionArgs.getInallocaArgNo()], |
2258 | FI.getArgStructAlignment()); |
2259 | |
2260 | getPointerTo()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2260, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ArgStruct.getType() == FI.getArgStruct()->getPointerTo()); |
2261 | } |
2262 | |
2263 | |
2264 | if (IRFunctionArgs.hasSRetArg()) { |
2265 | auto AI = cast<llvm::Argument>(FnArgs[IRFunctionArgs.getSRetArgNo()]); |
2266 | AI->setName("agg.result"); |
2267 | AI->addAttr(llvm::Attribute::NoAlias); |
2268 | } |
2269 | |
2270 | |
2271 | |
2272 | |
2273 | SmallVector<ParamValue, 16> ArgVals; |
2274 | ArgVals.reserve(Args.size()); |
2275 | |
2276 | |
2277 | |
2278 | |
2279 | |
2280 | (0) . __assert_fail ("FI.arg_size() == Args.size() && \"Mismatch between function signature & arguments.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2281, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(FI.arg_size() == Args.size() && |
2281 | (0) . __assert_fail ("FI.arg_size() == Args.size() && \"Mismatch between function signature & arguments.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2281, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Mismatch between function signature & arguments."); |
2282 | unsigned ArgNo = 0; |
2283 | CGFunctionInfo::const_arg_iterator info_it = FI.arg_begin(); |
2284 | for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); |
2285 | i != e; ++i, ++info_it, ++ArgNo) { |
2286 | const VarDecl *Arg = *i; |
2287 | const ABIArgInfo &ArgI = info_it->info; |
2288 | |
2289 | bool isPromoted = |
2290 | isa<ParmVarDecl>(Arg) && cast<ParmVarDecl>(Arg)->isKNRPromoted(); |
2291 | |
2292 | |
2293 | |
2294 | QualType Ty = isPromoted ? info_it->type : Arg->getType(); |
2295 | getType())", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2296, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(hasScalarEvaluationKind(Ty) == |
2296 | getType())", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2296, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> hasScalarEvaluationKind(Arg->getType())); |
2297 | |
2298 | unsigned FirstIRArg, NumIRArgs; |
2299 | std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo); |
2300 | |
2301 | switch (ArgI.getKind()) { |
2302 | case ABIArgInfo::InAlloca: { |
2303 | assert(NumIRArgs == 0); |
2304 | auto FieldIndex = ArgI.getInAllocaFieldIndex(); |
2305 | Address V = |
2306 | Builder.CreateStructGEP(ArgStruct, FieldIndex, Arg->getName()); |
2307 | ArgVals.push_back(ParamValue::forIndirect(V)); |
2308 | break; |
2309 | } |
2310 | |
2311 | case ABIArgInfo::Indirect: { |
2312 | assert(NumIRArgs == 1); |
2313 | Address ParamAddr = Address(FnArgs[FirstIRArg], ArgI.getIndirectAlign()); |
2314 | |
2315 | if (!hasScalarEvaluationKind(Ty)) { |
2316 | |
2317 | |
2318 | Address V = ParamAddr; |
2319 | if (ArgI.getIndirectRealign()) { |
2320 | Address AlignedTemp = CreateMemTemp(Ty, "coerce"); |
2321 | |
2322 | |
2323 | |
2324 | |
2325 | |
2326 | |
2327 | CharUnits Size = getContext().getTypeSizeInChars(Ty); |
2328 | auto SizeVal = llvm::ConstantInt::get(IntPtrTy, Size.getQuantity()); |
2329 | Address Dst = Builder.CreateBitCast(AlignedTemp, Int8PtrTy); |
2330 | Address Src = Builder.CreateBitCast(ParamAddr, Int8PtrTy); |
2331 | Builder.CreateMemCpy(Dst, Src, SizeVal, false); |
2332 | V = AlignedTemp; |
2333 | } |
2334 | ArgVals.push_back(ParamValue::forIndirect(V)); |
2335 | } else { |
2336 | |
2337 | llvm::Value *V = |
2338 | EmitLoadOfScalar(ParamAddr, false, Ty, Arg->getBeginLoc()); |
2339 | |
2340 | if (isPromoted) |
2341 | V = emitArgumentDemotion(*this, Arg, V); |
2342 | ArgVals.push_back(ParamValue::forDirect(V)); |
2343 | } |
2344 | break; |
2345 | } |
2346 | |
2347 | case ABIArgInfo::Extend: |
2348 | case ABIArgInfo::Direct: { |
2349 | |
2350 | |
2351 | if (!isa<llvm::StructType>(ArgI.getCoerceToType()) && |
2352 | ArgI.getCoerceToType() == ConvertType(Ty) && |
2353 | ArgI.getDirectOffset() == 0) { |
2354 | assert(NumIRArgs == 1); |
2355 | llvm::Value *V = FnArgs[FirstIRArg]; |
2356 | auto AI = cast<llvm::Argument>(V); |
2357 | |
2358 | if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) { |
2359 | if (getNonNullAttr(CurCodeDecl, PVD, PVD->getType(), |
2360 | PVD->getFunctionScopeIndex()) && |
2361 | !CGM.getCodeGenOpts().NullPointerIsValid) |
2362 | AI->addAttr(llvm::Attribute::NonNull); |
2363 | |
2364 | QualType OTy = PVD->getOriginalType(); |
2365 | if (const auto *ArrTy = |
2366 | getContext().getAsConstantArrayType(OTy)) { |
2367 | |
2368 | |
2369 | |
2370 | |
2371 | if (ArrTy->getSizeModifier() == ArrayType::Static) { |
2372 | QualType ETy = ArrTy->getElementType(); |
2373 | uint64_t ArrSize = ArrTy->getSize().getZExtValue(); |
2374 | if (!ETy->isIncompleteType() && ETy->isConstantSizeType() && |
2375 | ArrSize) { |
2376 | llvm::AttrBuilder Attrs; |
2377 | Attrs.addDereferenceableAttr( |
2378 | getContext().getTypeSizeInChars(ETy).getQuantity()*ArrSize); |
2379 | AI->addAttrs(Attrs); |
2380 | } else if (getContext().getTargetAddressSpace(ETy) == 0 && |
2381 | !CGM.getCodeGenOpts().NullPointerIsValid) { |
2382 | AI->addAttr(llvm::Attribute::NonNull); |
2383 | } |
2384 | } |
2385 | } else if (const auto *ArrTy = |
2386 | getContext().getAsVariableArrayType(OTy)) { |
2387 | |
2388 | |
2389 | |
2390 | if (ArrTy->getSizeModifier() == VariableArrayType::Static && |
2391 | !getContext().getTargetAddressSpace(ArrTy->getElementType()) && |
2392 | !CGM.getCodeGenOpts().NullPointerIsValid) |
2393 | AI->addAttr(llvm::Attribute::NonNull); |
2394 | } |
2395 | |
2396 | const auto *AVAttr = PVD->getAttr<AlignValueAttr>(); |
2397 | if (!AVAttr) |
2398 | if (const auto *TOTy = dyn_cast<TypedefType>(OTy)) |
2399 | AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>(); |
2400 | if (AVAttr && !SanOpts.has(SanitizerKind::Alignment)) { |
2401 | |
2402 | |
2403 | |
2404 | llvm::Value *AlignmentValue = |
2405 | EmitScalarExpr(AVAttr->getAlignment()); |
2406 | llvm::ConstantInt *AlignmentCI = |
2407 | cast<llvm::ConstantInt>(AlignmentValue); |
2408 | unsigned Alignment = std::min((unsigned)AlignmentCI->getZExtValue(), |
2409 | +llvm::Value::MaximumAlignment); |
2410 | AI->addAttrs(llvm::AttrBuilder().addAlignmentAttr(Alignment)); |
2411 | } |
2412 | } |
2413 | |
2414 | if (Arg->getType().isRestrictQualified()) |
2415 | AI->addAttr(llvm::Attribute::NoAlias); |
2416 | |
2417 | |
2418 | |
2419 | if (FI.getExtParameterInfo(ArgNo).getABI() |
2420 | == ParameterABI::SwiftErrorResult) { |
2421 | QualType pointeeTy = Ty->getPointeeType(); |
2422 | isPointerType()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2422, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(pointeeTy->isPointerType()); |
2423 | Address temp = |
2424 | CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp"); |
2425 | Address arg = Address(V, getContext().getTypeAlignInChars(pointeeTy)); |
2426 | llvm::Value *incomingErrorValue = Builder.CreateLoad(arg); |
2427 | Builder.CreateStore(incomingErrorValue, temp); |
2428 | V = temp.getPointer(); |
2429 | |
2430 | |
2431 | |
2432 | |
2433 | EHStack.pushCleanup<CopyBackSwiftError>(NormalCleanup, temp, arg); |
2434 | } |
2435 | |
2436 | |
2437 | if (V->getType() != ArgI.getCoerceToType()) |
2438 | V = Builder.CreateBitCast(V, ArgI.getCoerceToType()); |
2439 | |
2440 | if (isPromoted) |
2441 | V = emitArgumentDemotion(*this, Arg, V); |
2442 | |
2443 | |
2444 | |
2445 | |
2446 | |
2447 | llvm::Type *LTy = ConvertType(Arg->getType()); |
2448 | if (V->getType() != LTy) |
2449 | V = Builder.CreateBitCast(V, LTy); |
2450 | |
2451 | ArgVals.push_back(ParamValue::forDirect(V)); |
2452 | break; |
2453 | } |
2454 | |
2455 | Address Alloca = CreateMemTemp(Ty, getContext().getDeclAlign(Arg), |
2456 | Arg->getName()); |
2457 | |
2458 | |
2459 | Address Ptr = emitAddressAtOffset(*this, Alloca, ArgI); |
2460 | |
2461 | |
2462 | |
2463 | llvm::StructType *STy = dyn_cast<llvm::StructType>(ArgI.getCoerceToType()); |
2464 | if (ArgI.isDirect() && ArgI.getCanBeFlattened() && STy && |
2465 | STy->getNumElements() > 1) { |
2466 | uint64_t SrcSize = CGM.getDataLayout().getTypeAllocSize(STy); |
2467 | llvm::Type *DstTy = Ptr.getElementType(); |
2468 | uint64_t DstSize = CGM.getDataLayout().getTypeAllocSize(DstTy); |
2469 | |
2470 | Address AddrToStoreInto = Address::invalid(); |
2471 | if (SrcSize <= DstSize) { |
2472 | AddrToStoreInto = Builder.CreateElementBitCast(Ptr, STy); |
2473 | } else { |
2474 | AddrToStoreInto = |
2475 | CreateTempAlloca(STy, Alloca.getAlignment(), "coerce"); |
2476 | } |
2477 | |
2478 | getNumElements() == NumIRArgs", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2478, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(STy->getNumElements() == NumIRArgs); |
2479 | for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { |
2480 | auto AI = FnArgs[FirstIRArg + i]; |
2481 | AI->setName(Arg->getName() + ".coerce" + Twine(i)); |
2482 | Address EltPtr = Builder.CreateStructGEP(AddrToStoreInto, i); |
2483 | Builder.CreateStore(AI, EltPtr); |
2484 | } |
2485 | |
2486 | if (SrcSize > DstSize) { |
2487 | Builder.CreateMemCpy(Ptr, AddrToStoreInto, DstSize); |
2488 | } |
2489 | |
2490 | } else { |
2491 | |
2492 | assert(NumIRArgs == 1); |
2493 | auto AI = FnArgs[FirstIRArg]; |
2494 | AI->setName(Arg->getName() + ".coerce"); |
2495 | CreateCoercedStore(AI, Ptr, , *this); |
2496 | } |
2497 | |
2498 | |
2499 | if (CodeGenFunction::hasScalarEvaluationKind(Ty)) { |
2500 | llvm::Value *V = |
2501 | EmitLoadOfScalar(Alloca, false, Ty, Arg->getBeginLoc()); |
2502 | if (isPromoted) |
2503 | V = emitArgumentDemotion(*this, Arg, V); |
2504 | ArgVals.push_back(ParamValue::forDirect(V)); |
2505 | } else { |
2506 | ArgVals.push_back(ParamValue::forIndirect(Alloca)); |
2507 | } |
2508 | break; |
2509 | } |
2510 | |
2511 | case ABIArgInfo::CoerceAndExpand: { |
2512 | |
2513 | Address alloca = CreateMemTemp(Ty, getContext().getDeclAlign(Arg)); |
2514 | ArgVals.push_back(ParamValue::forIndirect(alloca)); |
2515 | |
2516 | auto coercionType = ArgI.getCoerceAndExpandType(); |
2517 | alloca = Builder.CreateElementBitCast(alloca, coercionType); |
2518 | |
2519 | unsigned argIndex = FirstIRArg; |
2520 | for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) { |
2521 | llvm::Type *eltType = coercionType->getElementType(i); |
2522 | if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType)) |
2523 | continue; |
2524 | |
2525 | auto eltAddr = Builder.CreateStructGEP(alloca, i); |
2526 | auto elt = FnArgs[argIndex++]; |
2527 | Builder.CreateStore(elt, eltAddr); |
2528 | } |
2529 | assert(argIndex == FirstIRArg + NumIRArgs); |
2530 | break; |
2531 | } |
2532 | |
2533 | case ABIArgInfo::Expand: { |
2534 | |
2535 | |
2536 | |
2537 | Address Alloca = CreateMemTemp(Ty, getContext().getDeclAlign(Arg)); |
2538 | LValue LV = MakeAddrLValue(Alloca, Ty); |
2539 | ArgVals.push_back(ParamValue::forIndirect(Alloca)); |
2540 | |
2541 | auto FnArgIter = FnArgs.begin() + FirstIRArg; |
2542 | ExpandTypeFromArgs(Ty, LV, FnArgIter); |
2543 | assert(FnArgIter == FnArgs.begin() + FirstIRArg + NumIRArgs); |
2544 | for (unsigned i = 0, e = NumIRArgs; i != e; ++i) { |
2545 | auto AI = FnArgs[FirstIRArg + i]; |
2546 | AI->setName(Arg->getName() + "." + Twine(i)); |
2547 | } |
2548 | break; |
2549 | } |
2550 | |
2551 | case ABIArgInfo::Ignore: |
2552 | assert(NumIRArgs == 0); |
2553 | |
2554 | if (!hasScalarEvaluationKind(Ty)) { |
2555 | ArgVals.push_back(ParamValue::forIndirect(CreateMemTemp(Ty))); |
2556 | } else { |
2557 | llvm::Value *U = llvm::UndefValue::get(ConvertType(Arg->getType())); |
2558 | ArgVals.push_back(ParamValue::forDirect(U)); |
2559 | } |
2560 | break; |
2561 | } |
2562 | } |
2563 | |
2564 | if (getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) { |
2565 | for (int I = Args.size() - 1; I >= 0; --I) |
2566 | EmitParmDecl(*Args[I], ArgVals[I], I + 1); |
2567 | } else { |
2568 | for (unsigned I = 0, E = Args.size(); I != E; ++I) |
2569 | EmitParmDecl(*Args[I], ArgVals[I], I + 1); |
2570 | } |
2571 | } |
2572 | |
2573 | static void eraseUnusedBitCasts(llvm::Instruction *insn) { |
2574 | while (insn->use_empty()) { |
2575 | llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(insn); |
2576 | if (!bitcast) return; |
2577 | |
2578 | |
2579 | insn = cast<llvm::Instruction>(bitcast->getOperand(0)); |
2580 | bitcast->eraseFromParent(); |
2581 | } |
2582 | } |
2583 | |
2584 | |
2585 | static llvm::Value *tryEmitFusedAutoreleaseOfResult(CodeGenFunction &CGF, |
2586 | llvm::Value *result) { |
2587 | |
2588 | llvm::BasicBlock *BB = CGF.Builder.GetInsertBlock(); |
2589 | if (BB->empty()) return nullptr; |
2590 | if (&BB->back() != result) return nullptr; |
2591 | |
2592 | llvm::Type *resultType = result->getType(); |
2593 | |
2594 | |
2595 | llvm::Instruction *generator = cast<llvm::Instruction>(result); |
2596 | |
2597 | SmallVector<llvm::Instruction *, 4> InstsToKill; |
2598 | |
2599 | |
2600 | |
2601 | while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(generator)) { |
2602 | |
2603 | |
2604 | generator = cast<llvm::Instruction>(bitcast->getOperand(0)); |
2605 | |
2606 | |
2607 | if (generator->getNextNode() != bitcast) |
2608 | return nullptr; |
2609 | |
2610 | InstsToKill.push_back(bitcast); |
2611 | } |
2612 | |
2613 | |
2614 | |
2615 | |
2616 | |
2617 | llvm::CallInst *call = dyn_cast<llvm::CallInst>(generator); |
2618 | if (!call) return nullptr; |
2619 | |
2620 | bool doRetainAutorelease; |
2621 | |
2622 | if (call->getCalledValue() == CGF.CGM.getObjCEntrypoints().objc_retain) { |
2623 | doRetainAutorelease = true; |
2624 | } else if (call->getCalledValue() == CGF.CGM.getObjCEntrypoints() |
2625 | .objc_retainAutoreleasedReturnValue) { |
2626 | doRetainAutorelease = false; |
2627 | |
2628 | |
2629 | |
2630 | |
2631 | |
2632 | |
2633 | if (CGF.CGM.getObjCEntrypoints().retainAutoreleasedReturnValueMarker) { |
2634 | llvm::Instruction *prev = call->getPrevNode(); |
2635 | assert(prev); |
2636 | if (isa<llvm::BitCastInst>(prev)) { |
2637 | prev = prev->getPrevNode(); |
2638 | assert(prev); |
2639 | } |
2640 | (prev)", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2640, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<llvm::CallInst>(prev)); |
2641 | (prev)->getCalledValue() == CGF.CGM.getObjCEntrypoints().retainAutoreleasedReturnValueMarker", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2642, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(cast<llvm::CallInst>(prev)->getCalledValue() == |
2642 | (prev)->getCalledValue() == CGF.CGM.getObjCEntrypoints().retainAutoreleasedReturnValueMarker", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2642, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> CGF.CGM.getObjCEntrypoints().retainAutoreleasedReturnValueMarker); |
2643 | InstsToKill.push_back(prev); |
2644 | } |
2645 | } else { |
2646 | return nullptr; |
2647 | } |
2648 | |
2649 | result = call->getArgOperand(0); |
2650 | InstsToKill.push_back(call); |
2651 | |
2652 | |
2653 | |
2654 | while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(result)) { |
2655 | if (!bitcast->hasOneUse()) break; |
2656 | InstsToKill.push_back(bitcast); |
2657 | result = bitcast->getOperand(0); |
2658 | } |
2659 | |
2660 | |
2661 | for (auto *I : InstsToKill) |
2662 | I->eraseFromParent(); |
2663 | |
2664 | |
2665 | if (doRetainAutorelease) |
2666 | result = CGF.EmitARCRetainAutoreleaseReturnValue(result); |
2667 | |
2668 | |
2669 | return CGF.Builder.CreateBitCast(result, resultType); |
2670 | } |
2671 | |
2672 | |
2673 | static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF, |
2674 | llvm::Value *result) { |
2675 | |
2676 | const ObjCMethodDecl *method = |
2677 | dyn_cast_or_null<ObjCMethodDecl>(CGF.CurCodeDecl); |
2678 | if (!method) return nullptr; |
2679 | const VarDecl *self = method->getSelfDecl(); |
2680 | if (!self->getType().isConstQualified()) return nullptr; |
2681 | |
2682 | |
2683 | llvm::CallInst *retainCall = |
2684 | dyn_cast<llvm::CallInst>(result->stripPointerCasts()); |
2685 | if (!retainCall || |
2686 | retainCall->getCalledValue() != CGF.CGM.getObjCEntrypoints().objc_retain) |
2687 | return nullptr; |
2688 | |
2689 | |
2690 | llvm::Value *retainedValue = retainCall->getArgOperand(0); |
2691 | llvm::LoadInst *load = |
2692 | dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts()); |
2693 | if (!load || load->isAtomic() || load->isVolatile() || |
2694 | load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getPointer()) |
2695 | return nullptr; |
2696 | |
2697 | |
2698 | |
2699 | |
2700 | llvm::Type *resultType = result->getType(); |
2701 | eraseUnusedBitCasts(cast<llvm::Instruction>(result)); |
2702 | use_empty()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2702, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(retainCall->use_empty()); |
2703 | retainCall->eraseFromParent(); |
2704 | eraseUnusedBitCasts(cast<llvm::Instruction>(retainedValue)); |
2705 | |
2706 | return CGF.Builder.CreateBitCast(load, resultType); |
2707 | } |
2708 | |
2709 | |
2710 | |
2711 | |
2712 | static llvm::Value *emitAutoreleaseOfResult(CodeGenFunction &CGF, |
2713 | llvm::Value *result) { |
2714 | |
2715 | |
2716 | |
2717 | |
2718 | if (llvm::Value *self = tryRemoveRetainOfSelf(CGF, result)) |
2719 | return self; |
2720 | |
2721 | |
2722 | if (CGF.shouldUseFusedARCCalls()) |
2723 | if (llvm::Value *fused = tryEmitFusedAutoreleaseOfResult(CGF, result)) |
2724 | return fused; |
2725 | |
2726 | return CGF.EmitARCAutoreleaseReturnValue(result); |
2727 | } |
2728 | |
2729 | |
2730 | static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { |
2731 | |
2732 | |
2733 | |
2734 | auto GetStoreIfValid = [&CGF](llvm::User *U) -> llvm::StoreInst * { |
2735 | auto *SI = dyn_cast<llvm::StoreInst>(U); |
2736 | if (!SI || SI->getPointerOperand() != CGF.ReturnValue.getPointer()) |
2737 | return nullptr; |
2738 | |
2739 | |
2740 | isAtomic() && !SI->isVolatile()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2740, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!SI->isAtomic() && !SI->isVolatile()); |
2741 | return SI; |
2742 | }; |
2743 | |
2744 | |
2745 | |
2746 | |
2747 | if (!CGF.ReturnValue.getPointer()->hasOneUse()) { |
2748 | llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock(); |
2749 | if (IP->empty()) return nullptr; |
2750 | llvm::Instruction *I = &IP->back(); |
2751 | |
2752 | |
2753 | for (llvm::BasicBlock::reverse_iterator II = IP->rbegin(), |
2754 | IE = IP->rend(); |
2755 | II != IE; ++II) { |
2756 | if (llvm::IntrinsicInst *Intrinsic = |
2757 | dyn_cast<llvm::IntrinsicInst>(&*II)) { |
2758 | if (Intrinsic->getIntrinsicID() == llvm::Intrinsic::lifetime_end) { |
2759 | const llvm::Value *CastAddr = Intrinsic->getArgOperand(1); |
2760 | ++II; |
2761 | if (II == IE) |
2762 | break; |
2763 | if (isa<llvm::BitCastInst>(&*II) && (CastAddr == &*II)) |
2764 | continue; |
2765 | } |
2766 | } |
2767 | I = &*II; |
2768 | break; |
2769 | } |
2770 | |
2771 | return GetStoreIfValid(I); |
2772 | } |
2773 | |
2774 | llvm::StoreInst *store = |
2775 | GetStoreIfValid(CGF.ReturnValue.getPointer()->user_back()); |
2776 | if (!store) return nullptr; |
2777 | |
2778 | |
2779 | |
2780 | llvm::BasicBlock *StoreBB = store->getParent(); |
2781 | llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock(); |
2782 | while (IP != StoreBB) { |
2783 | if (!(IP = IP->getSinglePredecessor())) |
2784 | return nullptr; |
2785 | } |
2786 | |
2787 | |
2788 | |
2789 | return store; |
2790 | } |
2791 | |
2792 | void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, |
2793 | bool EmitRetDbgLoc, |
2794 | SourceLocation EndLoc) { |
2795 | if (FI.isNoReturn()) { |
2796 | |
2797 | EmitUnreachable(EndLoc); |
2798 | return; |
2799 | } |
2800 | |
2801 | if (CurCodeDecl && CurCodeDecl->hasAttr<NakedAttr>()) { |
2802 | |
2803 | Builder.CreateUnreachable(); |
2804 | return; |
2805 | } |
2806 | |
2807 | |
2808 | if (!ReturnValue.isValid()) { |
2809 | Builder.CreateRetVoid(); |
2810 | return; |
2811 | } |
2812 | |
2813 | llvm::DebugLoc RetDbgLoc; |
2814 | llvm::Value *RV = nullptr; |
2815 | QualType RetTy = FI.getReturnType(); |
2816 | const ABIArgInfo &RetAI = FI.getReturnInfo(); |
2817 | |
2818 | switch (RetAI.getKind()) { |
2819 | case ABIArgInfo::InAlloca: |
2820 | |
2821 | |
2822 | assert(hasAggregateEvaluationKind(RetTy)); |
2823 | if (RetAI.getInAllocaSRet()) { |
2824 | llvm::Function::arg_iterator EI = CurFn->arg_end(); |
2825 | --EI; |
2826 | llvm::Value *ArgStruct = &*EI; |
2827 | llvm::Value *SRet = Builder.CreateStructGEP( |
2828 | nullptr, ArgStruct, RetAI.getInAllocaFieldIndex()); |
2829 | RV = Builder.CreateAlignedLoad(SRet, getPointerAlign(), "sret"); |
2830 | } |
2831 | break; |
2832 | |
2833 | case ABIArgInfo::Indirect: { |
2834 | auto AI = CurFn->arg_begin(); |
2835 | if (RetAI.isSRetAfterThis()) |
2836 | ++AI; |
2837 | switch (getEvaluationKind(RetTy)) { |
2838 | case TEK_Complex: { |
2839 | ComplexPairTy RT = |
2840 | EmitLoadOfComplex(MakeAddrLValue(ReturnValue, RetTy), EndLoc); |
2841 | EmitStoreOfComplex(RT, MakeNaturalAlignAddrLValue(&*AI, RetTy), |
2842 | true); |
2843 | break; |
2844 | } |
2845 | case TEK_Aggregate: |
2846 | |
2847 | break; |
2848 | case TEK_Scalar: |
2849 | EmitStoreOfScalar(Builder.CreateLoad(ReturnValue), |
2850 | MakeNaturalAlignAddrLValue(&*AI, RetTy), |
2851 | true); |
2852 | break; |
2853 | } |
2854 | break; |
2855 | } |
2856 | |
2857 | case ABIArgInfo::Extend: |
2858 | case ABIArgInfo::Direct: |
2859 | if (RetAI.getCoerceToType() == ConvertType(RetTy) && |
2860 | RetAI.getDirectOffset() == 0) { |
2861 | |
2862 | |
2863 | |
2864 | |
2865 | |
2866 | if (llvm::StoreInst *SI = |
2867 | findDominatingStoreToReturnValue(*this)) { |
2868 | |
2869 | |
2870 | |
2871 | if (EmitRetDbgLoc && !AutoreleaseResult) |
2872 | RetDbgLoc = SI->getDebugLoc(); |
2873 | |
2874 | RV = SI->getValueOperand(); |
2875 | SI->eraseFromParent(); |
2876 | |
2877 | |
2878 | auto returnValueInst = ReturnValue.getPointer(); |
2879 | if (returnValueInst->use_empty()) { |
2880 | if (auto alloca = dyn_cast<llvm::AllocaInst>(returnValueInst)) { |
2881 | alloca->eraseFromParent(); |
2882 | ReturnValue = Address::invalid(); |
2883 | } |
2884 | } |
2885 | |
2886 | |
2887 | } else { |
2888 | RV = Builder.CreateLoad(ReturnValue); |
2889 | } |
2890 | } else { |
2891 | |
2892 | Address V = emitAddressAtOffset(*this, ReturnValue, RetAI); |
2893 | |
2894 | RV = CreateCoercedLoad(V, RetAI.getCoerceToType(), *this); |
2895 | } |
2896 | |
2897 | |
2898 | |
2899 | if (AutoreleaseResult) { |
2900 | #ifndef NDEBUG |
2901 | |
2902 | |
2903 | |
2904 | |
2905 | QualType RT; |
2906 | |
2907 | if (auto *FD = dyn_cast<FunctionDecl>(CurCodeDecl)) |
2908 | RT = FD->getReturnType(); |
2909 | else if (auto *MD = dyn_cast<ObjCMethodDecl>(CurCodeDecl)) |
2910 | RT = MD->getReturnType(); |
2911 | else if (isa<BlockDecl>(CurCodeDecl)) |
2912 | RT = BlockInfo->BlockExpression->getFunctionType()->getReturnType(); |
2913 | else |
2914 | llvm_unreachable("Unexpected function/method type"); |
2915 | |
2916 | isObjCRetainableType()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2918, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getLangOpts().ObjCAutoRefCount && |
2917 | isObjCRetainableType()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2918, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> !FI.isReturnsRetained() && |
2918 | isObjCRetainableType()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2918, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> RT->isObjCRetainableType()); |
2919 | #endif |
2920 | RV = emitAutoreleaseOfResult(*this, RV); |
2921 | } |
2922 | |
2923 | break; |
2924 | |
2925 | case ABIArgInfo::Ignore: |
2926 | break; |
2927 | |
2928 | case ABIArgInfo::CoerceAndExpand: { |
2929 | auto coercionType = RetAI.getCoerceAndExpandType(); |
2930 | |
2931 | |
2932 | llvm::SmallVector<llvm::Value*, 4> results; |
2933 | Address addr = Builder.CreateElementBitCast(ReturnValue, coercionType); |
2934 | for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) { |
2935 | auto coercedEltType = coercionType->getElementType(i); |
2936 | if (ABIArgInfo::isPaddingForCoerceAndExpand(coercedEltType)) |
2937 | continue; |
2938 | |
2939 | auto eltAddr = Builder.CreateStructGEP(addr, i); |
2940 | auto elt = Builder.CreateLoad(eltAddr); |
2941 | results.push_back(elt); |
2942 | } |
2943 | |
2944 | |
2945 | if (results.size() == 1) { |
2946 | RV = results[0]; |
2947 | |
2948 | |
2949 | } else { |
2950 | |
2951 | llvm::Type *returnType = RetAI.getUnpaddedCoerceAndExpandType(); |
2952 | |
2953 | RV = llvm::UndefValue::get(returnType); |
2954 | for (unsigned i = 0, e = results.size(); i != e; ++i) { |
2955 | RV = Builder.CreateInsertValue(RV, results[i], i); |
2956 | } |
2957 | } |
2958 | break; |
2959 | } |
2960 | |
2961 | case ABIArgInfo::Expand: |
2962 | llvm_unreachable("Invalid ABI kind for return argument"); |
2963 | } |
2964 | |
2965 | llvm::Instruction *Ret; |
2966 | if (RV) { |
2967 | EmitReturnValueCheck(RV); |
2968 | Ret = Builder.CreateRet(RV); |
2969 | } else { |
2970 | Ret = Builder.CreateRetVoid(); |
2971 | } |
2972 | |
2973 | if (RetDbgLoc) |
2974 | Ret->setDebugLoc(std::move(RetDbgLoc)); |
2975 | } |
2976 | |
2977 | void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV) { |
2978 | |
2979 | if (!CurCodeDecl) |
2980 | return; |
2981 | |
2982 | ReturnsNonNullAttr *RetNNAttr = nullptr; |
2983 | if (SanOpts.has(SanitizerKind::ReturnsNonnullAttribute)) |
2984 | RetNNAttr = CurCodeDecl->getAttr<ReturnsNonNullAttr>(); |
2985 | |
2986 | if (!RetNNAttr && !requiresReturnValueNullabilityCheck()) |
2987 | return; |
2988 | |
2989 | |
2990 | SourceLocation AttrLoc; |
2991 | SanitizerMask CheckKind; |
2992 | SanitizerHandler Handler; |
2993 | if (RetNNAttr) { |
2994 | (0) . __assert_fail ("!requiresReturnValueNullabilityCheck() && \"Cannot check nullability and the nonnull attribute\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2995, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!requiresReturnValueNullabilityCheck() && |
2995 | (0) . __assert_fail ("!requiresReturnValueNullabilityCheck() && \"Cannot check nullability and the nonnull attribute\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 2995, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Cannot check nullability and the nonnull attribute"); |
2996 | AttrLoc = RetNNAttr->getLocation(); |
2997 | CheckKind = SanitizerKind::ReturnsNonnullAttribute; |
2998 | Handler = SanitizerHandler::NonnullReturn; |
2999 | } else { |
3000 | if (auto *DD = dyn_cast<DeclaratorDecl>(CurCodeDecl)) |
3001 | if (auto *TSI = DD->getTypeSourceInfo()) |
3002 | if (auto FTL = TSI->getTypeLoc().castAs<FunctionTypeLoc>()) |
3003 | AttrLoc = FTL.getReturnLoc().findNullabilityLoc(); |
3004 | CheckKind = SanitizerKind::NullabilityReturn; |
3005 | Handler = SanitizerHandler::NullabilityReturn; |
3006 | } |
3007 | |
3008 | SanitizerScope SanScope(this); |
3009 | |
3010 | |
3011 | |
3012 | llvm::BasicBlock *Check = createBasicBlock("nullcheck"); |
3013 | llvm::BasicBlock *NoCheck = createBasicBlock("no.nullcheck"); |
3014 | llvm::Value *SLocPtr = Builder.CreateLoad(ReturnLocation, "return.sloc.load"); |
3015 | llvm::Value *CanNullCheck = Builder.CreateIsNotNull(SLocPtr); |
3016 | if (requiresReturnValueNullabilityCheck()) |
3017 | CanNullCheck = |
3018 | Builder.CreateAnd(CanNullCheck, RetValNullabilityPrecondition); |
3019 | Builder.CreateCondBr(CanNullCheck, Check, NoCheck); |
3020 | EmitBlock(Check); |
3021 | |
3022 | |
3023 | llvm::Value *Cond = Builder.CreateIsNotNull(RV); |
3024 | llvm::Constant *StaticData[] = {EmitCheckSourceLocation(AttrLoc)}; |
3025 | llvm::Value *DynamicData[] = {SLocPtr}; |
3026 | EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, DynamicData); |
3027 | |
3028 | EmitBlock(NoCheck); |
3029 | |
3030 | #ifndef NDEBUG |
3031 | |
3032 | ReturnLocation = Address::invalid(); |
3033 | #endif |
3034 | } |
3035 | |
3036 | static bool isInAllocaArgument(CGCXXABI &ABI, QualType type) { |
3037 | const CXXRecordDecl *RD = type->getAsCXXRecordDecl(); |
3038 | return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory; |
3039 | } |
3040 | |
3041 | static AggValueSlot createPlaceholderSlot(CodeGenFunction &CGF, |
3042 | QualType Ty) { |
3043 | |
3044 | |
3045 | llvm::Type *IRTy = CGF.ConvertTypeForMem(Ty); |
3046 | llvm::Type *IRPtrTy = IRTy->getPointerTo(); |
3047 | llvm::Value *Placeholder = llvm::UndefValue::get(IRPtrTy->getPointerTo()); |
3048 | |
3049 | |
3050 | |
3051 | CharUnits Align = CharUnits::fromQuantity(4); |
3052 | Placeholder = CGF.Builder.CreateAlignedLoad(IRPtrTy, Placeholder, Align); |
3053 | |
3054 | return AggValueSlot::forAddr(Address(Placeholder, Align), |
3055 | Ty.getQualifiers(), |
3056 | AggValueSlot::IsNotDestructed, |
3057 | AggValueSlot::DoesNotNeedGCBarriers, |
3058 | AggValueSlot::IsNotAliased, |
3059 | AggValueSlot::DoesNotOverlap); |
3060 | } |
3061 | |
3062 | void CodeGenFunction::EmitDelegateCallArg(CallArgList &args, |
3063 | const VarDecl *param, |
3064 | SourceLocation loc) { |
3065 | |
3066 | |
3067 | |
3068 | Address local = GetAddrOfLocalVar(param); |
3069 | |
3070 | QualType type = param->getType(); |
3071 | |
3072 | if (isInAllocaArgument(CGM.getCXXABI(), type)) { |
3073 | CGM.ErrorUnsupported(param, "forwarded non-trivially copyable parameter"); |
3074 | } |
3075 | |
3076 | |
3077 | |
3078 | if (type->isReferenceType()) { |
3079 | args.add(RValue::get(Builder.CreateLoad(local)), type); |
3080 | |
3081 | |
3082 | |
3083 | |
3084 | |
3085 | |
3086 | } else if (getLangOpts().ObjCAutoRefCount && |
3087 | param->hasAttr<NSConsumedAttr>() && |
3088 | type->isObjCRetainableType()) { |
3089 | llvm::Value *ptr = Builder.CreateLoad(local); |
3090 | auto null = |
3091 | llvm::ConstantPointerNull::get(cast<llvm::PointerType>(ptr->getType())); |
3092 | Builder.CreateStore(null, local); |
3093 | args.add(RValue::get(ptr), type); |
3094 | |
3095 | |
3096 | |
3097 | } else { |
3098 | args.add(convertTempToRValue(local, type, loc), type); |
3099 | } |
3100 | |
3101 | |
3102 | if (hasAggregateEvaluationKind(type) && !CurFuncIsThunk && |
3103 | type->getAs<RecordType>()->getDecl()->isParamDestroyedInCallee() && |
3104 | type.isDestructedType()) { |
3105 | EHScopeStack::stable_iterator cleanup = |
3106 | CalleeDestructedParamCleanups.lookup(cast<ParmVarDecl>(param)); |
3107 | (0) . __assert_fail ("cleanup.isValid() && \"cleanup for callee-destructed param not recorded\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3108, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(cleanup.isValid() && |
3108 | (0) . __assert_fail ("cleanup.isValid() && \"cleanup for callee-destructed param not recorded\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3108, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "cleanup for callee-destructed param not recorded"); |
3109 | |
3110 | llvm::Instruction *isActive = Builder.CreateUnreachable(); |
3111 | args.addArgCleanupDeactivation(cleanup, isActive); |
3112 | } |
3113 | } |
3114 | |
3115 | static bool isProvablyNull(llvm::Value *addr) { |
3116 | return isa<llvm::ConstantPointerNull>(addr); |
3117 | } |
3118 | |
3119 | |
3120 | static void emitWriteback(CodeGenFunction &CGF, |
3121 | const CallArgList::Writeback &writeback) { |
3122 | const LValue &srcLV = writeback.Source; |
3123 | Address srcAddr = srcLV.getAddress(); |
3124 | (0) . __assert_fail ("!isProvablyNull(srcAddr.getPointer()) && \"shouldn't have writeback for provably null argument\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3125, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isProvablyNull(srcAddr.getPointer()) && |
3125 | (0) . __assert_fail ("!isProvablyNull(srcAddr.getPointer()) && \"shouldn't have writeback for provably null argument\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3125, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "shouldn't have writeback for provably null argument"); |
3126 | |
3127 | llvm::BasicBlock *contBB = nullptr; |
3128 | |
3129 | |
3130 | |
3131 | bool provablyNonNull = llvm::isKnownNonZero(srcAddr.getPointer(), |
3132 | CGF.CGM.getDataLayout()); |
3133 | if (!provablyNonNull) { |
3134 | llvm::BasicBlock *writebackBB = CGF.createBasicBlock("icr.writeback"); |
3135 | contBB = CGF.createBasicBlock("icr.done"); |
3136 | |
3137 | llvm::Value *isNull = |
3138 | CGF.Builder.CreateIsNull(srcAddr.getPointer(), "icr.isnull"); |
3139 | CGF.Builder.CreateCondBr(isNull, contBB, writebackBB); |
3140 | CGF.EmitBlock(writebackBB); |
3141 | } |
3142 | |
3143 | |
3144 | llvm::Value *value = CGF.Builder.CreateLoad(writeback.Temporary); |
3145 | |
3146 | |
3147 | value = CGF.Builder.CreateBitCast(value, srcAddr.getElementType(), |
3148 | "icr.writeback-cast"); |
3149 | |
3150 | |
3151 | |
3152 | |
3153 | |
3154 | |
3155 | |
3156 | |
3157 | if (writeback.ToUse) { |
3158 | assert(srcLV.getObjCLifetime() == Qualifiers::OCL_Strong); |
3159 | |
3160 | |
3161 | |
3162 | value = CGF.EmitARCRetainNonBlock(value); |
3163 | |
3164 | |
3165 | CGF.EmitARCIntrinsicUse(writeback.ToUse); |
3166 | |
3167 | |
3168 | llvm::Value *oldValue = CGF.EmitLoadOfScalar(srcLV, SourceLocation()); |
3169 | |
3170 | |
3171 | CGF.EmitStoreOfScalar(value, srcLV, false); |
3172 | |
3173 | |
3174 | CGF.EmitARCRelease(oldValue, srcLV.isARCPreciseLifetime()); |
3175 | |
3176 | |
3177 | } else { |
3178 | CGF.EmitStoreThroughLValue(RValue::get(value), srcLV); |
3179 | } |
3180 | |
3181 | |
3182 | if (!provablyNonNull) |
3183 | CGF.EmitBlock(contBB); |
3184 | } |
3185 | |
3186 | static void emitWritebacks(CodeGenFunction &CGF, |
3187 | const CallArgList &args) { |
3188 | for (const auto &I : args.writebacks()) |
3189 | emitWriteback(CGF, I); |
3190 | } |
3191 | |
3192 | static void deactivateArgCleanupsBeforeCall(CodeGenFunction &CGF, |
3193 | const CallArgList &CallArgs) { |
3194 | ArrayRef<CallArgList::CallArgCleanup> Cleanups = |
3195 | CallArgs.getCleanupsToDeactivate(); |
3196 | |
3197 | for (const auto &I : llvm::reverse(Cleanups)) { |
3198 | CGF.DeactivateCleanupBlock(I.Cleanup, I.IsActiveIP); |
3199 | I.IsActiveIP->eraseFromParent(); |
3200 | } |
3201 | } |
3202 | |
3203 | static const Expr *maybeGetUnaryAddrOfOperand(const Expr *E) { |
3204 | if (const UnaryOperator *uop = dyn_cast<UnaryOperator>(E->IgnoreParens())) |
3205 | if (uop->getOpcode() == UO_AddrOf) |
3206 | return uop->getSubExpr(); |
3207 | return nullptr; |
3208 | } |
3209 | |
3210 | |
3211 | |
3212 | |
3213 | |
3214 | static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, |
3215 | const ObjCIndirectCopyRestoreExpr *CRE) { |
3216 | LValue srcLV; |
3217 | |
3218 | |
3219 | |
3220 | if (const Expr *lvExpr = maybeGetUnaryAddrOfOperand(CRE->getSubExpr())) { |
3221 | srcLV = CGF.EmitLValue(lvExpr); |
3222 | |
3223 | |
3224 | } else { |
3225 | Address srcAddr = CGF.EmitPointerWithAlignment(CRE->getSubExpr()); |
3226 | |
3227 | QualType srcAddrType = |
3228 | CRE->getSubExpr()->getType()->castAs<PointerType>()->getPointeeType(); |
3229 | srcLV = CGF.MakeAddrLValue(srcAddr, srcAddrType); |
3230 | } |
3231 | Address srcAddr = srcLV.getAddress(); |
3232 | |
3233 | |
3234 | |
3235 | |
3236 | llvm::PointerType *destType = |
3237 | cast<llvm::PointerType>(CGF.ConvertType(CRE->getType())); |
3238 | |
3239 | |
3240 | if (isProvablyNull(srcAddr.getPointer())) { |
3241 | args.add(RValue::get(llvm::ConstantPointerNull::get(destType)), |
3242 | CRE->getType()); |
3243 | return; |
3244 | } |
3245 | |
3246 | |
3247 | Address temp = CGF.CreateTempAlloca(destType->getElementType(), |
3248 | CGF.getPointerAlign(), |
3249 | "icr.temp"); |
3250 | |
3251 | |
3252 | |
3253 | |
3254 | CodeGenFunction::ConditionalEvaluation condEval(CGF); |
3255 | |
3256 | |
3257 | bool shouldCopy = CRE->shouldCopy(); |
3258 | if (!shouldCopy) { |
3259 | llvm::Value *null = |
3260 | llvm::ConstantPointerNull::get( |
3261 | cast<llvm::PointerType>(destType->getElementType())); |
3262 | CGF.Builder.CreateStore(null, temp); |
3263 | } |
3264 | |
3265 | llvm::BasicBlock *contBB = nullptr; |
3266 | llvm::BasicBlock *originBB = nullptr; |
3267 | |
3268 | |
3269 | llvm::Value *finalArgument; |
3270 | |
3271 | bool provablyNonNull = llvm::isKnownNonZero(srcAddr.getPointer(), |
3272 | CGF.CGM.getDataLayout()); |
3273 | if (provablyNonNull) { |
3274 | finalArgument = temp.getPointer(); |
3275 | } else { |
3276 | llvm::Value *isNull = |
3277 | CGF.Builder.CreateIsNull(srcAddr.getPointer(), "icr.isnull"); |
3278 | |
3279 | finalArgument = CGF.Builder.CreateSelect(isNull, |
3280 | llvm::ConstantPointerNull::get(destType), |
3281 | temp.getPointer(), "icr.argument"); |
3282 | |
3283 | |
3284 | |
3285 | if (shouldCopy) { |
3286 | originBB = CGF.Builder.GetInsertBlock(); |
3287 | contBB = CGF.createBasicBlock("icr.cont"); |
3288 | llvm::BasicBlock *copyBB = CGF.createBasicBlock("icr.copy"); |
3289 | CGF.Builder.CreateCondBr(isNull, contBB, copyBB); |
3290 | CGF.EmitBlock(copyBB); |
3291 | condEval.begin(CGF); |
3292 | } |
3293 | } |
3294 | |
3295 | llvm::Value *valueToUse = nullptr; |
3296 | |
3297 | |
3298 | if (shouldCopy) { |
3299 | RValue srcRV = CGF.EmitLoadOfLValue(srcLV, SourceLocation()); |
3300 | assert(srcRV.isScalar()); |
3301 | |
3302 | llvm::Value *src = srcRV.getScalarVal(); |
3303 | src = CGF.Builder.CreateBitCast(src, destType->getElementType(), |
3304 | "icr.cast"); |
3305 | |
3306 | |
3307 | CGF.Builder.CreateStore(src, temp); |
3308 | |
3309 | |
3310 | |
3311 | |
3312 | |
3313 | |
3314 | if (CGF.CGM.getCodeGenOpts().OptimizationLevel != 0 && |
3315 | srcLV.getObjCLifetime() == Qualifiers::OCL_Strong) { |
3316 | valueToUse = src; |
3317 | } |
3318 | } |
3319 | |
3320 | |
3321 | if (shouldCopy && !provablyNonNull) { |
3322 | llvm::BasicBlock *copyBB = CGF.Builder.GetInsertBlock(); |
3323 | CGF.EmitBlock(contBB); |
3324 | |
3325 | |
3326 | if (valueToUse) { |
3327 | llvm::PHINode *phiToUse = CGF.Builder.CreatePHI(valueToUse->getType(), 2, |
3328 | "icr.to-use"); |
3329 | phiToUse->addIncoming(valueToUse, copyBB); |
3330 | phiToUse->addIncoming(llvm::UndefValue::get(valueToUse->getType()), |
3331 | originBB); |
3332 | valueToUse = phiToUse; |
3333 | } |
3334 | |
3335 | condEval.end(CGF); |
3336 | } |
3337 | |
3338 | args.addWriteback(srcLV, temp, valueToUse); |
3339 | args.add(RValue::get(finalArgument), CRE->getType()); |
3340 | } |
3341 | |
3342 | void CallArgList::allocateArgumentMemory(CodeGenFunction &CGF) { |
3343 | assert(!StackBase); |
3344 | |
3345 | |
3346 | llvm::Function *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stacksave); |
3347 | StackBase = CGF.Builder.CreateCall(F, {}, "inalloca.save"); |
3348 | } |
3349 | |
3350 | void CallArgList::freeArgumentMemory(CodeGenFunction &CGF) const { |
3351 | if (StackBase) { |
3352 | |
3353 | llvm::Function *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore); |
3354 | CGF.Builder.CreateCall(F, StackBase); |
3355 | } |
3356 | } |
3357 | |
3358 | void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType, |
3359 | SourceLocation ArgLoc, |
3360 | AbstractCallee AC, |
3361 | unsigned ParmNum) { |
3362 | if (!AC.getDecl() || !(SanOpts.has(SanitizerKind::NonnullAttribute) || |
3363 | SanOpts.has(SanitizerKind::NullabilityArg))) |
3364 | return; |
3365 | |
3366 | |
3367 | auto PVD = ParmNum < AC.getNumParams() ? AC.getParamDecl(ParmNum) : nullptr; |
3368 | unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum; |
3369 | |
3370 | |
3371 | const NonNullAttr *NNAttr = nullptr; |
3372 | if (SanOpts.has(SanitizerKind::NonnullAttribute)) |
3373 | NNAttr = getNonNullAttr(AC.getDecl(), PVD, ArgType, ArgNo); |
3374 | |
3375 | bool CanCheckNullability = false; |
3376 | if (SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD) { |
3377 | auto Nullability = PVD->getType()->getNullability(getContext()); |
3378 | CanCheckNullability = Nullability && |
3379 | *Nullability == NullabilityKind::NonNull && |
3380 | PVD->getTypeSourceInfo(); |
3381 | } |
3382 | |
3383 | if (!NNAttr && !CanCheckNullability) |
3384 | return; |
3385 | |
3386 | SourceLocation AttrLoc; |
3387 | SanitizerMask CheckKind; |
3388 | SanitizerHandler Handler; |
3389 | if (NNAttr) { |
3390 | AttrLoc = NNAttr->getLocation(); |
3391 | CheckKind = SanitizerKind::NonnullAttribute; |
3392 | Handler = SanitizerHandler::NonnullArg; |
3393 | } else { |
3394 | AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc(); |
3395 | CheckKind = SanitizerKind::NullabilityArg; |
3396 | Handler = SanitizerHandler::NullabilityArg; |
3397 | } |
3398 | |
3399 | SanitizerScope SanScope(this); |
3400 | assert(RV.isScalar()); |
3401 | llvm::Value *V = RV.getScalarVal(); |
3402 | llvm::Value *Cond = |
3403 | Builder.CreateICmpNE(V, llvm::Constant::getNullValue(V->getType())); |
3404 | llvm::Constant *StaticData[] = { |
3405 | EmitCheckSourceLocation(ArgLoc), EmitCheckSourceLocation(AttrLoc), |
3406 | llvm::ConstantInt::get(Int32Ty, ArgNo + 1), |
3407 | }; |
3408 | EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, None); |
3409 | } |
3410 | |
3411 | void CodeGenFunction::EmitCallArgs( |
3412 | CallArgList &Args, ArrayRef<QualType> ArgTypes, |
3413 | llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange, |
3414 | AbstractCallee AC, unsigned ParamsToSkip, EvaluationOrder Order) { |
3415 | assert((int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin())); |
3416 | |
3417 | |
3418 | |
3419 | |
3420 | |
3421 | |
3422 | bool LeftToRight = |
3423 | CGM.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee() |
3424 | ? Order == EvaluationOrder::ForceLeftToRight |
3425 | : Order != EvaluationOrder::ForceRightToLeft; |
3426 | |
3427 | auto MaybeEmitImplicitObjectSize = [&](unsigned I, const Expr *Arg, |
3428 | RValue EmittedArg) { |
3429 | if (!AC.hasFunctionDecl() || I >= AC.getNumParams()) |
3430 | return; |
3431 | auto *PS = AC.getParamDecl(I)->getAttr<PassObjectSizeAttr>(); |
3432 | if (PS == nullptr) |
3433 | return; |
3434 | |
3435 | const auto &Context = getContext(); |
3436 | auto SizeTy = Context.getSizeType(); |
3437 | auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy)); |
3438 | (0) . __assert_fail ("EmittedArg.getScalarVal() && \"We emitted nothing for the arg?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3438, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(EmittedArg.getScalarVal() && "We emitted nothing for the arg?"); |
3439 | llvm::Value *V = evaluateOrEmitBuiltinObjectSize(Arg, PS->getType(), T, |
3440 | EmittedArg.getScalarVal(), |
3441 | PS->isDynamic()); |
3442 | Args.add(RValue::get(V), SizeTy); |
3443 | |
3444 | |
3445 | if (!LeftToRight) |
3446 | std::swap(Args.back(), *(&Args.back() - 1)); |
3447 | }; |
3448 | |
3449 | |
3450 | bool HasInAllocaArgs = false; |
3451 | if (CGM.getTarget().getCXXABI().isMicrosoft()) { |
3452 | for (ArrayRef<QualType>::iterator I = ArgTypes.begin(), E = ArgTypes.end(); |
3453 | I != E && !HasInAllocaArgs; ++I) |
3454 | HasInAllocaArgs = isInAllocaArgument(CGM.getCXXABI(), *I); |
3455 | if (HasInAllocaArgs) { |
3456 | assert(getTarget().getTriple().getArch() == llvm::Triple::x86); |
3457 | Args.allocateArgumentMemory(*this); |
3458 | } |
3459 | } |
3460 | |
3461 | |
3462 | size_t CallArgsStart = Args.size(); |
3463 | for (unsigned I = 0, E = ArgTypes.size(); I != E; ++I) { |
3464 | unsigned Idx = LeftToRight ? I : E - I - 1; |
3465 | CallExpr::const_arg_iterator Arg = ArgRange.begin() + Idx; |
3466 | unsigned InitialArgSize = Args.size(); |
3467 | |
3468 | |
3469 | (0) . __assert_fail ("(!isa(*Arg) || getContext().hasSameUnqualifiedType((*Arg)->getType(), ArgTypes[Idx]) || (isa(AC.getDecl()) && isObjCMethodWithTypeParams(cast(AC.getDecl())))) && \"Argument and parameter types don't match\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3474, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((!isa<ObjCIndirectCopyRestoreExpr>(*Arg) || |
3470 | (0) . __assert_fail ("(!isa(*Arg) || getContext().hasSameUnqualifiedType((*Arg)->getType(), ArgTypes[Idx]) || (isa(AC.getDecl()) && isObjCMethodWithTypeParams(cast(AC.getDecl())))) && \"Argument and parameter types don't match\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3474, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> getContext().hasSameUnqualifiedType((*Arg)->getType(), |
3471 | (0) . __assert_fail ("(!isa(*Arg) || getContext().hasSameUnqualifiedType((*Arg)->getType(), ArgTypes[Idx]) || (isa(AC.getDecl()) && isObjCMethodWithTypeParams(cast(AC.getDecl())))) && \"Argument and parameter types don't match\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3474, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> ArgTypes[Idx]) || |
3472 | (0) . __assert_fail ("(!isa(*Arg) || getContext().hasSameUnqualifiedType((*Arg)->getType(), ArgTypes[Idx]) || (isa(AC.getDecl()) && isObjCMethodWithTypeParams(cast(AC.getDecl())))) && \"Argument and parameter types don't match\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3474, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> (isa<ObjCMethodDecl>(AC.getDecl()) && |
3473 | (0) . __assert_fail ("(!isa(*Arg) || getContext().hasSameUnqualifiedType((*Arg)->getType(), ArgTypes[Idx]) || (isa(AC.getDecl()) && isObjCMethodWithTypeParams(cast(AC.getDecl())))) && \"Argument and parameter types don't match\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3474, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> isObjCMethodWithTypeParams(cast<ObjCMethodDecl>(AC.getDecl())))) && |
3474 | (0) . __assert_fail ("(!isa(*Arg) || getContext().hasSameUnqualifiedType((*Arg)->getType(), ArgTypes[Idx]) || (isa(AC.getDecl()) && isObjCMethodWithTypeParams(cast(AC.getDecl())))) && \"Argument and parameter types don't match\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3474, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Argument and parameter types don't match"); |
3475 | EmitCallArg(Args, *Arg, ArgTypes[Idx]); |
3476 | |
3477 | |
3478 | (0) . __assert_fail ("InitialArgSize + 1 == Args.size() && \"The code below depends on only adding one arg per EmitCallArg\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3479, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(InitialArgSize + 1 == Args.size() && |
3479 | (0) . __assert_fail ("InitialArgSize + 1 == Args.size() && \"The code below depends on only adding one arg per EmitCallArg\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3479, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "The code below depends on only adding one arg per EmitCallArg"); |
3480 | (void)InitialArgSize; |
3481 | |
3482 | |
3483 | if (!Args.back().hasLValue()) { |
3484 | RValue RVArg = Args.back().getKnownRValue(); |
3485 | EmitNonNullArgCheck(RVArg, ArgTypes[Idx], (*Arg)->getExprLoc(), AC, |
3486 | ParamsToSkip + Idx); |
3487 | |
3488 | |
3489 | |
3490 | MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg); |
3491 | } |
3492 | } |
3493 | |
3494 | if (!LeftToRight) { |
3495 | |
3496 | |
3497 | std::reverse(Args.begin() + CallArgsStart, Args.end()); |
3498 | } |
3499 | } |
3500 | |
3501 | namespace { |
3502 | |
3503 | struct DestroyUnpassedArg final : EHScopeStack::Cleanup { |
3504 | DestroyUnpassedArg(Address Addr, QualType Ty) |
3505 | : Addr(Addr), Ty(Ty) {} |
3506 | |
3507 | Address Addr; |
3508 | QualType Ty; |
3509 | |
3510 | void Emit(CodeGenFunction &CGF, Flags flags) override { |
3511 | QualType::DestructionKind DtorKind = Ty.isDestructedType(); |
3512 | if (DtorKind == QualType::DK_cxx_destructor) { |
3513 | const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor(); |
3514 | isTrivial()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3514, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!Dtor->isTrivial()); |
3515 | CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, false, |
3516 | , Addr); |
3517 | } else { |
3518 | CGF.callCStructDestructor(CGF.MakeAddrLValue(Addr, Ty)); |
3519 | } |
3520 | } |
3521 | }; |
3522 | |
3523 | struct DisableDebugLocationUpdates { |
3524 | CodeGenFunction &CGF; |
3525 | bool disabledDebugInfo; |
3526 | DisableDebugLocationUpdates(CodeGenFunction &CGF, const Expr *E) : CGF(CGF) { |
3527 | if ((disabledDebugInfo = isa<CXXDefaultArgExpr>(E) && CGF.getDebugInfo())) |
3528 | CGF.disableDebugInfo(); |
3529 | } |
3530 | ~DisableDebugLocationUpdates() { |
3531 | if (disabledDebugInfo) |
3532 | CGF.enableDebugInfo(); |
3533 | } |
3534 | }; |
3535 | |
3536 | } |
3537 | |
3538 | RValue CallArg::getRValue(CodeGenFunction &CGF) const { |
3539 | if (!HasLV) |
3540 | return RV; |
3541 | LValue Copy = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty), Ty); |
3542 | CGF.EmitAggregateCopy(Copy, LV, Ty, AggValueSlot::DoesNotOverlap, |
3543 | LV.isVolatile()); |
3544 | IsUsed = true; |
3545 | return RValue::getAggregate(Copy.getAddress()); |
3546 | } |
3547 | |
3548 | void CallArg::copyInto(CodeGenFunction &CGF, Address Addr) const { |
3549 | LValue Dst = CGF.MakeAddrLValue(Addr, Ty); |
3550 | if (!HasLV && RV.isScalar()) |
3551 | CGF.EmitStoreOfScalar(RV.getScalarVal(), Dst, ); |
3552 | else if (!HasLV && RV.isComplex()) |
3553 | CGF.EmitStoreOfComplex(RV.getComplexVal(), Dst, ); |
3554 | else { |
3555 | auto Addr = HasLV ? LV.getAddress() : RV.getAggregateAddress(); |
3556 | LValue SrcLV = CGF.MakeAddrLValue(Addr, Ty); |
3557 | |
3558 | CGF.EmitAggregateCopy(Dst, SrcLV, Ty, AggValueSlot::DoesNotOverlap, |
3559 | HasLV ? LV.isVolatileQualified() |
3560 | : RV.isVolatileQualified()); |
3561 | } |
3562 | IsUsed = true; |
3563 | } |
3564 | |
3565 | void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, |
3566 | QualType type) { |
3567 | DisableDebugLocationUpdates Dis(*this, E); |
3568 | if (const ObjCIndirectCopyRestoreExpr *CRE |
3569 | = dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) { |
3570 | assert(getLangOpts().ObjCAutoRefCount); |
3571 | return emitWritebackArg(*this, args, CRE); |
3572 | } |
3573 | |
3574 | (0) . __assert_fail ("type->isReferenceType() == E->isGLValue() && \"reference binding to unmaterialized r-value!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3575, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(type->isReferenceType() == E->isGLValue() && |
3575 | (0) . __assert_fail ("type->isReferenceType() == E->isGLValue() && \"reference binding to unmaterialized r-value!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3575, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "reference binding to unmaterialized r-value!"); |
3576 | |
3577 | if (E->isGLValue()) { |
3578 | getObjectKind() == OK_Ordinary", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3578, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(E->getObjectKind() == OK_Ordinary); |
3579 | return args.add(EmitReferenceBindingToExpr(E), type); |
3580 | } |
3581 | |
3582 | bool HasAggregateEvalKind = hasAggregateEvaluationKind(type); |
3583 | |
3584 | |
3585 | |
3586 | |
3587 | if (HasAggregateEvalKind && |
3588 | type->getAs<RecordType>()->getDecl()->isParamDestroyedInCallee()) { |
3589 | |
3590 | |
3591 | AggValueSlot Slot; |
3592 | if (args.isUsingInAlloca()) |
3593 | Slot = createPlaceholderSlot(*this, type); |
3594 | else |
3595 | Slot = CreateAggTemp(type, "agg.tmp"); |
3596 | |
3597 | bool DestroyedInCallee = true, NeedsEHCleanup = true; |
3598 | if (const auto *RD = type->getAsCXXRecordDecl()) |
3599 | DestroyedInCallee = RD->hasNonTrivialDestructor(); |
3600 | else |
3601 | NeedsEHCleanup = needsEHCleanup(type.isDestructedType()); |
3602 | |
3603 | if (DestroyedInCallee) |
3604 | Slot.setExternallyDestructed(); |
3605 | |
3606 | EmitAggExpr(E, Slot); |
3607 | RValue RV = Slot.asRValue(); |
3608 | args.add(RV, type); |
3609 | |
3610 | if (DestroyedInCallee && NeedsEHCleanup) { |
3611 | |
3612 | |
3613 | |
3614 | pushFullExprCleanup<DestroyUnpassedArg>(EHCleanup, Slot.getAddress(), |
3615 | type); |
3616 | |
3617 | llvm::Instruction *IsActive = Builder.CreateUnreachable(); |
3618 | args.addArgCleanupDeactivation(EHStack.getInnermostEHScope(), IsActive); |
3619 | } |
3620 | return; |
3621 | } |
3622 | |
3623 | if (HasAggregateEvalKind && isa<ImplicitCastExpr>(E) && |
3624 | cast<CastExpr>(E)->getCastKind() == CK_LValueToRValue) { |
3625 | LValue L = EmitLValue(cast<CastExpr>(E)->getSubExpr()); |
3626 | assert(L.isSimple()); |
3627 | args.addUncopiedAggregate(L, type); |
3628 | return; |
3629 | } |
3630 | |
3631 | args.add(EmitAnyExprToTemp(E), type); |
3632 | } |
3633 | |
3634 | QualType CodeGenFunction::getVarArgType(const Expr *Arg) { |
3635 | |
3636 | |
3637 | |
3638 | if (!getTarget().getTriple().isOSWindows()) |
3639 | return Arg->getType(); |
3640 | |
3641 | if (Arg->getType()->isIntegerType() && |
3642 | getContext().getTypeSize(Arg->getType()) < |
3643 | getContext().getTargetInfo().getPointerWidth(0) && |
3644 | Arg->isNullPointerConstant(getContext(), |
3645 | Expr::NPC_ValueDependentIsNotNull)) { |
3646 | return getContext().getIntPtrType(); |
3647 | } |
3648 | |
3649 | return Arg->getType(); |
3650 | } |
3651 | |
3652 | |
3653 | |
3654 | void |
3655 | CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) { |
3656 | if (CGM.getCodeGenOpts().OptimizationLevel != 0 && |
3657 | !CGM.getCodeGenOpts().ObjCAutoRefCountExceptions) |
3658 | Inst->setMetadata("clang.arc.no_objc_arc_exceptions", |
3659 | CGM.getNoObjCARCExceptionsMetadata()); |
3660 | } |
3661 | |
3662 | |
3663 | llvm::CallInst * |
3664 | CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee, |
3665 | const llvm::Twine &name) { |
3666 | return EmitNounwindRuntimeCall(callee, None, name); |
3667 | } |
3668 | |
3669 | |
3670 | llvm::CallInst * |
3671 | CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee, |
3672 | ArrayRef<llvm::Value *> args, |
3673 | const llvm::Twine &name) { |
3674 | llvm::CallInst *call = EmitRuntimeCall(callee, args, name); |
3675 | call->setDoesNotThrow(); |
3676 | return call; |
3677 | } |
3678 | |
3679 | |
3680 | |
3681 | llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee, |
3682 | const llvm::Twine &name) { |
3683 | return EmitRuntimeCall(callee, None, name); |
3684 | } |
3685 | |
3686 | |
3687 | |
3688 | SmallVector<llvm::OperandBundleDef, 1> |
3689 | CodeGenFunction::getBundlesForFunclet(llvm::Value *Callee) { |
3690 | SmallVector<llvm::OperandBundleDef, 1> BundleList; |
3691 | |
3692 | |
3693 | if (!CurrentFuncletPad) |
3694 | return BundleList; |
3695 | |
3696 | |
3697 | auto *CalleeFn = dyn_cast<llvm::Function>(Callee->stripPointerCasts()); |
3698 | if (CalleeFn && CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow()) |
3699 | return BundleList; |
3700 | |
3701 | BundleList.emplace_back("funclet", CurrentFuncletPad); |
3702 | return BundleList; |
3703 | } |
3704 | |
3705 | |
3706 | llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee, |
3707 | ArrayRef<llvm::Value *> args, |
3708 | const llvm::Twine &name) { |
3709 | llvm::CallInst *call = Builder.CreateCall( |
3710 | callee, args, getBundlesForFunclet(callee.getCallee()), name); |
3711 | call->setCallingConv(getRuntimeCC()); |
3712 | return call; |
3713 | } |
3714 | |
3715 | |
3716 | void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke( |
3717 | llvm::FunctionCallee callee, ArrayRef<llvm::Value *> args) { |
3718 | SmallVector<llvm::OperandBundleDef, 1> BundleList = |
3719 | getBundlesForFunclet(callee.getCallee()); |
3720 | |
3721 | if (getInvokeDest()) { |
3722 | llvm::InvokeInst *invoke = |
3723 | Builder.CreateInvoke(callee, |
3724 | getUnreachableBlock(), |
3725 | getInvokeDest(), |
3726 | args, |
3727 | BundleList); |
3728 | invoke->setDoesNotReturn(); |
3729 | invoke->setCallingConv(getRuntimeCC()); |
3730 | } else { |
3731 | llvm::CallInst *call = Builder.CreateCall(callee, args, BundleList); |
3732 | call->setDoesNotReturn(); |
3733 | call->setCallingConv(getRuntimeCC()); |
3734 | Builder.CreateUnreachable(); |
3735 | } |
3736 | } |
3737 | |
3738 | |
3739 | llvm::CallBase * |
3740 | CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, |
3741 | const Twine &name) { |
3742 | return EmitRuntimeCallOrInvoke(callee, None, name); |
3743 | } |
3744 | |
3745 | |
3746 | llvm::CallBase * |
3747 | CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, |
3748 | ArrayRef<llvm::Value *> args, |
3749 | const Twine &name) { |
3750 | llvm::CallBase *call = EmitCallOrInvoke(callee, args, name); |
3751 | call->setCallingConv(getRuntimeCC()); |
3752 | return call; |
3753 | } |
3754 | |
3755 | |
3756 | |
3757 | llvm::CallBase *CodeGenFunction::EmitCallOrInvoke(llvm::FunctionCallee Callee, |
3758 | ArrayRef<llvm::Value *> Args, |
3759 | const Twine &Name) { |
3760 | llvm::BasicBlock *InvokeDest = getInvokeDest(); |
3761 | SmallVector<llvm::OperandBundleDef, 1> BundleList = |
3762 | getBundlesForFunclet(Callee.getCallee()); |
3763 | |
3764 | llvm::CallBase *Inst; |
3765 | if (!InvokeDest) |
3766 | Inst = Builder.CreateCall(Callee, Args, BundleList, Name); |
3767 | else { |
3768 | llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont"); |
3769 | Inst = Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, BundleList, |
3770 | Name); |
3771 | EmitBlock(ContBB); |
3772 | } |
3773 | |
3774 | |
3775 | |
3776 | if (CGM.getLangOpts().ObjCAutoRefCount) |
3777 | AddObjCARCExceptionMetadata(Inst); |
3778 | |
3779 | return Inst; |
3780 | } |
3781 | |
3782 | void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old, |
3783 | llvm::Value *New) { |
3784 | DeferredReplacements.push_back(std::make_pair(Old, New)); |
3785 | } |
3786 | |
3787 | RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, |
3788 | const CGCallee &Callee, |
3789 | ReturnValueSlot ReturnValue, |
3790 | const CallArgList &CallArgs, |
3791 | llvm::CallBase **callOrInvoke, |
3792 | SourceLocation Loc) { |
3793 | |
3794 | |
3795 | assert(Callee.isOrdinary() || Callee.isVirtual()); |
3796 | |
3797 | |
3798 | |
3799 | QualType RetTy = CallInfo.getReturnType(); |
3800 | const ABIArgInfo &RetAI = CallInfo.getReturnInfo(); |
3801 | |
3802 | llvm::FunctionType *IRFuncTy = getTypes().GetFunctionType(CallInfo); |
3803 | |
3804 | #ifndef NDEBUG |
3805 | if (!(CallInfo.isVariadic() && CallInfo.getArgStruct())) { |
3806 | |
3807 | |
3808 | |
3809 | |
3810 | |
3811 | |
3812 | |
3813 | llvm::Type *TypeFromVal; |
3814 | if (Callee.isVirtual()) |
3815 | TypeFromVal = Callee.getVirtualFunctionType(); |
3816 | else |
3817 | TypeFromVal = |
3818 | Callee.getFunctionPointer()->getType()->getPointerElementType(); |
3819 | assert(IRFuncTy == TypeFromVal); |
3820 | } |
3821 | #endif |
3822 | |
3823 | |
3824 | |
3825 | |
3826 | |
3827 | Address ArgMemory = Address::invalid(); |
3828 | if (llvm::StructType *ArgStruct = CallInfo.getArgStruct()) { |
3829 | const llvm::DataLayout &DL = CGM.getDataLayout(); |
3830 | llvm::Instruction *IP = CallArgs.getStackBase(); |
3831 | llvm::AllocaInst *AI; |
3832 | if (IP) { |
3833 | IP = IP->getNextNode(); |
3834 | AI = new llvm::AllocaInst(ArgStruct, DL.getAllocaAddrSpace(), |
3835 | "argmem", IP); |
3836 | } else { |
3837 | AI = CreateTempAlloca(ArgStruct, "argmem"); |
3838 | } |
3839 | auto Align = CallInfo.getArgStructAlignment(); |
3840 | AI->setAlignment(Align.getQuantity()); |
3841 | AI->setUsedWithInAlloca(true); |
3842 | isUsedWithInAlloca() && !AI->isStaticAlloca()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3842, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca()); |
3843 | ArgMemory = Address(AI, Align); |
3844 | } |
3845 | |
3846 | ClangToLLVMArgMapping IRFunctionArgs(CGM.getContext(), CallInfo); |
3847 | SmallVector<llvm::Value *, 16> IRCallArgs(IRFunctionArgs.totalIRArgs()); |
3848 | |
3849 | |
3850 | |
3851 | Address SRetPtr = Address::invalid(); |
3852 | Address SRetAlloca = Address::invalid(); |
3853 | llvm::Value *UnusedReturnSizePtr = nullptr; |
3854 | if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) { |
3855 | if (!ReturnValue.isNull()) { |
3856 | SRetPtr = ReturnValue.getValue(); |
3857 | } else { |
3858 | SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca); |
3859 | if (HaveInsertPoint() && ReturnValue.isUnused()) { |
3860 | uint64_t size = |
3861 | CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(RetTy)); |
3862 | UnusedReturnSizePtr = EmitLifetimeStart(size, SRetAlloca.getPointer()); |
3863 | } |
3864 | } |
3865 | if (IRFunctionArgs.hasSRetArg()) { |
3866 | IRCallArgs[IRFunctionArgs.getSRetArgNo()] = SRetPtr.getPointer(); |
3867 | } else if (RetAI.isInAlloca()) { |
3868 | Address Addr = |
3869 | Builder.CreateStructGEP(ArgMemory, RetAI.getInAllocaFieldIndex()); |
3870 | Builder.CreateStore(SRetPtr.getPointer(), Addr); |
3871 | } |
3872 | } |
3873 | |
3874 | Address swiftErrorTemp = Address::invalid(); |
3875 | Address swiftErrorArg = Address::invalid(); |
3876 | |
3877 | |
3878 | (0) . __assert_fail ("CallInfo.arg_size() == CallArgs.size() && \"Mismatch between function signature & arguments.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3879, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CallInfo.arg_size() == CallArgs.size() && |
3879 | (0) . __assert_fail ("CallInfo.arg_size() == CallArgs.size() && \"Mismatch between function signature & arguments.\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3879, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Mismatch between function signature & arguments."); |
3880 | unsigned ArgNo = 0; |
3881 | CGFunctionInfo::const_arg_iterator info_it = CallInfo.arg_begin(); |
3882 | for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end(); |
3883 | I != E; ++I, ++info_it, ++ArgNo) { |
3884 | const ABIArgInfo &ArgInfo = info_it->info; |
3885 | |
3886 | |
3887 | if (IRFunctionArgs.hasPaddingArg(ArgNo)) |
3888 | IRCallArgs[IRFunctionArgs.getPaddingArgNo(ArgNo)] = |
3889 | llvm::UndefValue::get(ArgInfo.getPaddingType()); |
3890 | |
3891 | unsigned FirstIRArg, NumIRArgs; |
3892 | std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo); |
3893 | |
3894 | switch (ArgInfo.getKind()) { |
3895 | case ABIArgInfo::InAlloca: { |
3896 | assert(NumIRArgs == 0); |
3897 | assert(getTarget().getTriple().getArch() == llvm::Triple::x86); |
3898 | if (I->isAggregate()) { |
3899 | |
3900 | Address Addr = I->hasLValue() |
3901 | ? I->getKnownLValue().getAddress() |
3902 | : I->getKnownRValue().getAggregateAddress(); |
3903 | llvm::Instruction *Placeholder = |
3904 | cast<llvm::Instruction>(Addr.getPointer()); |
3905 | CGBuilderTy::InsertPoint IP = Builder.saveIP(); |
3906 | Builder.SetInsertPoint(Placeholder); |
3907 | Addr = |
3908 | Builder.CreateStructGEP(ArgMemory, ArgInfo.getInAllocaFieldIndex()); |
3909 | Builder.restoreIP(IP); |
3910 | deferPlaceholderReplacement(Placeholder, Addr.getPointer()); |
3911 | } else { |
3912 | |
3913 | Address Addr = |
3914 | Builder.CreateStructGEP(ArgMemory, ArgInfo.getInAllocaFieldIndex()); |
3915 | unsigned AS = Addr.getType()->getPointerAddressSpace(); |
3916 | llvm::Type *MemType = ConvertTypeForMem(I->Ty)->getPointerTo(AS); |
3917 | |
3918 | |
3919 | |
3920 | if (Addr.getType() != MemType) |
3921 | Addr = Builder.CreateBitCast(Addr, MemType); |
3922 | I->copyInto(*this, Addr); |
3923 | } |
3924 | break; |
3925 | } |
3926 | |
3927 | case ABIArgInfo::Indirect: { |
3928 | assert(NumIRArgs == 1); |
3929 | if (!I->isAggregate()) { |
3930 | |
3931 | Address Addr = CreateMemTempWithoutCast( |
3932 | I->Ty, ArgInfo.getIndirectAlign(), "indirect-arg-temp"); |
3933 | IRCallArgs[FirstIRArg] = Addr.getPointer(); |
3934 | |
3935 | I->copyInto(*this, Addr); |
3936 | } else { |
3937 | |
3938 | |
3939 | |
3940 | |
3941 | |
3942 | |
3943 | |
3944 | |
3945 | Address Addr = I->hasLValue() |
3946 | ? I->getKnownLValue().getAddress() |
3947 | : I->getKnownRValue().getAggregateAddress(); |
3948 | llvm::Value *V = Addr.getPointer(); |
3949 | CharUnits Align = ArgInfo.getIndirectAlign(); |
3950 | const llvm::DataLayout *TD = &CGM.getDataLayout(); |
3951 | |
3952 | (0) . __assert_fail ("(FirstIRArg >= IRFuncTy->getNumParams() || IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() == TD->getAllocaAddrSpace()) && \"indirect argument must be in alloca address space\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3955, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((FirstIRArg >= IRFuncTy->getNumParams() || |
3953 | (0) . __assert_fail ("(FirstIRArg >= IRFuncTy->getNumParams() || IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() == TD->getAllocaAddrSpace()) && \"indirect argument must be in alloca address space\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3955, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() == |
3954 | (0) . __assert_fail ("(FirstIRArg >= IRFuncTy->getNumParams() || IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() == TD->getAllocaAddrSpace()) && \"indirect argument must be in alloca address space\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3955, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> TD->getAllocaAddrSpace()) && |
3955 | (0) . __assert_fail ("(FirstIRArg >= IRFuncTy->getNumParams() || IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() == TD->getAllocaAddrSpace()) && \"indirect argument must be in alloca address space\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 3955, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "indirect argument must be in alloca address space"); |
3956 | |
3957 | bool NeedCopy = false; |
3958 | |
3959 | if (Addr.getAlignment() < Align && |
3960 | llvm::getOrEnforceKnownAlignment(V, Align.getQuantity(), *TD) < |
3961 | Align.getQuantity()) { |
3962 | NeedCopy = true; |
3963 | } else if (I->hasLValue()) { |
3964 | auto LV = I->getKnownLValue(); |
3965 | auto AS = LV.getAddressSpace(); |
3966 | |
3967 | if ((!ArgInfo.getIndirectByVal() && |
3968 | (LV.getAlignment() >= |
3969 | getContext().getTypeAlignInChars(I->Ty)))) { |
3970 | NeedCopy = true; |
3971 | } |
3972 | if (!getLangOpts().OpenCL) { |
3973 | if ((ArgInfo.getIndirectByVal() && |
3974 | (AS != LangAS::Default && |
3975 | AS != CGM.getASTAllocaAddressSpace()))) { |
3976 | NeedCopy = true; |
3977 | } |
3978 | } |
3979 | |
3980 | |
3981 | else if ((ArgInfo.getIndirectByVal() && |
3982 | Addr.getType()->getAddressSpace() != IRFuncTy-> |
3983 | getParamType(FirstIRArg)->getPointerAddressSpace())) { |
3984 | NeedCopy = true; |
3985 | } |
3986 | } |
3987 | |
3988 | if (NeedCopy) { |
3989 | |
3990 | Address AI = CreateMemTempWithoutCast( |
3991 | I->Ty, ArgInfo.getIndirectAlign(), "byval-temp"); |
3992 | IRCallArgs[FirstIRArg] = AI.getPointer(); |
3993 | I->copyInto(*this, AI); |
3994 | } else { |
3995 | |
3996 | auto *T = V->getType()->getPointerElementType()->getPointerTo( |
3997 | CGM.getDataLayout().getAllocaAddrSpace()); |
3998 | IRCallArgs[FirstIRArg] = getTargetHooks().performAddrSpaceCast( |
3999 | *this, V, LangAS::Default, CGM.getASTAllocaAddressSpace(), T, |
4000 | true); |
4001 | } |
4002 | } |
4003 | break; |
4004 | } |
4005 | |
4006 | case ABIArgInfo::Ignore: |
4007 | assert(NumIRArgs == 0); |
4008 | break; |
4009 | |
4010 | case ABIArgInfo::Extend: |
4011 | case ABIArgInfo::Direct: { |
4012 | if (!isa<llvm::StructType>(ArgInfo.getCoerceToType()) && |
4013 | ArgInfo.getCoerceToType() == ConvertType(info_it->type) && |
4014 | ArgInfo.getDirectOffset() == 0) { |
4015 | assert(NumIRArgs == 1); |
4016 | llvm::Value *V; |
4017 | if (!I->isAggregate()) |
4018 | V = I->getKnownRValue().getScalarVal(); |
4019 | else |
4020 | V = Builder.CreateLoad( |
4021 | I->hasLValue() ? I->getKnownLValue().getAddress() |
4022 | : I->getKnownRValue().getAggregateAddress()); |
4023 | |
4024 | |
4025 | |
4026 | if (CallInfo.getExtParameterInfo(ArgNo).getABI() |
4027 | == ParameterABI::SwiftErrorResult) { |
4028 | (0) . __assert_fail ("!swiftErrorTemp.isValid() && \"multiple swifterror args\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 4028, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!swiftErrorTemp.isValid() && "multiple swifterror args"); |
4029 | |
4030 | QualType pointeeTy = I->Ty->getPointeeType(); |
4031 | swiftErrorArg = |
4032 | Address(V, getContext().getTypeAlignInChars(pointeeTy)); |
4033 | |
4034 | swiftErrorTemp = |
4035 | CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp"); |
4036 | V = swiftErrorTemp.getPointer(); |
4037 | cast<llvm::AllocaInst>(V)->setSwiftError(true); |
4038 | |
4039 | llvm::Value *errorValue = Builder.CreateLoad(swiftErrorArg); |
4040 | Builder.CreateStore(errorValue, swiftErrorTemp); |
4041 | } |
4042 | |
4043 | |
4044 | if (ArgInfo.getCoerceToType() != V->getType() && |
4045 | V->getType()->isIntegerTy()) |
4046 | V = Builder.CreateZExt(V, ArgInfo.getCoerceToType()); |
4047 | |
4048 | |
4049 | |
4050 | if (FirstIRArg < IRFuncTy->getNumParams() && |
4051 | V->getType() != IRFuncTy->getParamType(FirstIRArg)) |
4052 | V = Builder.CreateBitCast(V, IRFuncTy->getParamType(FirstIRArg)); |
4053 | |
4054 | IRCallArgs[FirstIRArg] = V; |
4055 | break; |
4056 | } |
4057 | |
4058 | |
4059 | Address Src = Address::invalid(); |
4060 | if (!I->isAggregate()) { |
4061 | Src = CreateMemTemp(I->Ty, "coerce"); |
4062 | I->copyInto(*this, Src); |
4063 | } else { |
4064 | Src = I->hasLValue() ? I->getKnownLValue().getAddress() |
4065 | : I->getKnownRValue().getAggregateAddress(); |
4066 | } |
4067 | |
4068 | |
4069 | Src = emitAddressAtOffset(*this, Src, ArgInfo); |
4070 | |
4071 | |
4072 | |
4073 | llvm::StructType *STy = |
4074 | dyn_cast<llvm::StructType>(ArgInfo.getCoerceToType()); |
4075 | if (STy && ArgInfo.isDirect() && ArgInfo.getCanBeFlattened()) { |
4076 | llvm::Type *SrcTy = Src.getType()->getElementType(); |
4077 | uint64_t SrcSize = CGM.getDataLayout().getTypeAllocSize(SrcTy); |
4078 | uint64_t DstSize = CGM.getDataLayout().getTypeAllocSize(STy); |
4079 | |
4080 | |
4081 | |
4082 | |
4083 | |
4084 | if (SrcSize < DstSize) { |
4085 | Address TempAlloca |
4086 | = CreateTempAlloca(STy, Src.getAlignment(), |
4087 | Src.getName() + ".coerce"); |
4088 | Builder.CreateMemCpy(TempAlloca, Src, SrcSize); |
4089 | Src = TempAlloca; |
4090 | } else { |
4091 | Src = Builder.CreateBitCast(Src, |
4092 | STy->getPointerTo(Src.getAddressSpace())); |
4093 | } |
4094 | |
4095 | getNumElements()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 4095, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(NumIRArgs == STy->getNumElements()); |
4096 | for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { |
4097 | Address EltPtr = Builder.CreateStructGEP(Src, i); |
4098 | llvm::Value *LI = Builder.CreateLoad(EltPtr); |
4099 | IRCallArgs[FirstIRArg + i] = LI; |
4100 | } |
4101 | } else { |
4102 | |
4103 | assert(NumIRArgs == 1); |
4104 | IRCallArgs[FirstIRArg] = |
4105 | CreateCoercedLoad(Src, ArgInfo.getCoerceToType(), *this); |
4106 | } |
4107 | |
4108 | break; |
4109 | } |
4110 | |
4111 | case ABIArgInfo::CoerceAndExpand: { |
4112 | auto coercionType = ArgInfo.getCoerceAndExpandType(); |
4113 | auto layout = CGM.getDataLayout().getStructLayout(coercionType); |
4114 | |
4115 | llvm::Value *tempSize = nullptr; |
4116 | Address addr = Address::invalid(); |
4117 | Address AllocaAddr = Address::invalid(); |
4118 | if (I->isAggregate()) { |
4119 | addr = I->hasLValue() ? I->getKnownLValue().getAddress() |
4120 | : I->getKnownRValue().getAggregateAddress(); |
4121 | |
4122 | } else { |
4123 | RValue RV = I->getKnownRValue(); |
4124 | assert(RV.isScalar()); |
4125 | |
4126 | llvm::Type *scalarType = RV.getScalarVal()->getType(); |
4127 | auto scalarSize = CGM.getDataLayout().getTypeAllocSize(scalarType); |
4128 | auto scalarAlign = CGM.getDataLayout().getPrefTypeAlignment(scalarType); |
4129 | |
4130 | |
4131 | addr = CreateTempAlloca(RV.getScalarVal()->getType(), |
4132 | CharUnits::fromQuantity(std::max( |
4133 | layout->getAlignment(), scalarAlign)), |
4134 | "tmp", |
4135 | , &AllocaAddr); |
4136 | tempSize = EmitLifetimeStart(scalarSize, AllocaAddr.getPointer()); |
4137 | |
4138 | Builder.CreateStore(RV.getScalarVal(), addr); |
4139 | } |
4140 | |
4141 | addr = Builder.CreateElementBitCast(addr, coercionType); |
4142 | |
4143 | unsigned IRArgPos = FirstIRArg; |
4144 | for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) { |
4145 | llvm::Type *eltType = coercionType->getElementType(i); |
4146 | if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType)) continue; |
4147 | Address eltAddr = Builder.CreateStructGEP(addr, i); |
4148 | llvm::Value *elt = Builder.CreateLoad(eltAddr); |
4149 | IRCallArgs[IRArgPos++] = elt; |
4150 | } |
4151 | assert(IRArgPos == FirstIRArg + NumIRArgs); |
4152 | |
4153 | if (tempSize) { |
4154 | EmitLifetimeEnd(tempSize, AllocaAddr.getPointer()); |
4155 | } |
4156 | |
4157 | break; |
4158 | } |
4159 | |
4160 | case ABIArgInfo::Expand: |
4161 | unsigned IRArgPos = FirstIRArg; |
4162 | ExpandTypeToArgs(I->Ty, *I, IRFuncTy, IRCallArgs, IRArgPos); |
4163 | assert(IRArgPos == FirstIRArg + NumIRArgs); |
4164 | break; |
4165 | } |
4166 | } |
4167 | |
4168 | const CGCallee &ConcreteCallee = Callee.prepareConcreteCallee(*this); |
4169 | llvm::Value *CalleePtr = ConcreteCallee.getFunctionPointer(); |
4170 | |
4171 | |
4172 | if (ArgMemory.isValid()) { |
4173 | llvm::Value *Arg = ArgMemory.getPointer(); |
4174 | if (CallInfo.isVariadic()) { |
4175 | |
4176 | |
4177 | |
4178 | |
4179 | unsigned CalleeAS = CalleePtr->getType()->getPointerAddressSpace(); |
4180 | CalleePtr = |
4181 | Builder.CreateBitCast(CalleePtr, IRFuncTy->getPointerTo(CalleeAS)); |
4182 | } else { |
4183 | llvm::Type *LastParamTy = |
4184 | IRFuncTy->getParamType(IRFuncTy->getNumParams() - 1); |
4185 | if (Arg->getType() != LastParamTy) { |
4186 | #ifndef NDEBUG |
4187 | |
4188 | llvm::StructType *FullTy = CallInfo.getArgStruct(); |
4189 | llvm::StructType *DeclaredTy = cast<llvm::StructType>( |
4190 | cast<llvm::PointerType>(LastParamTy)->getElementType()); |
4191 | getNumElements() == FullTy->getNumElements()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 4191, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DeclaredTy->getNumElements() == FullTy->getNumElements()); |
4192 | for (llvm::StructType::element_iterator DI = DeclaredTy->element_begin(), |
4193 | DE = DeclaredTy->element_end(), |
4194 | FI = FullTy->element_begin(); |
4195 | DI != DE; ++DI, ++FI) |
4196 | assert(*DI == *FI); |
4197 | #endif |
4198 | Arg = Builder.CreateBitCast(Arg, LastParamTy); |
4199 | } |
4200 | } |
4201 | assert(IRFunctionArgs.hasInallocaArg()); |
4202 | IRCallArgs[IRFunctionArgs.getInallocaArgNo()] = Arg; |
4203 | } |
4204 | |
4205 | |
4206 | |
4207 | |
4208 | |
4209 | |
4210 | |
4211 | |
4212 | |
4213 | auto simplifyVariadicCallee = [](llvm::FunctionType *CalleeFT, |
4214 | llvm::Value *Ptr) -> llvm::Function * { |
4215 | if (!CalleeFT->isVarArg()) |
4216 | return nullptr; |
4217 | |
4218 | |
4219 | if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr)) { |
4220 | if (CE->getOpcode() == llvm::Instruction::BitCast) |
4221 | Ptr = CE->getOperand(0); |
4222 | } |
4223 | |
4224 | llvm::Function *OrigFn = dyn_cast<llvm::Function>(Ptr); |
4225 | if (!OrigFn) |
4226 | return nullptr; |
4227 | |
4228 | llvm::FunctionType *OrigFT = OrigFn->getFunctionType(); |
4229 | |
4230 | |
4231 | |
4232 | if (OrigFT->isVarArg() || |
4233 | OrigFT->getNumParams() != CalleeFT->getNumParams() || |
4234 | OrigFT->getReturnType() != CalleeFT->getReturnType()) |
4235 | return nullptr; |
4236 | |
4237 | for (unsigned i = 0, e = OrigFT->getNumParams(); i != e; ++i) |
4238 | if (OrigFT->getParamType(i) != CalleeFT->getParamType(i)) |
4239 | return nullptr; |
4240 | |
4241 | return OrigFn; |
4242 | }; |
4243 | |
4244 | if (llvm::Function *OrigFn = simplifyVariadicCallee(IRFuncTy, CalleePtr)) { |
4245 | CalleePtr = OrigFn; |
4246 | IRFuncTy = OrigFn->getFunctionType(); |
4247 | } |
4248 | |
4249 | |
4250 | |
4251 | |
4252 | |
4253 | if (!CallArgs.getCleanupsToDeactivate().empty()) |
4254 | deactivateArgCleanupsBeforeCall(*this, CallArgs); |
4255 | |
4256 | |
4257 | |
4258 | |
4259 | |
4260 | #ifndef NDEBUG |
4261 | getNumParams() || IRFuncTy->isVarArg()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 4261, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(IRCallArgs.size() == IRFuncTy->getNumParams() || IRFuncTy->isVarArg()); |
4262 | for (unsigned i = 0; i < IRCallArgs.size(); ++i) { |
4263 | |
4264 | if (IRFunctionArgs.hasInallocaArg() && |
4265 | i == IRFunctionArgs.getInallocaArgNo()) |
4266 | continue; |
4267 | if (i < IRFuncTy->getNumParams()) |
4268 | getType() == IRFuncTy->getParamType(i)", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 4268, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(IRCallArgs[i]->getType() == IRFuncTy->getParamType(i)); |
4269 | } |
4270 | #endif |
4271 | |
4272 | |
4273 | for (unsigned i = 0; i < IRCallArgs.size(); ++i) { |
4274 | if (auto *VT = dyn_cast<llvm::VectorType>(IRCallArgs[i]->getType())) |
4275 | LargestVectorWidth = std::max(LargestVectorWidth, |
4276 | VT->getPrimitiveSizeInBits()); |
4277 | } |
4278 | |
4279 | |
4280 | unsigned CallingConv; |
4281 | llvm::AttributeList Attrs; |
4282 | CGM.ConstructAttributeList(CalleePtr->getName(), CallInfo, |
4283 | Callee.getAbstractInfo(), Attrs, CallingConv, |
4284 | ); |
4285 | |
4286 | |
4287 | |
4288 | |
4289 | |
4290 | |
4291 | if (CurCodeDecl && CurCodeDecl->hasAttr<FlattenAttr>() && |
4292 | !(Callee.getAbstractInfo().getCalleeDecl().getDecl() && |
4293 | Callee.getAbstractInfo() |
4294 | .getCalleeDecl() |
4295 | .getDecl() |
4296 | ->hasAttr<NoInlineAttr>())) { |
4297 | Attrs = |
4298 | Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex, |
4299 | llvm::Attribute::AlwaysInline); |
4300 | } |
4301 | |
4302 | |
4303 | if (isSEHTryScope()) { |
4304 | Attrs = |
4305 | Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex, |
4306 | llvm::Attribute::NoInline); |
4307 | } |
4308 | |
4309 | |
4310 | bool CannotThrow; |
4311 | if (currentFunctionUsesSEHTry()) { |
4312 | |
4313 | CannotThrow = false; |
4314 | } else if (isCleanupPadScope() && |
4315 | EHPersonality::get(*this).isMSVCXXPersonality()) { |
4316 | |
4317 | |
4318 | |
4319 | CannotThrow = true; |
4320 | } else { |
4321 | |
4322 | CannotThrow = Attrs.hasAttribute(llvm::AttributeList::FunctionIndex, |
4323 | llvm::Attribute::NoUnwind); |
4324 | } |
4325 | |
4326 | |
4327 | |
4328 | |
4329 | |
4330 | if (UnusedReturnSizePtr) |
4331 | pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetAlloca, |
4332 | UnusedReturnSizePtr); |
4333 | |
4334 | llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr : getInvokeDest(); |
4335 | |
4336 | SmallVector<llvm::OperandBundleDef, 1> BundleList = |
4337 | getBundlesForFunclet(CalleePtr); |
4338 | |
4339 | |
4340 | llvm::CallBase *CI; |
4341 | if (!InvokeDest) { |
4342 | CI = Builder.CreateCall(IRFuncTy, CalleePtr, IRCallArgs, BundleList); |
4343 | } else { |
4344 | llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); |
4345 | CI = Builder.CreateInvoke(IRFuncTy, CalleePtr, Cont, InvokeDest, IRCallArgs, |
4346 | BundleList); |
4347 | EmitBlock(Cont); |
4348 | } |
4349 | if (callOrInvoke) |
4350 | *callOrInvoke = CI; |
4351 | |
4352 | |
4353 | CI->setAttributes(Attrs); |
4354 | CI->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv)); |
4355 | |
4356 | |
4357 | |
4358 | if (!CI->getType()->isVoidTy()) |
4359 | CI->setName("call"); |
4360 | |
4361 | |
4362 | if (auto *VT = dyn_cast<llvm::VectorType>(CI->getType())) |
4363 | LargestVectorWidth = std::max(LargestVectorWidth, |
4364 | VT->getPrimitiveSizeInBits()); |
4365 | |
4366 | |
4367 | |
4368 | |
4369 | if (!CI->getCalledFunction()) |
4370 | PGO.valueProfile(Builder, llvm::IPVK_IndirectCallTarget, |
4371 | CI, CalleePtr); |
4372 | |
4373 | |
4374 | |
4375 | if (CGM.getLangOpts().ObjCAutoRefCount) |
4376 | AddObjCARCExceptionMetadata(CI); |
4377 | |
4378 | |
4379 | if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(CI)) { |
4380 | const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl(); |
4381 | if (TargetDecl && TargetDecl->hasAttr<NotTailCalledAttr>()) |
4382 | Call->setTailCallKind(llvm::CallInst::TCK_NoTail); |
4383 | } |
4384 | |
4385 | |
4386 | |
4387 | |
4388 | |
4389 | |
4390 | if (CI->doesNotReturn()) { |
4391 | if (UnusedReturnSizePtr) |
4392 | PopCleanupBlock(); |
4393 | |
4394 | |
4395 | if (SanOpts.has(SanitizerKind::Unreachable)) { |
4396 | |
4397 | |
4398 | if (auto *F = CI->getCalledFunction()) |
4399 | F->removeFnAttr(llvm::Attribute::NoReturn); |
4400 | CI->removeAttribute(llvm::AttributeList::FunctionIndex, |
4401 | llvm::Attribute::NoReturn); |
4402 | |
4403 | |
4404 | |
4405 | if (SanOpts.hasOneOf(SanitizerKind::Address | |
4406 | SanitizerKind::KernelAddress)) { |
4407 | SanitizerScope SanScope(this); |
4408 | llvm::IRBuilder<>::InsertPointGuard IPGuard(Builder); |
4409 | Builder.SetInsertPoint(CI); |
4410 | auto *FnType = llvm::FunctionType::get(CGM.VoidTy, ); |
4411 | llvm::FunctionCallee Fn = |
4412 | CGM.CreateRuntimeFunction(FnType, "__asan_handle_no_return"); |
4413 | EmitNounwindRuntimeCall(Fn); |
4414 | } |
4415 | } |
4416 | |
4417 | EmitUnreachable(Loc); |
4418 | Builder.ClearInsertionPoint(); |
4419 | |
4420 | |
4421 | |
4422 | |
4423 | EnsureInsertPoint(); |
4424 | |
4425 | |
4426 | return GetUndefRValue(RetTy); |
4427 | } |
4428 | |
4429 | |
4430 | if (swiftErrorTemp.isValid()) { |
4431 | llvm::Value *errorResult = Builder.CreateLoad(swiftErrorTemp); |
4432 | Builder.CreateStore(errorResult, swiftErrorArg); |
4433 | } |
4434 | |
4435 | |
4436 | |
4437 | if (CallArgs.hasWritebacks()) |
4438 | emitWritebacks(*this, CallArgs); |
4439 | |
4440 | |
4441 | |
4442 | CallArgs.freeArgumentMemory(*this); |
4443 | |
4444 | |
4445 | RValue Ret = [&] { |
4446 | switch (RetAI.getKind()) { |
4447 | case ABIArgInfo::CoerceAndExpand: { |
4448 | auto coercionType = RetAI.getCoerceAndExpandType(); |
4449 | |
4450 | Address addr = SRetPtr; |
4451 | addr = Builder.CreateElementBitCast(addr, coercionType); |
4452 | |
4453 | getType() == RetAI.getUnpaddedCoerceAndExpandType()", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CGCall.cpp", 4453, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CI->getType() == RetAI.getUnpaddedCoerceAndExpandType()); |
4454 | bool = isa<llvm::StructType>(CI->getType()); |
4455 | |
4456 | unsigned unpaddedIndex = 0; |
4457 | for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) { |
4458 | llvm::Type *eltType = coercionType->getElementType(i); |
4459 | if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType)) continue; |
4460 | Address eltAddr = Builder.CreateStructGEP(addr, i); |
4461 | llvm::Value *elt = CI; |
4462 | if (requiresExtract) |
4463 | elt = Builder.CreateExtractValue(elt, unpaddedIndex++); |
4464 | else |
4465 | assert(unpaddedIndex == 0); |
4466 | Builder.CreateStore(elt, eltAddr); |
4467 | } |
4468 | |
4469 | LLVM_FALLTHROUGH; |
4470 | } |
4471 | |
4472 | case ABIArgInfo::InAlloca: |
4473 | case ABIArgInfo::Indirect: { |
4474 | RValue ret = convertTempToRValue(SRetPtr, RetTy, SourceLocation()); |
4475 | if (UnusedReturnSizePtr) |
4476 | PopCleanupBlock(); |
4477 | return ret; |
4478 | } |
4479 | |
4480 | case ABIArgInfo::Ignore: |
4481 | |
4482 | |
4483 | return GetUndefRValue(RetTy); |
4484 | |
4485 | case ABIArgInfo::Extend: |
4486 | case ABIArgInfo::Direct: { |
4487 | llvm::Type *RetIRTy = ConvertType(RetTy); |
4488 | if (RetAI.getCoerceToType() == RetIRTy && RetAI.getDirectOffset() == 0) { |
4489 | switch (getEvaluationKind(RetTy)) { |
4490 | case TEK_Complex: { |
4491 | llvm::Value *Real = Builder.CreateExtractValue(CI, 0); |
4492 | llvm::Value *Imag = Builder.CreateExtractValue(CI, 1); |
4493 | return RValue::getComplex(std::make_pair(Real, Imag)); |
4494 | } |
4495 | case TEK_Aggregate: { |
4496 | Address DestPtr = ReturnValue.getValue(); |
4497 | bool DestIsVolatile = ReturnValue.isVolatile(); |
4498 | |
4499 | if (!DestPtr.isValid()) { |
4500 | DestPtr = CreateMemTemp(RetTy, "agg.tmp"); |
4501 | DestIsVolatile = false; |
4502 | } |
4503 | BuildAggStore(*this, CI, DestPtr, DestIsVolatile); |
4504 | return RValue::getAggregate(DestPtr); |
4505 | } |
4506 | case TEK_Scalar: { |
4507 | |
4508 | |
4509 | llvm::Value *V = CI; |
4510 | if (V->getType() != RetIRTy) |
4511 | V = Builder.CreateBitCast(V, RetIRTy); |
4512 | return RValue::get(V); |
4513 | } |
4514 | } |
4515 | llvm_unreachable("bad evaluation kind"); |
4516 | } |
4517 | |
4518 | Address DestPtr = ReturnValue.getValue(); |
4519 | bool DestIsVolatile = ReturnValue.isVolatile(); |
4520 | |
4521 | if (!DestPtr.isValid()) { |
4522 | DestPtr = CreateMemTemp(RetTy, "coerce"); |
4523 | DestIsVolatile = false; |
4524 | } |
4525 | |
4526 | |
4527 | Address StorePtr = emitAddressAtOffset(*this, DestPtr, RetAI); |
4528 | CreateCoercedStore(CI, StorePtr, DestIsVolatile, *this); |
4529 | |
4530 | return convertTempToRValue(DestPtr, RetTy, SourceLocation()); |
4531 | } |
4532 | |
4533 | case ABIArgInfo::Expand: |
4534 | llvm_unreachable("Invalid ABI kind for return argument"); |
4535 | } |
4536 | |
4537 | llvm_unreachable("Unhandled ABIArgInfo::Kind"); |
4538 | } (); |
4539 | |
4540 | |
4541 | const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl(); |
4542 | if (Ret.isScalar() && TargetDecl) { |
4543 | if (const auto *AA = TargetDecl->getAttr<AssumeAlignedAttr>()) { |
4544 | llvm::Value *OffsetValue = nullptr; |
4545 | if (const auto *Offset = AA->getOffset()) |
4546 | OffsetValue = EmitScalarExpr(Offset); |
4547 | |
4548 | llvm::Value *Alignment = EmitScalarExpr(AA->getAlignment()); |
4549 | llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(Alignment); |
4550 | EmitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc, AA->getLocation(), |
4551 | AlignmentCI->getZExtValue(), OffsetValue); |
4552 | } else if (const auto *AA = TargetDecl->getAttr<AllocAlignAttr>()) { |
4553 | llvm::Value *AlignmentVal = CallArgs[AA->getParamIndex().getLLVMIndex()] |
4554 | .getRValue(*this) |
4555 | .getScalarVal(); |
4556 | EmitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc, AA->getLocation(), |
4557 | AlignmentVal); |
4558 | } |
4559 | } |
4560 | |
4561 | return Ret; |
4562 | } |
4563 | |
4564 | CGCallee CGCallee::prepareConcreteCallee(CodeGenFunction &CGF) const { |
4565 | if (isVirtual()) { |
4566 | const CallExpr *CE = getVirtualCallExpr(); |
4567 | return CGF.CGM.getCXXABI().getVirtualFunctionPointer( |
4568 | CGF, getVirtualMethodDecl(), getThisAddress(), getVirtualFunctionType(), |
4569 | CE ? CE->getBeginLoc() : SourceLocation()); |
4570 | } |
4571 | |
4572 | return *this; |
4573 | } |
4574 | |
4575 | |
4576 | |
4577 | Address CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr) { |
4578 | VAListAddr = VE->isMicrosoftABI() |
4579 | ? EmitMSVAListRef(VE->getSubExpr()) |
4580 | : EmitVAListRef(VE->getSubExpr()); |
4581 | QualType Ty = VE->getType(); |
4582 | if (VE->isMicrosoftABI()) |
4583 | return CGM.getTypes().getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty); |
4584 | return CGM.getTypes().getABIInfo().EmitVAArg(*this, VAListAddr, Ty); |
4585 | } |
4586 | |