1 //==-- CGFunctionInfo.h - Representation of function argument/return types -==// 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 // Defines CGFunctionInfo and associated types used in representing the 10 // LLVM source types and ABI-coerced types for function arguments and 11 // return values. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H 16 #define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H 17 18 #include "clang/AST/CanonicalType.h" 19 #include "clang/AST/CharUnits.h" 20 #include "clang/AST/Decl.h" 21 #include "clang/AST/Type.h" 22 #include "llvm/IR/DerivedTypes.h" 23 #include "llvm/ADT/FoldingSet.h" 24 #include "llvm/Support/TrailingObjects.h" 25 #include <cassert> 26 27 namespace clang { 28 namespace CodeGen { 29 30 /// ABIArgInfo - Helper class to encapsulate information about how a 31 /// specific C type should be passed to or returned from a function. 32 class ABIArgInfo { 33 public: 34 enum Kind : uint8_t { 35 /// Direct - Pass the argument directly using the normal converted LLVM 36 /// type, or by coercing to another specified type stored in 37 /// 'CoerceToType'). If an offset is specified (in UIntData), then the 38 /// argument passed is offset by some number of bytes in the memory 39 /// representation. A dummy argument is emitted before the real argument 40 /// if the specified type stored in "PaddingType" is not zero. 41 Direct, 42 43 /// Extend - Valid only for integer argument types. Same as 'direct' 44 /// but also emit a zero/sign extension attribute. 45 Extend, 46 47 /// Indirect - Pass the argument indirectly via a hidden pointer with the 48 /// specified alignment (0 indicates default alignment) and address space. 49 Indirect, 50 51 /// IndirectAliased - Similar to Indirect, but the pointer may be to an 52 /// object that is otherwise referenced. The object is known to not be 53 /// modified through any other references for the duration of the call, and 54 /// the callee must not itself modify the object. Because C allows 55 /// parameter variables to be modified and guarantees that they have unique 56 /// addresses, the callee must defensively copy the object into a local 57 /// variable if it might be modified or its address might be compared. 58 /// Since those are uncommon, in principle this convention allows programs 59 /// to avoid copies in more situations. However, it may introduce *extra* 60 /// copies if the callee fails to prove that a copy is unnecessary and the 61 /// caller naturally produces an unaliased object for the argument. 62 IndirectAliased, 63 64 /// Ignore - Ignore the argument (treat as void). Useful for void and 65 /// empty structs. 66 Ignore, 67 68 /// Expand - Only valid for aggregate argument types. The structure should 69 /// be expanded into consecutive arguments for its constituent fields. 70 /// Currently expand is only allowed on structures whose fields 71 /// are all scalar types or are themselves expandable types. 72 Expand, 73 74 /// CoerceAndExpand - Only valid for aggregate argument types. The 75 /// structure should be expanded into consecutive arguments corresponding 76 /// to the non-array elements of the type stored in CoerceToType. 77 /// Array elements in the type are assumed to be padding and skipped. 78 CoerceAndExpand, 79 80 /// InAlloca - Pass the argument directly using the LLVM inalloca attribute. 81 /// This is similar to indirect with byval, except it only applies to 82 /// arguments stored in memory and forbids any implicit copies. When 83 /// applied to a return type, it means the value is returned indirectly via 84 /// an implicit sret parameter stored in the argument struct. 85 InAlloca, 86 KindFirst = Direct, 87 KindLast = InAlloca 88 }; 89 90 private: 91 llvm::Type *TypeData; // canHaveCoerceToType() 92 union { 93 llvm::Type *PaddingType; // canHavePaddingType() 94 llvm::Type *UnpaddedCoerceAndExpandType; // isCoerceAndExpand() 95 }; 96 struct DirectAttrInfo { 97 unsigned Offset; 98 unsigned Align; 99 }; 100 struct IndirectAttrInfo { 101 unsigned Align; 102 unsigned AddrSpace; 103 }; 104 union { 105 DirectAttrInfo DirectAttr; // isDirect() || isExtend() 106 IndirectAttrInfo IndirectAttr; // isIndirect() 107 unsigned AllocaFieldIndex; // isInAlloca() 108 }; 109 Kind TheKind; 110 bool PaddingInReg : 1; 111 bool InAllocaSRet : 1; // isInAlloca() 112 bool InAllocaIndirect : 1;// isInAlloca() 113 bool IndirectByVal : 1; // isIndirect() 114 bool IndirectRealign : 1; // isIndirect() 115 bool SRetAfterThis : 1; // isIndirect() 116 bool InReg : 1; // isDirect() || isExtend() || isIndirect() 117 bool CanBeFlattened: 1; // isDirect() 118 bool SignExt : 1; // isExtend() 119 bool ZeroExt : 1; // isExtend() 120 121 bool canHavePaddingType() const { 122 return isDirect() || isExtend() || isIndirect() || isIndirectAliased() || 123 isExpand(); 124 } 125 void setPaddingType(llvm::Type *T) { 126 assert(canHavePaddingType()); 127 PaddingType = T; 128 } 129 130 void setUnpaddedCoerceToType(llvm::Type *T) { 131 assert(isCoerceAndExpand()); 132 UnpaddedCoerceAndExpandType = T; 133 } 134 135 public: 136 ABIArgInfo(Kind K = Direct) 137 : TypeData(nullptr), PaddingType(nullptr), DirectAttr{0, 0}, TheKind(K), 138 PaddingInReg(false), InAllocaSRet(false), 139 InAllocaIndirect(false), IndirectByVal(false), IndirectRealign(false), 140 SRetAfterThis(false), InReg(false), CanBeFlattened(false), 141 SignExt(false), ZeroExt(false) {} 142 143 static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0, 144 llvm::Type *Padding = nullptr, 145 bool CanBeFlattened = true, unsigned Align = 0) { 146 auto AI = ABIArgInfo(Direct); 147 AI.setCoerceToType(T); 148 AI.setPaddingType(Padding); 149 AI.setDirectOffset(Offset); 150 AI.setDirectAlign(Align); 151 AI.setCanBeFlattened(CanBeFlattened); 152 return AI; 153 } 154 static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) { 155 auto AI = getDirect(T); 156 AI.setInReg(true); 157 return AI; 158 } 159 160 static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T = nullptr) { 161 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType"); 162 auto AI = ABIArgInfo(Extend); 163 AI.setCoerceToType(T); 164 AI.setPaddingType(nullptr); 165 AI.setDirectOffset(0); 166 AI.setDirectAlign(0); 167 AI.setSignExt(true); 168 return AI; 169 } 170 171 static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T = nullptr) { 172 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType"); 173 auto AI = ABIArgInfo(Extend); 174 AI.setCoerceToType(T); 175 AI.setPaddingType(nullptr); 176 AI.setDirectOffset(0); 177 AI.setDirectAlign(0); 178 AI.setZeroExt(true); 179 return AI; 180 } 181 182 // ABIArgInfo will record the argument as being extended based on the sign 183 // of its type. Produces a sign or zero extension. 184 static ABIArgInfo getExtend(QualType Ty, llvm::Type *T = nullptr) { 185 assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType"); 186 if (Ty->hasSignedIntegerRepresentation()) 187 return getSignExtend(Ty, T); 188 return getZeroExtend(Ty, T); 189 } 190 191 // Struct in register marked explicitly as not needing extension. 192 static ABIArgInfo getNoExtend(llvm::IntegerType *T) { 193 auto AI = ABIArgInfo(Extend); 194 AI.setCoerceToType(T); 195 AI.setPaddingType(nullptr); 196 AI.setDirectOffset(0); 197 AI.setDirectAlign(0); 198 return AI; 199 } 200 201 static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T = nullptr) { 202 auto AI = getExtend(Ty, T); 203 AI.setInReg(true); 204 return AI; 205 } 206 static ABIArgInfo getIgnore() { 207 return ABIArgInfo(Ignore); 208 } 209 static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true, 210 bool Realign = false, 211 llvm::Type *Padding = nullptr) { 212 auto AI = ABIArgInfo(Indirect); 213 AI.setIndirectAlign(Alignment); 214 AI.setIndirectByVal(ByVal); 215 AI.setIndirectRealign(Realign); 216 AI.setSRetAfterThis(false); 217 AI.setPaddingType(Padding); 218 return AI; 219 } 220 221 /// Pass this in memory using the IR byref attribute. 222 static ABIArgInfo getIndirectAliased(CharUnits Alignment, unsigned AddrSpace, 223 bool Realign = false, 224 llvm::Type *Padding = nullptr) { 225 auto AI = ABIArgInfo(IndirectAliased); 226 AI.setIndirectAlign(Alignment); 227 AI.setIndirectRealign(Realign); 228 AI.setPaddingType(Padding); 229 AI.setIndirectAddrSpace(AddrSpace); 230 return AI; 231 } 232 233 static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true, 234 bool Realign = false) { 235 auto AI = getIndirect(Alignment, ByVal, Realign); 236 AI.setInReg(true); 237 return AI; 238 } 239 static ABIArgInfo getInAlloca(unsigned FieldIndex, bool Indirect = false) { 240 auto AI = ABIArgInfo(InAlloca); 241 AI.setInAllocaFieldIndex(FieldIndex); 242 AI.setInAllocaIndirect(Indirect); 243 return AI; 244 } 245 static ABIArgInfo getExpand() { 246 auto AI = ABIArgInfo(Expand); 247 AI.setPaddingType(nullptr); 248 return AI; 249 } 250 static ABIArgInfo getExpandWithPadding(bool PaddingInReg, 251 llvm::Type *Padding) { 252 auto AI = getExpand(); 253 AI.setPaddingInReg(PaddingInReg); 254 AI.setPaddingType(Padding); 255 return AI; 256 } 257 258 /// \param unpaddedCoerceToType The coerce-to type with padding elements 259 /// removed, canonicalized to a single element if it would otherwise 260 /// have exactly one element. 261 static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, 262 llvm::Type *unpaddedCoerceToType) { 263 #ifndef NDEBUG 264 // Check that unpaddedCoerceToType has roughly the right shape. 265 266 // Assert that we only have a struct type if there are multiple elements. 267 auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType); 268 assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1); 269 270 // Assert that all the non-padding elements have a corresponding element 271 // in the unpadded type. 272 unsigned unpaddedIndex = 0; 273 for (auto eltType : coerceToType->elements()) { 274 if (isPaddingForCoerceAndExpand(eltType)) 275 continue; 276 unpaddedIndex++; 277 } 278 279 // Assert that there aren't extra elements in the unpadded type. 280 if (unpaddedStruct) { 281 assert(unpaddedStruct->getNumElements() == unpaddedIndex); 282 } else { 283 assert(unpaddedIndex == 1); 284 } 285 #endif 286 287 auto AI = ABIArgInfo(CoerceAndExpand); 288 AI.setCoerceToType(coerceToType); 289 AI.setUnpaddedCoerceToType(unpaddedCoerceToType); 290 return AI; 291 } 292 293 static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) { 294 return eltType->isArrayTy() && 295 eltType->getArrayElementType()->isIntegerTy(8); 296 } 297 298 Kind getKind() const { return TheKind; } 299 bool isDirect() const { return TheKind == Direct; } 300 bool isInAlloca() const { return TheKind == InAlloca; } 301 bool isExtend() const { return TheKind == Extend; } 302 bool isIgnore() const { return TheKind == Ignore; } 303 bool isIndirect() const { return TheKind == Indirect; } 304 bool isIndirectAliased() const { return TheKind == IndirectAliased; } 305 bool isExpand() const { return TheKind == Expand; } 306 bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; } 307 308 bool canHaveCoerceToType() const { 309 return isDirect() || isExtend() || isCoerceAndExpand(); 310 } 311 312 // Direct/Extend accessors 313 unsigned getDirectOffset() const { 314 assert((isDirect() || isExtend()) && "Not a direct or extend kind"); 315 return DirectAttr.Offset; 316 } 317 void setDirectOffset(unsigned Offset) { 318 assert((isDirect() || isExtend()) && "Not a direct or extend kind"); 319 DirectAttr.Offset = Offset; 320 } 321 322 unsigned getDirectAlign() const { 323 assert((isDirect() || isExtend()) && "Not a direct or extend kind"); 324 return DirectAttr.Align; 325 } 326 void setDirectAlign(unsigned Align) { 327 assert((isDirect() || isExtend()) && "Not a direct or extend kind"); 328 DirectAttr.Align = Align; 329 } 330 331 bool isSignExt() const { 332 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!"); 333 return SignExt; 334 } 335 void setSignExt(bool SExt) { 336 assert(isExtend() && "Invalid kind!"); 337 SignExt = SExt; 338 } 339 340 bool isZeroExt() const { 341 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!"); 342 return ZeroExt; 343 } 344 void setZeroExt(bool ZExt) { 345 assert(isExtend() && "Invalid kind!"); 346 ZeroExt = ZExt; 347 } 348 349 bool isNoExt() const { 350 assert(isExtend() && (SignExt + ZeroExt <= 1) && "Invalid kind / flags!"); 351 return !SignExt && !ZeroExt; 352 } 353 354 llvm::Type *getPaddingType() const { 355 return (canHavePaddingType() ? PaddingType : nullptr); 356 } 357 358 bool getPaddingInReg() const { 359 return PaddingInReg; 360 } 361 void setPaddingInReg(bool PIR) { 362 PaddingInReg = PIR; 363 } 364 365 llvm::Type *getCoerceToType() const { 366 assert(canHaveCoerceToType() && "Invalid kind!"); 367 return TypeData; 368 } 369 370 void setCoerceToType(llvm::Type *T) { 371 assert(canHaveCoerceToType() && "Invalid kind!"); 372 TypeData = T; 373 } 374 375 llvm::StructType *getCoerceAndExpandType() const { 376 assert(isCoerceAndExpand()); 377 return cast<llvm::StructType>(TypeData); 378 } 379 380 llvm::Type *getUnpaddedCoerceAndExpandType() const { 381 assert(isCoerceAndExpand()); 382 return UnpaddedCoerceAndExpandType; 383 } 384 385 ArrayRef<llvm::Type *>getCoerceAndExpandTypeSequence() const { 386 assert(isCoerceAndExpand()); 387 if (auto structTy = 388 dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) { 389 return structTy->elements(); 390 } else { 391 return llvm::ArrayRef(&UnpaddedCoerceAndExpandType, 1); 392 } 393 } 394 395 bool getInReg() const { 396 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"); 397 return InReg; 398 } 399 400 void setInReg(bool IR) { 401 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"); 402 InReg = IR; 403 } 404 405 // Indirect accessors 406 CharUnits getIndirectAlign() const { 407 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!"); 408 return CharUnits::fromQuantity(IndirectAttr.Align); 409 } 410 void setIndirectAlign(CharUnits IA) { 411 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!"); 412 IndirectAttr.Align = IA.getQuantity(); 413 } 414 415 bool getIndirectByVal() const { 416 assert(isIndirect() && "Invalid kind!"); 417 return IndirectByVal; 418 } 419 void setIndirectByVal(bool IBV) { 420 assert(isIndirect() && "Invalid kind!"); 421 IndirectByVal = IBV; 422 } 423 424 unsigned getIndirectAddrSpace() const { 425 assert(isIndirectAliased() && "Invalid kind!"); 426 return IndirectAttr.AddrSpace; 427 } 428 429 void setIndirectAddrSpace(unsigned AddrSpace) { 430 assert(isIndirectAliased() && "Invalid kind!"); 431 IndirectAttr.AddrSpace = AddrSpace; 432 } 433 434 bool getIndirectRealign() const { 435 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!"); 436 return IndirectRealign; 437 } 438 void setIndirectRealign(bool IR) { 439 assert((isIndirect() || isIndirectAliased()) && "Invalid kind!"); 440 IndirectRealign = IR; 441 } 442 443 bool isSRetAfterThis() const { 444 assert(isIndirect() && "Invalid kind!"); 445 return SRetAfterThis; 446 } 447 void setSRetAfterThis(bool AfterThis) { 448 assert(isIndirect() && "Invalid kind!"); 449 SRetAfterThis = AfterThis; 450 } 451 452 unsigned getInAllocaFieldIndex() const { 453 assert(isInAlloca() && "Invalid kind!"); 454 return AllocaFieldIndex; 455 } 456 void setInAllocaFieldIndex(unsigned FieldIndex) { 457 assert(isInAlloca() && "Invalid kind!"); 458 AllocaFieldIndex = FieldIndex; 459 } 460 461 unsigned getInAllocaIndirect() const { 462 assert(isInAlloca() && "Invalid kind!"); 463 return InAllocaIndirect; 464 } 465 void setInAllocaIndirect(bool Indirect) { 466 assert(isInAlloca() && "Invalid kind!"); 467 InAllocaIndirect = Indirect; 468 } 469 470 /// Return true if this field of an inalloca struct should be returned 471 /// to implement a struct return calling convention. 472 bool getInAllocaSRet() const { 473 assert(isInAlloca() && "Invalid kind!"); 474 return InAllocaSRet; 475 } 476 477 void setInAllocaSRet(bool SRet) { 478 assert(isInAlloca() && "Invalid kind!"); 479 InAllocaSRet = SRet; 480 } 481 482 bool getCanBeFlattened() const { 483 assert(isDirect() && "Invalid kind!"); 484 return CanBeFlattened; 485 } 486 487 void setCanBeFlattened(bool Flatten) { 488 assert(isDirect() && "Invalid kind!"); 489 CanBeFlattened = Flatten; 490 } 491 492 void dump() const; 493 }; 494 495 /// A class for recording the number of arguments that a function 496 /// signature requires. 497 class RequiredArgs { 498 /// The number of required arguments, or ~0 if the signature does 499 /// not permit optional arguments. 500 unsigned NumRequired; 501 public: 502 enum All_t { All }; 503 504 RequiredArgs(All_t _) : NumRequired(~0U) {} 505 explicit RequiredArgs(unsigned n) : NumRequired(n) { 506 assert(n != ~0U); 507 } 508 509 /// Compute the arguments required by the given formal prototype, 510 /// given that there may be some additional, non-formal arguments 511 /// in play. 512 /// 513 /// If FD is not null, this will consider pass_object_size params in FD. 514 static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, 515 unsigned additional) { 516 if (!prototype->isVariadic()) return All; 517 518 if (prototype->hasExtParameterInfos()) 519 additional += llvm::count_if( 520 prototype->getExtParameterInfos(), 521 [](const FunctionProtoType::ExtParameterInfo &ExtInfo) { 522 return ExtInfo.hasPassObjectSize(); 523 }); 524 525 return RequiredArgs(prototype->getNumParams() + additional); 526 } 527 528 static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype, 529 unsigned additional) { 530 return forPrototypePlus(prototype.getTypePtr(), additional); 531 } 532 533 static RequiredArgs forPrototype(const FunctionProtoType *prototype) { 534 return forPrototypePlus(prototype, 0); 535 } 536 537 static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) { 538 return forPrototypePlus(prototype.getTypePtr(), 0); 539 } 540 541 bool allowsOptionalArgs() const { return NumRequired != ~0U; } 542 unsigned getNumRequiredArgs() const { 543 assert(allowsOptionalArgs()); 544 return NumRequired; 545 } 546 547 /// Return true if the argument at a given index is required. 548 bool isRequiredArg(unsigned argIdx) const { 549 return argIdx == ~0U || argIdx < NumRequired; 550 } 551 552 unsigned getOpaqueData() const { return NumRequired; } 553 static RequiredArgs getFromOpaqueData(unsigned value) { 554 if (value == ~0U) return All; 555 return RequiredArgs(value); 556 } 557 }; 558 559 // Implementation detail of CGFunctionInfo, factored out so it can be named 560 // in the TrailingObjects base class of CGFunctionInfo. 561 struct CGFunctionInfoArgInfo { 562 CanQualType type; 563 ABIArgInfo info; 564 }; 565 566 /// CGFunctionInfo - Class to encapsulate the information about a 567 /// function definition. 568 class CGFunctionInfo final 569 : public llvm::FoldingSetNode, 570 private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo, 571 FunctionProtoType::ExtParameterInfo> { 572 typedef CGFunctionInfoArgInfo ArgInfo; 573 typedef FunctionProtoType::ExtParameterInfo ExtParameterInfo; 574 575 /// The LLVM::CallingConv to use for this function (as specified by the 576 /// user). 577 unsigned CallingConvention : 8; 578 579 /// The LLVM::CallingConv to actually use for this function, which may 580 /// depend on the ABI. 581 unsigned EffectiveCallingConvention : 8; 582 583 /// The clang::CallingConv that this was originally created with. 584 LLVM_PREFERRED_TYPE(CallingConv) 585 unsigned ASTCallingConvention : 6; 586 587 /// Whether this is an instance method. 588 LLVM_PREFERRED_TYPE(bool) 589 unsigned InstanceMethod : 1; 590 591 /// Whether this is a chain call. 592 LLVM_PREFERRED_TYPE(bool) 593 unsigned ChainCall : 1; 594 595 /// Whether this function is called by forwarding arguments. 596 /// This doesn't support inalloca or varargs. 597 LLVM_PREFERRED_TYPE(bool) 598 unsigned DelegateCall : 1; 599 600 /// Whether this function is a CMSE nonsecure call 601 LLVM_PREFERRED_TYPE(bool) 602 unsigned CmseNSCall : 1; 603 604 /// Whether this function is noreturn. 605 LLVM_PREFERRED_TYPE(bool) 606 unsigned NoReturn : 1; 607 608 /// Whether this function is returns-retained. 609 LLVM_PREFERRED_TYPE(bool) 610 unsigned ReturnsRetained : 1; 611 612 /// Whether this function saved caller registers. 613 LLVM_PREFERRED_TYPE(bool) 614 unsigned NoCallerSavedRegs : 1; 615 616 /// How many arguments to pass inreg. 617 LLVM_PREFERRED_TYPE(bool) 618 unsigned HasRegParm : 1; 619 unsigned RegParm : 3; 620 621 /// Whether this function has nocf_check attribute. 622 LLVM_PREFERRED_TYPE(bool) 623 unsigned NoCfCheck : 1; 624 625 /// Log 2 of the maximum vector width. 626 unsigned MaxVectorWidth : 4; 627 628 RequiredArgs Required; 629 630 /// The struct representing all arguments passed in memory. Only used when 631 /// passing non-trivial types with inalloca. Not part of the profile. 632 llvm::StructType *ArgStruct; 633 unsigned ArgStructAlign : 31; 634 LLVM_PREFERRED_TYPE(bool) 635 unsigned HasExtParameterInfos : 1; 636 637 unsigned NumArgs; 638 639 ArgInfo *getArgsBuffer() { 640 return getTrailingObjects<ArgInfo>(); 641 } 642 const ArgInfo *getArgsBuffer() const { 643 return getTrailingObjects<ArgInfo>(); 644 } 645 646 ExtParameterInfo *getExtParameterInfosBuffer() { 647 return getTrailingObjects<ExtParameterInfo>(); 648 } 649 const ExtParameterInfo *getExtParameterInfosBuffer() const{ 650 return getTrailingObjects<ExtParameterInfo>(); 651 } 652 653 CGFunctionInfo() : Required(RequiredArgs::All) {} 654 655 public: 656 static CGFunctionInfo * 657 create(unsigned llvmCC, bool instanceMethod, bool chainCall, 658 bool delegateCall, const FunctionType::ExtInfo &extInfo, 659 ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType, 660 ArrayRef<CanQualType> argTypes, RequiredArgs required); 661 void operator delete(void *p) { ::operator delete(p); } 662 663 // Friending class TrailingObjects is apparently not good enough for MSVC, 664 // so these have to be public. 665 friend class TrailingObjects; 666 size_t numTrailingObjects(OverloadToken<ArgInfo>) const { 667 return NumArgs + 1; 668 } 669 size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const { 670 return (HasExtParameterInfos ? NumArgs : 0); 671 } 672 673 typedef const ArgInfo *const_arg_iterator; 674 typedef ArgInfo *arg_iterator; 675 676 MutableArrayRef<ArgInfo> arguments() { 677 return MutableArrayRef<ArgInfo>(arg_begin(), NumArgs); 678 } 679 ArrayRef<ArgInfo> arguments() const { 680 return ArrayRef<ArgInfo>(arg_begin(), NumArgs); 681 } 682 683 const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; } 684 const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; } 685 arg_iterator arg_begin() { return getArgsBuffer() + 1; } 686 arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; } 687 688 unsigned arg_size() const { return NumArgs; } 689 690 bool isVariadic() const { return Required.allowsOptionalArgs(); } 691 RequiredArgs getRequiredArgs() const { return Required; } 692 unsigned getNumRequiredArgs() const { 693 return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size(); 694 } 695 696 bool isInstanceMethod() const { return InstanceMethod; } 697 698 bool isChainCall() const { return ChainCall; } 699 700 bool isDelegateCall() const { return DelegateCall; } 701 702 bool isCmseNSCall() const { return CmseNSCall; } 703 704 bool isNoReturn() const { return NoReturn; } 705 706 /// In ARC, whether this function retains its return value. This 707 /// is not always reliable for call sites. 708 bool isReturnsRetained() const { return ReturnsRetained; } 709 710 /// Whether this function no longer saves caller registers. 711 bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; } 712 713 /// Whether this function has nocf_check attribute. 714 bool isNoCfCheck() const { return NoCfCheck; } 715 716 /// getASTCallingConvention() - Return the AST-specified calling 717 /// convention. 718 CallingConv getASTCallingConvention() const { 719 return CallingConv(ASTCallingConvention); 720 } 721 722 /// getCallingConvention - Return the user specified calling 723 /// convention, which has been translated into an LLVM CC. 724 unsigned getCallingConvention() const { return CallingConvention; } 725 726 /// getEffectiveCallingConvention - Return the actual calling convention to 727 /// use, which may depend on the ABI. 728 unsigned getEffectiveCallingConvention() const { 729 return EffectiveCallingConvention; 730 } 731 void setEffectiveCallingConvention(unsigned Value) { 732 EffectiveCallingConvention = Value; 733 } 734 735 bool getHasRegParm() const { return HasRegParm; } 736 unsigned getRegParm() const { return RegParm; } 737 738 FunctionType::ExtInfo getExtInfo() const { 739 return FunctionType::ExtInfo(isNoReturn(), getHasRegParm(), getRegParm(), 740 getASTCallingConvention(), isReturnsRetained(), 741 isNoCallerSavedRegs(), isNoCfCheck(), 742 isCmseNSCall()); 743 } 744 745 CanQualType getReturnType() const { return getArgsBuffer()[0].type; } 746 747 ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; } 748 const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; } 749 750 ArrayRef<ExtParameterInfo> getExtParameterInfos() const { 751 if (!HasExtParameterInfos) return {}; 752 return llvm::ArrayRef(getExtParameterInfosBuffer(), NumArgs); 753 } 754 ExtParameterInfo getExtParameterInfo(unsigned argIndex) const { 755 assert(argIndex <= NumArgs); 756 if (!HasExtParameterInfos) return ExtParameterInfo(); 757 return getExtParameterInfos()[argIndex]; 758 } 759 760 /// Return true if this function uses inalloca arguments. 761 bool usesInAlloca() const { return ArgStruct; } 762 763 /// Get the struct type used to represent all the arguments in memory. 764 llvm::StructType *getArgStruct() const { return ArgStruct; } 765 CharUnits getArgStructAlignment() const { 766 return CharUnits::fromQuantity(ArgStructAlign); 767 } 768 void setArgStruct(llvm::StructType *Ty, CharUnits Align) { 769 ArgStruct = Ty; 770 ArgStructAlign = Align.getQuantity(); 771 } 772 773 /// Return the maximum vector width in the arguments. 774 unsigned getMaxVectorWidth() const { 775 return MaxVectorWidth ? 1U << (MaxVectorWidth - 1) : 0; 776 } 777 778 /// Set the maximum vector width in the arguments. 779 void setMaxVectorWidth(unsigned Width) { 780 assert(llvm::isPowerOf2_32(Width) && "Expected power of 2 vector"); 781 MaxVectorWidth = llvm::countr_zero(Width) + 1; 782 } 783 784 void Profile(llvm::FoldingSetNodeID &ID) { 785 ID.AddInteger(getASTCallingConvention()); 786 ID.AddBoolean(InstanceMethod); 787 ID.AddBoolean(ChainCall); 788 ID.AddBoolean(DelegateCall); 789 ID.AddBoolean(NoReturn); 790 ID.AddBoolean(ReturnsRetained); 791 ID.AddBoolean(NoCallerSavedRegs); 792 ID.AddBoolean(HasRegParm); 793 ID.AddInteger(RegParm); 794 ID.AddBoolean(NoCfCheck); 795 ID.AddBoolean(CmseNSCall); 796 ID.AddInteger(Required.getOpaqueData()); 797 ID.AddBoolean(HasExtParameterInfos); 798 if (HasExtParameterInfos) { 799 for (auto paramInfo : getExtParameterInfos()) 800 ID.AddInteger(paramInfo.getOpaqueValue()); 801 } 802 getReturnType().Profile(ID); 803 for (const auto &I : arguments()) 804 I.type.Profile(ID); 805 } 806 static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod, 807 bool ChainCall, bool IsDelegateCall, 808 const FunctionType::ExtInfo &info, 809 ArrayRef<ExtParameterInfo> paramInfos, 810 RequiredArgs required, CanQualType resultType, 811 ArrayRef<CanQualType> argTypes) { 812 ID.AddInteger(info.getCC()); 813 ID.AddBoolean(InstanceMethod); 814 ID.AddBoolean(ChainCall); 815 ID.AddBoolean(IsDelegateCall); 816 ID.AddBoolean(info.getNoReturn()); 817 ID.AddBoolean(info.getProducesResult()); 818 ID.AddBoolean(info.getNoCallerSavedRegs()); 819 ID.AddBoolean(info.getHasRegParm()); 820 ID.AddInteger(info.getRegParm()); 821 ID.AddBoolean(info.getNoCfCheck()); 822 ID.AddBoolean(info.getCmseNSCall()); 823 ID.AddInteger(required.getOpaqueData()); 824 ID.AddBoolean(!paramInfos.empty()); 825 if (!paramInfos.empty()) { 826 for (auto paramInfo : paramInfos) 827 ID.AddInteger(paramInfo.getOpaqueValue()); 828 } 829 resultType.Profile(ID); 830 for (ArrayRef<CanQualType>::iterator 831 i = argTypes.begin(), e = argTypes.end(); i != e; ++i) { 832 i->Profile(ID); 833 } 834 } 835 }; 836 837 } // end namespace CodeGen 838 } // end namespace clang 839 840 #endif 841