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 * 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 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 58 CIRGenCallee CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const { 59 assert(!cir::MissingFeatures::opCallVirtual()); 60 return *this; 61 } 62 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 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. 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. 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 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 & 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. 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 & 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 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 & 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. 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`. 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 & 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 & 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 & 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 & 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 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 & 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 & 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 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 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 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. 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 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