xref: /freebsd/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===--- CIRGenCall.cpp - Encapsulate calling convention details ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // These classes wrap the information about a call or function definition used
10 // to handle ABI compliancy.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "CIRGenCall.h"
15 #include "CIRGenCXXABI.h"
16 #include "CIRGenFunction.h"
17 #include "CIRGenFunctionInfo.h"
18 #include "clang/CIR/MissingFeatures.h"
19 
20 using namespace clang;
21 using namespace clang::CIRGen;
22 
23 CIRGenFunctionInfo *
create(CanQualType resultType,llvm::ArrayRef<CanQualType> argTypes,RequiredArgs required)24 CIRGenFunctionInfo::create(CanQualType resultType,
25                            llvm::ArrayRef<CanQualType> argTypes,
26                            RequiredArgs required) {
27   // The first slot allocated for arg type slot is for the return value.
28   void *buffer = operator new(
29       totalSizeToAlloc<CanQualType>(argTypes.size() + 1));
30 
31   assert(!cir::MissingFeatures::opCallCIRGenFuncInfoParamInfo());
32 
33   CIRGenFunctionInfo *fi = new (buffer) CIRGenFunctionInfo();
34 
35   fi->required = required;
36   fi->numArgs = argTypes.size();
37 
38   fi->getArgTypes()[0] = resultType;
39   std::copy(argTypes.begin(), argTypes.end(), fi->argTypesBegin());
40   assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
41 
42   return fi;
43 }
44 
getFunctionType(const CIRGenFunctionInfo & fi)45 cir::FuncType CIRGenTypes::getFunctionType(const CIRGenFunctionInfo &fi) {
46   mlir::Type resultType = convertType(fi.getReturnType());
47   SmallVector<mlir::Type, 8> argTypes;
48   argTypes.reserve(fi.getNumRequiredArgs());
49 
50   for (const CanQualType &argType : fi.requiredArguments())
51     argTypes.push_back(convertType(argType));
52 
53   return cir::FuncType::get(argTypes,
54                             (resultType ? resultType : builder.getVoidTy()),
55                             fi.isVariadic());
56 }
57 
prepareConcreteCallee(CIRGenFunction & cgf) const58 CIRGenCallee CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const {
59   assert(!cir::MissingFeatures::opCallVirtual());
60   return *this;
61 }
62 
emitAggregateStore(mlir::Value value,Address dest)63 void CIRGenFunction::emitAggregateStore(mlir::Value value, Address dest) {
64   // In classic codegen:
65   // Function to store a first-class aggregate into memory. We prefer to
66   // store the elements rather than the aggregate to be more friendly to
67   // fast-isel.
68   // In CIR codegen:
69   // Emit the most simple cir.store possible (e.g. a store for a whole
70   // record), which can later be broken down in other CIR levels (or prior
71   // to dialect codegen).
72 
73   // Stored result for the callers of this function expected to be in the same
74   // scope as the value, don't make assumptions about current insertion point.
75   mlir::OpBuilder::InsertionGuard guard(builder);
76   builder.setInsertionPointAfter(value.getDefiningOp());
77   builder.createStore(*currSrcLoc, value, dest);
78 }
79 
addAttributesFromFunctionProtoType(CIRGenBuilderTy & builder,mlir::NamedAttrList & attrs,const FunctionProtoType * fpt)80 static void addAttributesFromFunctionProtoType(CIRGenBuilderTy &builder,
81                                                mlir::NamedAttrList &attrs,
82                                                const FunctionProtoType *fpt) {
83   if (!fpt)
84     return;
85 
86   if (!isUnresolvedExceptionSpec(fpt->getExceptionSpecType()) &&
87       fpt->isNothrow())
88     attrs.set(cir::CIRDialect::getNoThrowAttrName(),
89               mlir::UnitAttr::get(builder.getContext()));
90 }
91 
92 /// Construct the CIR attribute list of a function or call.
constructAttributeList(CIRGenCalleeInfo calleeInfo,mlir::NamedAttrList & attrs)93 void CIRGenModule::constructAttributeList(CIRGenCalleeInfo calleeInfo,
94                                           mlir::NamedAttrList &attrs) {
95   assert(!cir::MissingFeatures::opCallCallConv());
96   auto sideEffect = cir::SideEffect::All;
97 
98   addAttributesFromFunctionProtoType(getBuilder(), attrs,
99                                      calleeInfo.getCalleeFunctionProtoType());
100 
101   const Decl *targetDecl = calleeInfo.getCalleeDecl().getDecl();
102 
103   if (targetDecl) {
104     if (targetDecl->hasAttr<NoThrowAttr>())
105       attrs.set(cir::CIRDialect::getNoThrowAttrName(),
106                 mlir::UnitAttr::get(&getMLIRContext()));
107 
108     if (const FunctionDecl *func = dyn_cast<FunctionDecl>(targetDecl)) {
109       addAttributesFromFunctionProtoType(
110           getBuilder(), attrs, func->getType()->getAs<FunctionProtoType>());
111       assert(!cir::MissingFeatures::opCallAttrs());
112     }
113 
114     assert(!cir::MissingFeatures::opCallAttrs());
115 
116     // 'const', 'pure' and 'noalias' attributed functions are also nounwind.
117     if (targetDecl->hasAttr<ConstAttr>()) {
118       // gcc specifies that 'const' functions have greater restrictions than
119       // 'pure' functions, so they also cannot have infinite loops.
120       sideEffect = cir::SideEffect::Const;
121     } else if (targetDecl->hasAttr<PureAttr>()) {
122       // gcc specifies that 'pure' functions cannot have infinite loops.
123       sideEffect = cir::SideEffect::Pure;
124     }
125 
126     assert(!cir::MissingFeatures::opCallAttrs());
127   }
128 
129   assert(!cir::MissingFeatures::opCallAttrs());
130 
131   attrs.set(cir::CIRDialect::getSideEffectAttrName(),
132             cir::SideEffectAttr::get(&getMLIRContext(), sideEffect));
133 }
134 
135 /// Returns the canonical formal type of the given C++ method.
getFormalType(const CXXMethodDecl * md)136 static CanQual<FunctionProtoType> getFormalType(const CXXMethodDecl *md) {
137   return md->getType()
138       ->getCanonicalTypeUnqualified()
139       .getAs<FunctionProtoType>();
140 }
141 
142 /// Adds the formal parameters in FPT to the given prefix. If any parameter in
143 /// FPT has pass_object_size_attrs, then we'll add parameters for those, too.
144 /// TODO(cir): this should be shared with LLVM codegen
appendParameterTypes(const CIRGenTypes & cgt,SmallVectorImpl<CanQualType> & prefix,CanQual<FunctionProtoType> fpt)145 static void appendParameterTypes(const CIRGenTypes &cgt,
146                                  SmallVectorImpl<CanQualType> &prefix,
147                                  CanQual<FunctionProtoType> fpt) {
148   assert(!cir::MissingFeatures::opCallExtParameterInfo());
149   // Fast path: don't touch param info if we don't need to.
150   if (!fpt->hasExtParameterInfos()) {
151     prefix.append(fpt->param_type_begin(), fpt->param_type_end());
152     return;
153   }
154 
155   cgt.getCGModule().errorNYI("appendParameterTypes: hasExtParameterInfos");
156 }
157 
158 const CIRGenFunctionInfo &
arrangeCXXStructorDeclaration(GlobalDecl gd)159 CIRGenTypes::arrangeCXXStructorDeclaration(GlobalDecl gd) {
160   auto *md = cast<CXXMethodDecl>(gd.getDecl());
161 
162   llvm::SmallVector<CanQualType, 16> argTypes;
163   argTypes.push_back(deriveThisType(md->getParent(), md));
164 
165   bool passParams = true;
166 
167   if (auto *cd = dyn_cast<CXXConstructorDecl>(md)) {
168     // A base class inheriting constructor doesn't get forwarded arguments
169     // needed to construct a virtual base (or base class thereof)
170     if (cd->getInheritedConstructor())
171       cgm.errorNYI(cd->getSourceRange(),
172                    "arrangeCXXStructorDeclaration: inheriting constructor");
173   }
174 
175   CanQual<FunctionProtoType> fpt = getFormalType(md);
176 
177   if (passParams)
178     appendParameterTypes(*this, argTypes, fpt);
179 
180   assert(!cir::MissingFeatures::implicitConstructorArgs());
181 
182   RequiredArgs required =
183       (passParams && md->isVariadic() ? RequiredArgs(argTypes.size())
184                                       : RequiredArgs::All);
185 
186   CanQualType resultType = theCXXABI.hasThisReturn(gd) ? argTypes.front()
187                            : theCXXABI.hasMostDerivedReturn(gd)
188                                ? astContext.VoidPtrTy
189                                : astContext.VoidTy;
190 
191   assert(!theCXXABI.hasThisReturn(gd) &&
192          "Please send PR with a test and remove this");
193 
194   assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
195   assert(!cir::MissingFeatures::opCallFnInfoOpts());
196 
197   return arrangeCIRFunctionInfo(resultType, argTypes, required);
198 }
199 
200 /// Derives the 'this' type for CIRGen purposes, i.e. ignoring method CVR
201 /// qualification. Either or both of `rd` and `md` may be null. A null `rd`
202 /// indicates that there is no meaningful 'this' type, and a null `md` can occur
203 /// when calling a method pointer.
deriveThisType(const CXXRecordDecl * rd,const CXXMethodDecl * md)204 CanQualType CIRGenTypes::deriveThisType(const CXXRecordDecl *rd,
205                                         const CXXMethodDecl *md) {
206   QualType recTy;
207   if (rd) {
208     recTy = getASTContext().getTagDeclType(rd)->getCanonicalTypeInternal();
209   } else {
210     // This can happen with the MS ABI. It shouldn't need anything more than
211     // setting recTy to VoidTy here, but we're flagging it for now because we
212     // don't have the full handling implemented.
213     cgm.errorNYI("deriveThisType: no record decl");
214     recTy = getASTContext().VoidTy;
215   }
216 
217   if (md)
218     recTy = getASTContext().getAddrSpaceQualType(
219         recTy, md->getMethodQualifiers().getAddressSpace());
220   return getASTContext().getPointerType(CanQualType::CreateUnsafe(recTy));
221 }
222 
223 /// Arrange the CIR function layout for a value of the given function type, on
224 /// top of any implicit parameters already stored.
225 static const CIRGenFunctionInfo &
arrangeCIRFunctionInfo(CIRGenTypes & cgt,SmallVectorImpl<CanQualType> & prefix,CanQual<FunctionProtoType> fpt)226 arrangeCIRFunctionInfo(CIRGenTypes &cgt, SmallVectorImpl<CanQualType> &prefix,
227                        CanQual<FunctionProtoType> fpt) {
228   assert(!cir::MissingFeatures::opCallFnInfoOpts());
229   RequiredArgs required =
230       RequiredArgs::getFromProtoWithExtraSlots(fpt, prefix.size());
231   assert(!cir::MissingFeatures::opCallExtParameterInfo());
232   appendParameterTypes(cgt, prefix, fpt);
233   CanQualType resultType = fpt->getReturnType().getUnqualifiedType();
234   return cgt.arrangeCIRFunctionInfo(resultType, prefix, required);
235 }
236 
emitDelegateCallArg(CallArgList & args,const VarDecl * param,SourceLocation loc)237 void CIRGenFunction::emitDelegateCallArg(CallArgList &args,
238                                          const VarDecl *param,
239                                          SourceLocation loc) {
240   // StartFunction converted the ABI-lowered parameter(s) into a local alloca.
241   // We need to turn that into an r-value suitable for emitCall
242   Address local = getAddrOfLocalVar(param);
243 
244   QualType type = param->getType();
245 
246   if (type->getAsCXXRecordDecl()) {
247     cgm.errorNYI(param->getSourceRange(),
248                  "emitDelegateCallArg: record argument");
249     return;
250   }
251 
252   // GetAddrOfLocalVar returns a pointer-to-pointer for references, but the
253   // argument needs to be the original pointer.
254   if (type->isReferenceType()) {
255     args.add(
256         RValue::get(builder.createLoad(getLoc(param->getSourceRange()), local)),
257         type);
258   } else if (getLangOpts().ObjCAutoRefCount) {
259     cgm.errorNYI(param->getSourceRange(),
260                  "emitDelegateCallArg: ObjCAutoRefCount");
261     // For the most part, we just need to load the alloca, except that aggregate
262     // r-values are actually pointers to temporaries.
263   } else {
264     args.add(convertTempToRValue(local, type, loc), type);
265   }
266 
267   // Deactivate the cleanup for the callee-destructed param that was pushed.
268   assert(!cir::MissingFeatures::thunks());
269   if (type->isRecordType() &&
270       type->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee() &&
271       param->needsDestruction(getContext())) {
272     cgm.errorNYI(param->getSourceRange(),
273                  "emitDelegateCallArg: callee-destructed param");
274   }
275 }
276 
277 static const CIRGenFunctionInfo &
arrangeFreeFunctionLikeCall(CIRGenTypes & cgt,CIRGenModule & cgm,const CallArgList & args,const FunctionType * fnType)278 arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm,
279                             const CallArgList &args,
280                             const FunctionType *fnType) {
281 
282   RequiredArgs required = RequiredArgs::All;
283 
284   if (const auto *proto = dyn_cast<FunctionProtoType>(fnType)) {
285     if (proto->isVariadic())
286       required = RequiredArgs::getFromProtoWithExtraSlots(proto, 0);
287     if (proto->hasExtParameterInfos())
288       cgm.errorNYI("call to functions with extra parameter info");
289   } else if (cgm.getTargetCIRGenInfo().isNoProtoCallVariadic(
290                  cast<FunctionNoProtoType>(fnType)))
291     cgm.errorNYI("call to function without a prototype");
292 
293   SmallVector<CanQualType, 16> argTypes;
294   for (const CallArg &arg : args)
295     argTypes.push_back(cgt.getASTContext().getCanonicalParamType(arg.ty));
296 
297   CanQualType retType = fnType->getReturnType()
298                             ->getCanonicalTypeUnqualified()
299                             .getUnqualifiedType();
300 
301   assert(!cir::MissingFeatures::opCallFnInfoOpts());
302   return cgt.arrangeCIRFunctionInfo(retType, argTypes, required);
303 }
304 
305 /// Arrange a call to a C++ method, passing the given arguments.
306 ///
307 /// passProtoArgs indicates whether `args` has args for the parameters in the
308 /// given CXXConstructorDecl.
arrangeCXXConstructorCall(const CallArgList & args,const CXXConstructorDecl * d,CXXCtorType ctorKind,bool passProtoArgs)309 const CIRGenFunctionInfo &CIRGenTypes::arrangeCXXConstructorCall(
310     const CallArgList &args, const CXXConstructorDecl *d, CXXCtorType ctorKind,
311     bool passProtoArgs) {
312 
313   // FIXME: Kill copy.
314   llvm::SmallVector<CanQualType, 16> argTypes;
315   for (const auto &arg : args)
316     argTypes.push_back(astContext.getCanonicalParamType(arg.ty));
317 
318   assert(!cir::MissingFeatures::implicitConstructorArgs());
319   // +1 for implicit this, which should always be args[0]
320   unsigned totalPrefixArgs = 1;
321 
322   CanQual<FunctionProtoType> fpt = getFormalType(d);
323   RequiredArgs required =
324       passProtoArgs
325           ? RequiredArgs::getFromProtoWithExtraSlots(fpt, totalPrefixArgs)
326           : RequiredArgs::All;
327 
328   GlobalDecl gd(d, ctorKind);
329   if (theCXXABI.hasThisReturn(gd))
330     cgm.errorNYI(d->getSourceRange(),
331                  "arrangeCXXConstructorCall: hasThisReturn");
332   if (theCXXABI.hasMostDerivedReturn(gd))
333     cgm.errorNYI(d->getSourceRange(),
334                  "arrangeCXXConstructorCall: hasMostDerivedReturn");
335   CanQualType resultType = astContext.VoidTy;
336 
337   assert(!cir::MissingFeatures::opCallFnInfoOpts());
338   assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
339 
340   return arrangeCIRFunctionInfo(resultType, argTypes, required);
341 }
342 
343 /// Arrange a call to a C++ method, passing the given arguments.
344 ///
345 /// numPrefixArgs is the number of the ABI-specific prefix arguments we have. It
346 /// does not count `this`.
arrangeCXXMethodCall(const CallArgList & args,const FunctionProtoType * proto,RequiredArgs required,unsigned numPrefixArgs)347 const CIRGenFunctionInfo &CIRGenTypes::arrangeCXXMethodCall(
348     const CallArgList &args, const FunctionProtoType *proto,
349     RequiredArgs required, unsigned numPrefixArgs) {
350   assert(!cir::MissingFeatures::opCallExtParameterInfo());
351   assert(numPrefixArgs + 1 <= args.size() &&
352          "Emitting a call with less args than the required prefix?");
353 
354   // FIXME: Kill copy.
355   llvm::SmallVector<CanQualType, 16> argTypes;
356   for (const CallArg &arg : args)
357     argTypes.push_back(astContext.getCanonicalParamType(arg.ty));
358 
359   assert(!cir::MissingFeatures::opCallFnInfoOpts());
360   return arrangeCIRFunctionInfo(proto->getReturnType()
361                                     ->getCanonicalTypeUnqualified()
362                                     .getUnqualifiedType(),
363                                 argTypes, required);
364 }
365 
366 const CIRGenFunctionInfo &
arrangeFreeFunctionCall(const CallArgList & args,const FunctionType * fnType)367 CIRGenTypes::arrangeFreeFunctionCall(const CallArgList &args,
368                                      const FunctionType *fnType) {
369   return arrangeFreeFunctionLikeCall(*this, cgm, args, fnType);
370 }
371 
372 /// Arrange the argument and result information for a declaration or definition
373 /// of the given C++ non-static member function. The member function must be an
374 /// ordinary function, i.e. not a constructor or destructor.
375 const CIRGenFunctionInfo &
arrangeCXXMethodDeclaration(const CXXMethodDecl * md)376 CIRGenTypes::arrangeCXXMethodDeclaration(const CXXMethodDecl *md) {
377   assert(!isa<CXXConstructorDecl>(md) && "wrong method for constructors!");
378   assert(!isa<CXXDestructorDecl>(md) && "wrong method for destructors!");
379 
380   auto prototype =
381       md->getType()->getCanonicalTypeUnqualified().getAs<FunctionProtoType>();
382   assert(!cir::MissingFeatures::cudaSupport());
383 
384   if (md->isInstance()) {
385     // The abstract case is perfectly fine.
386     auto *thisType = theCXXABI.getThisArgumentTypeForMethod(md);
387     return arrangeCXXMethodType(thisType, prototype.getTypePtr(), md);
388   }
389 
390   return arrangeFreeFunctionType(prototype);
391 }
392 
393 /// Arrange the argument and result information for a call to an unknown C++
394 /// non-static member function of the given abstract type. (A null RD means we
395 /// don't have any meaningful "this" argument type, so fall back to a generic
396 /// pointer type). The member fucntion must be an ordinary function, i.e. not a
397 /// constructor or destructor.
398 const CIRGenFunctionInfo &
arrangeCXXMethodType(const CXXRecordDecl * rd,const FunctionProtoType * fpt,const CXXMethodDecl * md)399 CIRGenTypes::arrangeCXXMethodType(const CXXRecordDecl *rd,
400                                   const FunctionProtoType *fpt,
401                                   const CXXMethodDecl *md) {
402   llvm::SmallVector<CanQualType, 16> argTypes;
403 
404   // Add the 'this' pointer.
405   argTypes.push_back(deriveThisType(rd, md));
406 
407   assert(!cir::MissingFeatures::opCallFnInfoOpts());
408   return ::arrangeCIRFunctionInfo(
409       *this, argTypes,
410       fpt->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
411 }
412 
413 /// Arrange the argument and result information for the declaration or
414 /// definition of the given function.
415 const CIRGenFunctionInfo &
arrangeFunctionDeclaration(const FunctionDecl * fd)416 CIRGenTypes::arrangeFunctionDeclaration(const FunctionDecl *fd) {
417   if (const auto *md = dyn_cast<CXXMethodDecl>(fd))
418     if (md->isInstance())
419       return arrangeCXXMethodDeclaration(md);
420 
421   CanQualType funcTy = fd->getType()->getCanonicalTypeUnqualified();
422 
423   assert(isa<FunctionType>(funcTy));
424   // TODO: setCUDAKernelCallingConvention
425   assert(!cir::MissingFeatures::cudaSupport());
426 
427   // When declaring a function without a prototype, always use a non-variadic
428   // type.
429   if (CanQual<FunctionNoProtoType> noProto =
430           funcTy.getAs<FunctionNoProtoType>()) {
431     assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
432     assert(!cir::MissingFeatures::opCallFnInfoOpts());
433     return arrangeCIRFunctionInfo(noProto->getReturnType(), {},
434                                   RequiredArgs::All);
435   }
436 
437   return arrangeFreeFunctionType(funcTy.castAs<FunctionProtoType>());
438 }
439 
440 static cir::CIRCallOpInterface
emitCallLikeOp(CIRGenFunction & cgf,mlir::Location callLoc,cir::FuncType indirectFuncTy,mlir::Value indirectFuncVal,cir::FuncOp directFuncOp,const SmallVectorImpl<mlir::Value> & cirCallArgs,const mlir::NamedAttrList & attrs)441 emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
442                cir::FuncType indirectFuncTy, mlir::Value indirectFuncVal,
443                cir::FuncOp directFuncOp,
444                const SmallVectorImpl<mlir::Value> &cirCallArgs,
445                const mlir::NamedAttrList &attrs) {
446   CIRGenBuilderTy &builder = cgf.getBuilder();
447 
448   assert(!cir::MissingFeatures::opCallSurroundingTry());
449   assert(!cir::MissingFeatures::invokeOp());
450 
451   assert(builder.getInsertionBlock() && "expected valid basic block");
452 
453   cir::CallOp op;
454   if (indirectFuncTy) {
455     // TODO(cir): Set calling convention for indirect calls.
456     assert(!cir::MissingFeatures::opCallCallConv());
457     op = builder.createIndirectCallOp(callLoc, indirectFuncVal, indirectFuncTy,
458                                       cirCallArgs, attrs);
459   } else {
460     op = builder.createCallOp(callLoc, directFuncOp, cirCallArgs, attrs);
461   }
462 
463   return op;
464 }
465 
466 const CIRGenFunctionInfo &
arrangeFreeFunctionType(CanQual<FunctionProtoType> fpt)467 CIRGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> fpt) {
468   SmallVector<CanQualType, 16> argTypes;
469   assert(!cir::MissingFeatures::opCallFnInfoOpts());
470   return ::arrangeCIRFunctionInfo(*this, argTypes, fpt);
471 }
472 
473 const CIRGenFunctionInfo &
arrangeFreeFunctionType(CanQual<FunctionNoProtoType> fnpt)474 CIRGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> fnpt) {
475   CanQualType resultType = fnpt->getReturnType().getUnqualifiedType();
476   assert(!cir::MissingFeatures::opCallFnInfoOpts());
477   return arrangeCIRFunctionInfo(resultType, {}, RequiredArgs(0));
478 }
479 
emitCall(const CIRGenFunctionInfo & funcInfo,const CIRGenCallee & callee,ReturnValueSlot returnValue,const CallArgList & args,cir::CIRCallOpInterface * callOp,mlir::Location loc)480 RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
481                                 const CIRGenCallee &callee,
482                                 ReturnValueSlot returnValue,
483                                 const CallArgList &args,
484                                 cir::CIRCallOpInterface *callOp,
485                                 mlir::Location loc) {
486   QualType retTy = funcInfo.getReturnType();
487   cir::FuncType cirFuncTy = getTypes().getFunctionType(funcInfo);
488 
489   SmallVector<mlir::Value, 16> cirCallArgs(args.size());
490 
491   assert(!cir::MissingFeatures::emitLifetimeMarkers());
492 
493   // Translate all of the arguments as necessary to match the CIR lowering.
494   for (auto [argNo, arg, canQualArgType] :
495        llvm::enumerate(args, funcInfo.argTypes())) {
496 
497     // Insert a padding argument to ensure proper alignment.
498     assert(!cir::MissingFeatures::opCallPaddingArgs());
499 
500     mlir::Type argType = convertType(canQualArgType);
501     if (!mlir::isa<cir::RecordType>(argType)) {
502       mlir::Value v;
503       if (arg.isAggregate())
504         cgm.errorNYI(loc, "emitCall: aggregate call argument");
505       v = arg.getKnownRValue().getValue();
506 
507       // We might have to widen integers, but we should never truncate.
508       if (argType != v.getType() && mlir::isa<cir::IntType>(v.getType()))
509         cgm.errorNYI(loc, "emitCall: widening integer call argument");
510 
511       // If the argument doesn't match, perform a bitcast to coerce it. This
512       // can happen due to trivial type mismatches.
513       // TODO(cir): When getFunctionType is added, assert that this isn't
514       // needed.
515       assert(!cir::MissingFeatures::opCallBitcastArg());
516       cirCallArgs[argNo] = v;
517     } else {
518       Address src = Address::invalid();
519       if (!arg.isAggregate())
520         cgm.errorNYI(loc, "emitCall: non-aggregate call argument");
521       else
522         src = arg.hasLValue() ? arg.getKnownLValue().getAddress()
523                               : arg.getKnownRValue().getAggregateAddress();
524 
525       // Fast-isel and the optimizer generally like scalar values better than
526       // FCAs, so we flatten them if this is safe to do for this argument.
527       auto argRecordTy = cast<cir::RecordType>(argType);
528       mlir::Type srcTy = src.getElementType();
529       // FIXME(cir): get proper location for each argument.
530       mlir::Location argLoc = loc;
531 
532       // If the source type is smaller than the destination type of the
533       // coerce-to logic, copy the source value into a temp alloca the size
534       // of the destination type to allow loading all of it. The bits past
535       // the source value are left undef.
536       // FIXME(cir): add data layout info and compare sizes instead of
537       // matching the types.
538       //
539       // uint64_t SrcSize = CGM.getDataLayout().getTypeAllocSize(SrcTy);
540       // uint64_t DstSize = CGM.getDataLayout().getTypeAllocSize(STy);
541       // if (SrcSize < DstSize) {
542       assert(!cir::MissingFeatures::dataLayoutTypeAllocSize());
543       if (srcTy != argRecordTy) {
544         cgm.errorNYI(loc, "emitCall: source type does not match argument type");
545       } else {
546         // FIXME(cir): this currently only runs when the types are exactly the
547         // same, but should be when alloc sizes are the same, fix this as soon
548         // as datalayout gets introduced.
549         assert(!cir::MissingFeatures::dataLayoutTypeAllocSize());
550       }
551 
552       // assert(NumCIRArgs == STy.getMembers().size());
553       // In LLVMGen: Still only pass the struct without any gaps but mark it
554       // as such somehow.
555       //
556       // In CIRGen: Emit a load from the "whole" struct,
557       // which shall be broken later by some lowering step into multiple
558       // loads.
559       assert(!cir::MissingFeatures::lowerAggregateLoadStore());
560       cirCallArgs[argNo] = builder.createLoad(argLoc, src);
561     }
562   }
563 
564   const CIRGenCallee &concreteCallee = callee.prepareConcreteCallee(*this);
565   mlir::Operation *calleePtr = concreteCallee.getFunctionPointer();
566 
567   assert(!cir::MissingFeatures::opCallInAlloca());
568 
569   mlir::NamedAttrList attrs;
570   StringRef funcName;
571   if (auto calleeFuncOp = dyn_cast<cir::FuncOp>(calleePtr))
572     funcName = calleeFuncOp.getName();
573 
574   assert(!cir::MissingFeatures::opCallCallConv());
575   assert(!cir::MissingFeatures::opCallAttrs());
576   cgm.constructAttributeList(callee.getAbstractInfo(), attrs);
577 
578   assert(!cir::MissingFeatures::invokeOp());
579 
580   cir::FuncType indirectFuncTy;
581   mlir::Value indirectFuncVal;
582   cir::FuncOp directFuncOp;
583   if (auto fnOp = dyn_cast<cir::FuncOp>(calleePtr)) {
584     directFuncOp = fnOp;
585   } else {
586     [[maybe_unused]] mlir::ValueTypeRange<mlir::ResultRange> resultTypes =
587         calleePtr->getResultTypes();
588     [[maybe_unused]] auto funcPtrTy =
589         mlir::dyn_cast<cir::PointerType>(resultTypes.front());
590     assert(funcPtrTy && mlir::isa<cir::FuncType>(funcPtrTy.getPointee()) &&
591            "expected pointer to function");
592 
593     indirectFuncTy = cirFuncTy;
594     indirectFuncVal = calleePtr->getResult(0);
595   }
596 
597   mlir::Location callLoc = loc;
598   cir::CIRCallOpInterface theCall =
599       emitCallLikeOp(*this, loc, indirectFuncTy, indirectFuncVal, directFuncOp,
600                      cirCallArgs, attrs);
601 
602   if (callOp)
603     *callOp = theCall;
604 
605   assert(!cir::MissingFeatures::opCallMustTail());
606   assert(!cir::MissingFeatures::opCallReturn());
607 
608   mlir::Type retCIRTy = convertType(retTy);
609   if (isa<cir::VoidType>(retCIRTy))
610     return getUndefRValue(retTy);
611   switch (getEvaluationKind(retTy)) {
612   case cir::TEK_Aggregate: {
613     Address destPtr = returnValue.getValue();
614 
615     if (!destPtr.isValid())
616       destPtr = createMemTemp(retTy, callLoc, getCounterAggTmpAsString());
617 
618     mlir::ResultRange results = theCall->getOpResults();
619     assert(results.size() <= 1 && "multiple returns from a call");
620 
621     SourceLocRAIIObject loc{*this, callLoc};
622     emitAggregateStore(results[0], destPtr);
623     return RValue::getAggregate(destPtr);
624   }
625   case cir::TEK_Scalar: {
626     mlir::ResultRange results = theCall->getOpResults();
627     assert(results.size() == 1 && "unexpected number of returns");
628 
629     // If the argument doesn't match, perform a bitcast to coerce it. This
630     // can happen due to trivial type mismatches.
631     if (results[0].getType() != retCIRTy)
632       cgm.errorNYI(loc, "bitcast on function return value");
633 
634     mlir::Region *region = builder.getBlock()->getParent();
635     if (region != theCall->getParentRegion())
636       cgm.errorNYI(loc, "function calls with cleanup");
637 
638     return RValue::get(results[0]);
639   }
640   case cir::TEK_Complex:
641     cgm.errorNYI(loc, "unsupported evaluation kind of function call result");
642     return getUndefRValue(retTy);
643   }
644   llvm_unreachable("Invalid evaluation kind");
645 }
646 
emitCallArg(CallArgList & args,const clang::Expr * e,clang::QualType argType)647 void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,
648                                  clang::QualType argType) {
649   assert(argType->isReferenceType() == e->isGLValue() &&
650          "reference binding to unmaterialized r-value!");
651 
652   if (e->isGLValue()) {
653     assert(e->getObjectKind() == OK_Ordinary);
654     return args.add(emitReferenceBindingToExpr(e), argType);
655   }
656 
657   bool hasAggregateEvalKind = hasAggregateEvaluationKind(argType);
658 
659   // In the Microsoft C++ ABI, aggregate arguments are destructed by the callee.
660   // However, we still have to push an EH-only cleanup in case we unwind before
661   // we make it to the call.
662   if (argType->isRecordType() &&
663       argType->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee()) {
664     assert(!cir::MissingFeatures::msabi());
665     cgm.errorNYI(e->getSourceRange(), "emitCallArg: msabi is NYI");
666   }
667 
668   if (hasAggregateEvalKind && isa<ImplicitCastExpr>(e) &&
669       cast<CastExpr>(e)->getCastKind() == CK_LValueToRValue) {
670     LValue lv = emitLValue(cast<CastExpr>(e)->getSubExpr());
671     assert(lv.isSimple());
672     args.addUncopiedAggregate(lv, argType);
673     return;
674   }
675 
676   args.add(emitAnyExprToTemp(e), argType);
677 }
678 
getVarArgType(const Expr * arg)679 QualType CIRGenFunction::getVarArgType(const Expr *arg) {
680   // System headers on Windows define NULL to 0 instead of 0LL on Win64. MSVC
681   // implicitly widens null pointer constants that are arguments to varargs
682   // functions to pointer-sized ints.
683   if (!getTarget().getTriple().isOSWindows())
684     return arg->getType();
685 
686   assert(!cir::MissingFeatures::msabi());
687   cgm.errorNYI(arg->getSourceRange(), "getVarArgType: NYI for Windows target");
688   return arg->getType();
689 }
690 
691 /// Similar to emitAnyExpr(), however, the result will always be accessible
692 /// even if no aggregate location is provided.
emitAnyExprToTemp(const Expr * e)693 RValue CIRGenFunction::emitAnyExprToTemp(const Expr *e) {
694   AggValueSlot aggSlot = AggValueSlot::ignored();
695 
696   if (hasAggregateEvaluationKind(e->getType()))
697     aggSlot = createAggTemp(e->getType(), getLoc(e->getSourceRange()),
698                             getCounterAggTmpAsString());
699 
700   return emitAnyExpr(e, aggSlot);
701 }
702 
emitCallArgs(CallArgList & args,PrototypeWrapper prototype,llvm::iterator_range<clang::CallExpr::const_arg_iterator> argRange,AbstractCallee callee,unsigned paramsToSkip)703 void CIRGenFunction::emitCallArgs(
704     CallArgList &args, PrototypeWrapper prototype,
705     llvm::iterator_range<clang::CallExpr::const_arg_iterator> argRange,
706     AbstractCallee callee, unsigned paramsToSkip) {
707   llvm::SmallVector<QualType, 16> argTypes;
708 
709   assert(!cir::MissingFeatures::opCallCallConv());
710 
711   // First, if a prototype was provided, use those argument types.
712   bool isVariadic = false;
713   if (prototype.p) {
714     assert(!cir::MissingFeatures::opCallObjCMethod());
715 
716     const auto *fpt = cast<const FunctionProtoType *>(prototype.p);
717     isVariadic = fpt->isVariadic();
718     assert(!cir::MissingFeatures::opCallCallConv());
719     argTypes.assign(fpt->param_type_begin() + paramsToSkip,
720                     fpt->param_type_end());
721   }
722 
723   // If we still have any arguments, emit them using the type of the argument.
724   for (const clang::Expr *a : llvm::drop_begin(argRange, argTypes.size()))
725     argTypes.push_back(isVariadic ? getVarArgType(a) : a->getType());
726   assert(argTypes.size() == (size_t)(argRange.end() - argRange.begin()));
727 
728   // We must evaluate arguments from right to left in the MS C++ ABI, because
729   // arguments are destroyed left to right in the callee. As a special case,
730   // there are certain language constructs taht require left-to-right
731   // evaluation, and in those cases we consider the evaluation order requirement
732   // to trump the "destruction order is reverse construction order" guarantee.
733   auto leftToRight = true;
734   assert(!cir::MissingFeatures::msabi());
735 
736   auto maybeEmitImplicitObjectSize = [&](size_t i, const Expr *arg,
737                                          RValue emittedArg) {
738     if (!callee.hasFunctionDecl() || i >= callee.getNumParams())
739       return;
740     auto *ps = callee.getParamDecl(i)->getAttr<PassObjectSizeAttr>();
741     if (!ps)
742       return;
743 
744     assert(!cir::MissingFeatures::opCallImplicitObjectSizeArgs());
745     cgm.errorNYI("emit implicit object size for call arg");
746   };
747 
748   // Evaluate each argument in the appropriate order.
749   size_t callArgsStart = args.size();
750   for (size_t i = 0; i != argTypes.size(); ++i) {
751     size_t idx = leftToRight ? i : argTypes.size() - i - 1;
752     CallExpr::const_arg_iterator currentArg = argRange.begin() + idx;
753     size_t initialArgSize = args.size();
754 
755     emitCallArg(args, *currentArg, argTypes[idx]);
756 
757     // In particular, we depend on it being the last arg in Args, and the
758     // objectsize bits depend on there only being one arg if !LeftToRight.
759     assert(initialArgSize + 1 == args.size() &&
760            "The code below depends on only adding one arg per emitCallArg");
761     (void)initialArgSize;
762 
763     // Since pointer argument are never emitted as LValue, it is safe to emit
764     // non-null argument check for r-value only.
765     if (!args.back().hasLValue()) {
766       RValue rvArg = args.back().getKnownRValue();
767       assert(!cir::MissingFeatures::sanitizers());
768       maybeEmitImplicitObjectSize(idx, *currentArg, rvArg);
769     }
770 
771     if (!leftToRight)
772       std::reverse(args.begin() + callArgsStart, args.end());
773   }
774 }
775