18b54999a831bb195c08541ca995ef0505c96193fMark Lacey//==-- CGFunctionInfo.h - Representation of function argument/return types -==//
28b54999a831bb195c08541ca995ef0505c96193fMark Lacey//
38b54999a831bb195c08541ca995ef0505c96193fMark Lacey//                     The LLVM Compiler Infrastructure
48b54999a831bb195c08541ca995ef0505c96193fMark Lacey//
58b54999a831bb195c08541ca995ef0505c96193fMark Lacey// This file is distributed under the University of Illinois Open Source
68b54999a831bb195c08541ca995ef0505c96193fMark Lacey// License. See LICENSE.TXT for details.
78b54999a831bb195c08541ca995ef0505c96193fMark Lacey//
88b54999a831bb195c08541ca995ef0505c96193fMark Lacey//===----------------------------------------------------------------------===//
98b54999a831bb195c08541ca995ef0505c96193fMark Lacey//
108b54999a831bb195c08541ca995ef0505c96193fMark Lacey// Defines CGFunctionInfo and associated types used in representing the
118b54999a831bb195c08541ca995ef0505c96193fMark Lacey// LLVM source types and ABI-coerced types for function arguments and
128b54999a831bb195c08541ca995ef0505c96193fMark Lacey// return values.
138b54999a831bb195c08541ca995ef0505c96193fMark Lacey//
148b54999a831bb195c08541ca995ef0505c96193fMark Lacey//===----------------------------------------------------------------------===//
158b54999a831bb195c08541ca995ef0505c96193fMark Lacey
16176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
17176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
188b54999a831bb195c08541ca995ef0505c96193fMark Lacey
194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/Attr.h"
208b54999a831bb195c08541ca995ef0505c96193fMark Lacey#include "clang/AST/CanonicalType.h"
2187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#include "clang/AST/CharUnits.h"
224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/Decl.h"
238b54999a831bb195c08541ca995ef0505c96193fMark Lacey#include "clang/AST/Type.h"
244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/IR/DerivedTypes.h"
258b54999a831bb195c08541ca995ef0505c96193fMark Lacey#include "llvm/ADT/FoldingSet.h"
264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/Support/TrailingObjects.h"
278b54999a831bb195c08541ca995ef0505c96193fMark Lacey#include <cassert>
288b54999a831bb195c08541ca995ef0505c96193fMark Lacey
298b54999a831bb195c08541ca995ef0505c96193fMark Laceynamespace clang {
308b54999a831bb195c08541ca995ef0505c96193fMark Laceynamespace CodeGen {
318b54999a831bb195c08541ca995ef0505c96193fMark Lacey
328b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// ABIArgInfo - Helper class to encapsulate information about how a
338b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// specific C type should be passed to or returned from a function.
348b54999a831bb195c08541ca995ef0505c96193fMark Laceyclass ABIArgInfo {
358b54999a831bb195c08541ca995ef0505c96193fMark Laceypublic:
366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  enum Kind : uint8_t {
378b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// Direct - Pass the argument directly using the normal converted LLVM
388b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// type, or by coercing to another specified type stored in
398b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// 'CoerceToType').  If an offset is specified (in UIntData), then the
408b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// argument passed is offset by some number of bytes in the memory
418b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// representation. A dummy argument is emitted before the real argument
428b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// if the specified type stored in "PaddingType" is not zero.
438b54999a831bb195c08541ca995ef0505c96193fMark Lacey    Direct,
448b54999a831bb195c08541ca995ef0505c96193fMark Lacey
458b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// Extend - Valid only for integer argument types. Same as 'direct'
468b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// but also emit a zero/sign extension attribute.
478b54999a831bb195c08541ca995ef0505c96193fMark Lacey    Extend,
488b54999a831bb195c08541ca995ef0505c96193fMark Lacey
498b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// Indirect - Pass the argument indirectly via a hidden pointer
508b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// with the specified alignment (0 indicates default alignment).
518b54999a831bb195c08541ca995ef0505c96193fMark Lacey    Indirect,
528b54999a831bb195c08541ca995ef0505c96193fMark Lacey
538b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// Ignore - Ignore the argument (treat as void). Useful for void and
548b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// empty structs.
558b54999a831bb195c08541ca995ef0505c96193fMark Lacey    Ignore,
568b54999a831bb195c08541ca995ef0505c96193fMark Lacey
578b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// Expand - Only valid for aggregate argument types. The structure should
588b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// be expanded into consecutive arguments for its constituent fields.
598b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// Currently expand is only allowed on structures whose fields
608b54999a831bb195c08541ca995ef0505c96193fMark Lacey    /// are all scalar types or are themselves expandable types.
618b54999a831bb195c08541ca995ef0505c96193fMark Lacey    Expand,
628b54999a831bb195c08541ca995ef0505c96193fMark Lacey
634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// CoerceAndExpand - Only valid for aggregate argument types. The
644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// structure should be expanded into consecutive arguments corresponding
654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// to the non-array elements of the type stored in CoerceToType.
664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    /// Array elements in the type are assumed to be padding and skipped.
674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    CoerceAndExpand,
684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// InAlloca - Pass the argument directly using the LLVM inalloca attribute.
700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    /// This is similar to indirect with byval, except it only applies to
710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    /// arguments stored in memory and forbids any implicit copies.  When
720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    /// applied to a return type, it means the value is returned indirectly via
730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    /// an implicit sret parameter stored in the argument struct.
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    InAlloca,
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    KindFirst = Direct,
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    KindLast = InAlloca
778b54999a831bb195c08541ca995ef0505c96193fMark Lacey  };
788b54999a831bb195c08541ca995ef0505c96193fMark Lacey
798b54999a831bb195c08541ca995ef0505c96193fMark Laceyprivate:
804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Type *TypeData; // canHaveCoerceToType()
814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  union {
824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *PaddingType; // canHavePaddingType()
834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm::Type *UnpaddedCoerceAndExpandType; // isCoerceAndExpand()
844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  };
856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  union {
866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    unsigned DirectOffset;     // isDirect() || isExtend()
876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    unsigned IndirectAlign;    // isIndirect()
886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    unsigned AllocaFieldIndex; // isInAlloca()
896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  };
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Kind TheKind;
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool PaddingInReg : 1;
926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool InAllocaSRet : 1;    // isInAlloca()
936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool IndirectByVal : 1;   // isIndirect()
946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool IndirectRealign : 1; // isIndirect()
956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool SRetAfterThis : 1;   // isIndirect()
966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool InReg : 1;           // isDirect() || isExtend() || isIndirect()
97176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  bool CanBeFlattened: 1;   // isDirect()
988b54999a831bb195c08541ca995ef0505c96193fMark Lacey
994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool canHavePaddingType() const {
1004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return isDirect() || isExtend() || isIndirect() || isExpand();
1014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
1024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void setPaddingType(llvm::Type *T) {
1034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(canHavePaddingType());
1044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    PaddingType = T;
1054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
1064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void setUnpaddedCoerceToType(llvm::Type *T) {
1084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(isCoerceAndExpand());
1094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    UnpaddedCoerceAndExpandType = T;
1104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
1114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ABIArgInfo(Kind K)
1134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      : TheKind(K), PaddingInReg(false), InReg(false) {
1144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
1158b54999a831bb195c08541ca995ef0505c96193fMark Lacey
1168b54999a831bb195c08541ca995ef0505c96193fMark Laceypublic:
1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ABIArgInfo()
1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        TheKind(Direct), PaddingInReg(false), InReg(false) {}
1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
122176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                              llvm::Type *Padding = nullptr,
123176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                              bool CanBeFlattened = true) {
1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    auto AI = ABIArgInfo(Direct);
1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setCoerceToType(T);
1266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setPaddingType(Padding);
1274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    AI.setDirectOffset(Offset);
128176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    AI.setCanBeFlattened(CanBeFlattened);
1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return AI;
1308b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    auto AI = getDirect(T);
1336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setInReg(true);
1346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return AI;
1358b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
1366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  static ABIArgInfo getExtend(llvm::Type *T = nullptr) {
1376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    auto AI = ABIArgInfo(Extend);
1386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setCoerceToType(T);
1394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    AI.setPaddingType(nullptr);
1406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setDirectOffset(0);
1416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return AI;
1428b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
1436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  static ABIArgInfo getExtendInReg(llvm::Type *T = nullptr) {
1446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    auto AI = getExtend(T);
1456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setInReg(true);
1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return AI;
1478b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
1488b54999a831bb195c08541ca995ef0505c96193fMark Lacey  static ABIArgInfo getIgnore() {
1496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return ABIArgInfo(Ignore);
1508b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
15187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true,
1526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                bool Realign = false,
1536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                llvm::Type *Padding = nullptr) {
1546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    auto AI = ABIArgInfo(Indirect);
1556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setIndirectAlign(Alignment);
1566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setIndirectByVal(ByVal);
1576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setIndirectRealign(Realign);
1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setSRetAfterThis(false);
1596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setPaddingType(Padding);
1606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return AI;
1618b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
16287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true,
1636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                     bool Realign = false) {
1646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    auto AI = getIndirect(Alignment, ByVal, Realign);
1656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setInReg(true);
1666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return AI;
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  static ABIArgInfo getInAlloca(unsigned FieldIndex) {
1696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    auto AI = ABIArgInfo(InAlloca);
1706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setInAllocaFieldIndex(FieldIndex);
1716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return AI;
1728b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
1738b54999a831bb195c08541ca995ef0505c96193fMark Lacey  static ABIArgInfo getExpand() {
1744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto AI = ABIArgInfo(Expand);
1754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    AI.setPaddingType(nullptr);
1764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return AI;
1778b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
1788b54999a831bb195c08541ca995ef0505c96193fMark Lacey  static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
1798b54999a831bb195c08541ca995ef0505c96193fMark Lacey                                         llvm::Type *Padding) {
1806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    auto AI = getExpand();
1816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setPaddingInReg(PaddingInReg);
1826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AI.setPaddingType(Padding);
1836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return AI;
1848b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
1858b54999a831bb195c08541ca995ef0505c96193fMark Lacey
1864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// \param unpaddedCoerceToType The coerce-to type with padding elements
1874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ///   removed, canonicalized to a single element if it would otherwise
1884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ///   have exactly one element.
1894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType,
1904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       llvm::Type *unpaddedCoerceToType) {
1914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#ifndef NDEBUG
1924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Sanity checks on unpaddedCoerceToType.
1934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Assert that we only have a struct type if there are multiple elements.
1954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType);
1964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1);
1974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Assert that all the non-padding elements have a corresponding element
1994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // in the unpadded type.
2004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned unpaddedIndex = 0;
2014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto eltType : coerceToType->elements()) {
2024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (isPaddingForCoerceAndExpand(eltType)) continue;
2034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (unpaddedStruct) {
2044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        assert(unpaddedStruct->getElementType(unpaddedIndex) == eltType);
2054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      } else {
2064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        assert(unpaddedIndex == 0 && unpaddedCoerceToType == eltType);
2074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
2084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      unpaddedIndex++;
2094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
2104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    // Assert that there aren't extra elements in the unpadded type.
2124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (unpaddedStruct) {
2134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      assert(unpaddedStruct->getNumElements() == unpaddedIndex);
2144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    } else {
2154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      assert(unpaddedIndex == 1);
2164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
2174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#endif
2184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto AI = ABIArgInfo(CoerceAndExpand);
2204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    AI.setCoerceToType(coerceToType);
2214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    AI.setUnpaddedCoerceToType(unpaddedCoerceToType);
2224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return AI;
2234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) {
2264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (eltType->isArrayTy()) {
2274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      assert(eltType->getArrayElementType()->isIntegerTy(8));
2284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return true;
2294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    } else {
2304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return false;
2314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
2324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2348b54999a831bb195c08541ca995ef0505c96193fMark Lacey  Kind getKind() const { return TheKind; }
2358b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool isDirect() const { return TheKind == Direct; }
236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool isInAlloca() const { return TheKind == InAlloca; }
2378b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool isExtend() const { return TheKind == Extend; }
2388b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool isIgnore() const { return TheKind == Ignore; }
2398b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool isIndirect() const { return TheKind == Indirect; }
2408b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool isExpand() const { return TheKind == Expand; }
2414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; }
2428b54999a831bb195c08541ca995ef0505c96193fMark Lacey
2434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool canHaveCoerceToType() const {
2444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return isDirect() || isExtend() || isCoerceAndExpand();
2454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2468b54999a831bb195c08541ca995ef0505c96193fMark Lacey
2478b54999a831bb195c08541ca995ef0505c96193fMark Lacey  // Direct/Extend accessors
2488b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned getDirectOffset() const {
2498b54999a831bb195c08541ca995ef0505c96193fMark Lacey    assert((isDirect() || isExtend()) && "Not a direct or extend kind");
2506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return DirectOffset;
2518b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
2526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void setDirectOffset(unsigned Offset) {
2536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert((isDirect() || isExtend()) && "Not a direct or extend kind");
2546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DirectOffset = Offset;
2558b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
2568b54999a831bb195c08541ca995ef0505c96193fMark Lacey
2574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Type *getPaddingType() const {
2584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return (canHavePaddingType() ? PaddingType : nullptr);
2594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
2618b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool getPaddingInReg() const {
2628b54999a831bb195c08541ca995ef0505c96193fMark Lacey    return PaddingInReg;
2638b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
2646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void setPaddingInReg(bool PIR) {
2656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    PaddingInReg = PIR;
2666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
2678b54999a831bb195c08541ca995ef0505c96193fMark Lacey
2688b54999a831bb195c08541ca995ef0505c96193fMark Lacey  llvm::Type *getCoerceToType() const {
2698b54999a831bb195c08541ca995ef0505c96193fMark Lacey    assert(canHaveCoerceToType() && "Invalid kind!");
2708b54999a831bb195c08541ca995ef0505c96193fMark Lacey    return TypeData;
2718b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
2728b54999a831bb195c08541ca995ef0505c96193fMark Lacey
2738b54999a831bb195c08541ca995ef0505c96193fMark Lacey  void setCoerceToType(llvm::Type *T) {
2748b54999a831bb195c08541ca995ef0505c96193fMark Lacey    assert(canHaveCoerceToType() && "Invalid kind!");
2758b54999a831bb195c08541ca995ef0505c96193fMark Lacey    TypeData = T;
2768b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
2778b54999a831bb195c08541ca995ef0505c96193fMark Lacey
2784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::StructType *getCoerceAndExpandType() const {
2794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(isCoerceAndExpand());
2804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return cast<llvm::StructType>(TypeData);
2814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  llvm::Type *getUnpaddedCoerceAndExpandType() const {
2844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(isCoerceAndExpand());
2854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return UnpaddedCoerceAndExpandType;
2864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ArrayRef<llvm::Type *>getCoerceAndExpandTypeSequence() const {
2894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(isCoerceAndExpand());
2904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (auto structTy =
2914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) {
2924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return structTy->elements();
2934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    } else {
2944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return llvm::makeArrayRef(&UnpaddedCoerceAndExpandType, 1);
2954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
2964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2988b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool getInReg() const {
2998b54999a831bb195c08541ca995ef0505c96193fMark Lacey    assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
3008b54999a831bb195c08541ca995ef0505c96193fMark Lacey    return InReg;
3018b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
3028b54999a831bb195c08541ca995ef0505c96193fMark Lacey
3036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void setInReg(bool IR) {
3046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
3056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    InReg = IR;
3066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
3076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
3088b54999a831bb195c08541ca995ef0505c96193fMark Lacey  // Indirect accessors
30987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CharUnits getIndirectAlign() const {
3106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isIndirect() && "Invalid kind!");
31187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return CharUnits::fromQuantity(IndirectAlign);
3126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
31387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  void setIndirectAlign(CharUnits IA) {
3146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isIndirect() && "Invalid kind!");
31587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    IndirectAlign = IA.getQuantity();
3168b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
3178b54999a831bb195c08541ca995ef0505c96193fMark Lacey
3188b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool getIndirectByVal() const {
3196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isIndirect() && "Invalid kind!");
3206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return IndirectByVal;
3216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
32287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  void setIndirectByVal(bool IBV) {
3236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isIndirect() && "Invalid kind!");
3246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    IndirectByVal = IBV;
3258b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
3268b54999a831bb195c08541ca995ef0505c96193fMark Lacey
3278b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool getIndirectRealign() const {
3286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isIndirect() && "Invalid kind!");
3296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return IndirectRealign;
3306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
3316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void setIndirectRealign(bool IR) {
3326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isIndirect() && "Invalid kind!");
3336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    IndirectRealign = IR;
3346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
3356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
3366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool isSRetAfterThis() const {
3376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isIndirect() && "Invalid kind!");
3386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return SRetAfterThis;
3396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
3406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void setSRetAfterThis(bool AfterThis) {
3416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isIndirect() && "Invalid kind!");
3426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    SRetAfterThis = AfterThis;
3438b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
3448b54999a831bb195c08541ca995ef0505c96193fMark Lacey
345651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned getInAllocaFieldIndex() const {
3466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isInAlloca() && "Invalid kind!");
3476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return AllocaFieldIndex;
3486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
3496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void setInAllocaFieldIndex(unsigned FieldIndex) {
3506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isInAlloca() && "Invalid kind!");
3516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    AllocaFieldIndex = FieldIndex;
352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Return true if this field of an inalloca struct should be returned
355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// to implement a struct return calling convention.
356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool getInAllocaSRet() const {
3576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isInAlloca() && "Invalid kind!");
3586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return InAllocaSRet;
359651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
361651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void setInAllocaSRet(bool SRet) {
3626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isInAlloca() && "Invalid kind!");
3636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    InAllocaSRet = SRet;
364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
366176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  bool getCanBeFlattened() const {
367176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    assert(isDirect() && "Invalid kind!");
368176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return CanBeFlattened;
369176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
370176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
371176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void setCanBeFlattened(bool Flatten) {
372176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    assert(isDirect() && "Invalid kind!");
373176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    CanBeFlattened = Flatten;
374176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
375176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
3768b54999a831bb195c08541ca995ef0505c96193fMark Lacey  void dump() const;
3778b54999a831bb195c08541ca995ef0505c96193fMark Lacey};
3788b54999a831bb195c08541ca995ef0505c96193fMark Lacey
3798b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// A class for recording the number of arguments that a function
3808b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// signature requires.
3818b54999a831bb195c08541ca995ef0505c96193fMark Laceyclass RequiredArgs {
3828b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// The number of required arguments, or ~0 if the signature does
3838b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// not permit optional arguments.
3848b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned NumRequired;
3858b54999a831bb195c08541ca995ef0505c96193fMark Laceypublic:
3868b54999a831bb195c08541ca995ef0505c96193fMark Lacey  enum All_t { All };
3878b54999a831bb195c08541ca995ef0505c96193fMark Lacey
3888b54999a831bb195c08541ca995ef0505c96193fMark Lacey  RequiredArgs(All_t _) : NumRequired(~0U) {}
3898b54999a831bb195c08541ca995ef0505c96193fMark Lacey  explicit RequiredArgs(unsigned n) : NumRequired(n) {
3908b54999a831bb195c08541ca995ef0505c96193fMark Lacey    assert(n != ~0U);
3918b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
3928b54999a831bb195c08541ca995ef0505c96193fMark Lacey
3938b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// Compute the arguments required by the given formal prototype,
3948b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// given that there may be some additional, non-formal arguments
3958b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// in play.
3964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ///
3974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  /// If FD is not null, this will consider pass_object_size params in FD.
3988b54999a831bb195c08541ca995ef0505c96193fMark Lacey  static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
3994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       unsigned additional,
4004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       const FunctionDecl *FD) {
4018b54999a831bb195c08541ca995ef0505c96193fMark Lacey    if (!prototype->isVariadic()) return All;
4024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (FD)
4034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      additional +=
4044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          llvm::count_if(FD->parameters(), [](const ParmVarDecl *PVD) {
4054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar            return PVD->hasAttr<PassObjectSizeAttr>();
4064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          });
407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return RequiredArgs(prototype->getNumParams() + additional);
4088b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
4098b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static RequiredArgs forPrototype(const FunctionProtoType *prototype,
4114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   const FunctionDecl *FD) {
4124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return forPrototypePlus(prototype, 0, FD);
4138b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
4148b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype,
4164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   const FunctionDecl *FD) {
4174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return forPrototype(prototype.getTypePtr(), FD);
4188b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
4198b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4208b54999a831bb195c08541ca995ef0505c96193fMark Lacey  static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
4214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       unsigned additional,
4224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                       const FunctionDecl *FD) {
4234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return forPrototypePlus(prototype.getTypePtr(), additional, FD);
4248b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
4258b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4268b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool allowsOptionalArgs() const { return NumRequired != ~0U; }
4278b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned getNumRequiredArgs() const {
4288b54999a831bb195c08541ca995ef0505c96193fMark Lacey    assert(allowsOptionalArgs());
4298b54999a831bb195c08541ca995ef0505c96193fMark Lacey    return NumRequired;
4308b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
4318b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4328b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned getOpaqueData() const { return NumRequired; }
4338b54999a831bb195c08541ca995ef0505c96193fMark Lacey  static RequiredArgs getFromOpaqueData(unsigned value) {
4348b54999a831bb195c08541ca995ef0505c96193fMark Lacey    if (value == ~0U) return All;
4358b54999a831bb195c08541ca995ef0505c96193fMark Lacey    return RequiredArgs(value);
4368b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
4378b54999a831bb195c08541ca995ef0505c96193fMark Lacey};
4388b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// Implementation detail of CGFunctionInfo, factored out so it can be named
4404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// in the TrailingObjects base class of CGFunctionInfo.
4414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstruct CGFunctionInfoArgInfo {
4424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  CanQualType type;
4434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ABIArgInfo info;
4444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
4454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
4468b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// CGFunctionInfo - Class to encapsulate the information about a
4478b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// function definition.
4484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass CGFunctionInfo final
4494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    : public llvm::FoldingSetNode,
4504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo,
4514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    FunctionProtoType::ExtParameterInfo> {
4524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  typedef CGFunctionInfoArgInfo ArgInfo;
4534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  typedef FunctionProtoType::ExtParameterInfo ExtParameterInfo;
4548b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4558b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// The LLVM::CallingConv to use for this function (as specified by the
4568b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// user).
4578b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned CallingConvention : 8;
4588b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4598b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// The LLVM::CallingConv to actually use for this function, which may
4608b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// depend on the ABI.
4618b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned EffectiveCallingConvention : 8;
4628b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4638b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// The clang::CallingConv that this was originally created with.
4648b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned ASTCallingConvention : 8;
4658b54999a831bb195c08541ca995ef0505c96193fMark Lacey
466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Whether this is an instance method.
467651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned InstanceMethod : 1;
468651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  /// Whether this is a chain call.
4700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  unsigned ChainCall : 1;
4710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
4728b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// Whether this function is noreturn.
4738b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned NoReturn : 1;
4748b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4758b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// Whether this function is returns-retained.
4768b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned ReturnsRetained : 1;
4778b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4788b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// How many arguments to pass inreg.
4798b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned HasRegParm : 1;
4800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  unsigned RegParm : 3;
4818b54999a831bb195c08541ca995ef0505c96193fMark Lacey
4828b54999a831bb195c08541ca995ef0505c96193fMark Lacey  RequiredArgs Required;
4838b54999a831bb195c08541ca995ef0505c96193fMark Lacey
484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// The struct representing all arguments passed in memory.  Only used when
485651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// passing non-trivial types with inalloca.  Not part of the profile.
486651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::StructType *ArgStruct;
4874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned ArgStructAlign : 31;
4884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned HasExtParameterInfos : 1;
489651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4908b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned NumArgs;
4914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
4928b54999a831bb195c08541ca995ef0505c96193fMark Lacey  ArgInfo *getArgsBuffer() {
4934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return getTrailingObjects<ArgInfo>();
4948b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
4958b54999a831bb195c08541ca995ef0505c96193fMark Lacey  const ArgInfo *getArgsBuffer() const {
4964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return getTrailingObjects<ArgInfo>();
4974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
4984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
4994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ExtParameterInfo *getExtParameterInfosBuffer() {
5004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return getTrailingObjects<ExtParameterInfo>();
5014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
5024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const ExtParameterInfo *getExtParameterInfosBuffer() const{
5034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return getTrailingObjects<ExtParameterInfo>();
5048b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
5058b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5068b54999a831bb195c08541ca995ef0505c96193fMark Lacey  CGFunctionInfo() : Required(RequiredArgs::All) {}
5078b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5088b54999a831bb195c08541ca995ef0505c96193fMark Laceypublic:
5098b54999a831bb195c08541ca995ef0505c96193fMark Lacey  static CGFunctionInfo *create(unsigned llvmCC,
5100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                bool instanceMethod,
5110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                bool chainCall,
5128b54999a831bb195c08541ca995ef0505c96193fMark Lacey                                const FunctionType::ExtInfo &extInfo,
5134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                ArrayRef<ExtParameterInfo> paramInfos,
5148b54999a831bb195c08541ca995ef0505c96193fMark Lacey                                CanQualType resultType,
5158b54999a831bb195c08541ca995ef0505c96193fMark Lacey                                ArrayRef<CanQualType> argTypes,
5168b54999a831bb195c08541ca995ef0505c96193fMark Lacey                                RequiredArgs required);
5174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void operator delete(void *p) { ::operator delete(p); }
5184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
5194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Friending class TrailingObjects is apparently not good enough for MSVC,
5204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // so these have to be public.
5214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  friend class TrailingObjects;
5224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  size_t numTrailingObjects(OverloadToken<ArgInfo>) const {
5234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return NumArgs + 1;
5244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
5254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
5264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return (HasExtParameterInfos ? NumArgs : 0);
5274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
5288b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5298b54999a831bb195c08541ca995ef0505c96193fMark Lacey  typedef const ArgInfo *const_arg_iterator;
5308b54999a831bb195c08541ca995ef0505c96193fMark Lacey  typedef ArgInfo *arg_iterator;
5318b54999a831bb195c08541ca995ef0505c96193fMark Lacey
532651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<arg_iterator> arg_range;
533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
534651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
535651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
536651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  arg_const_range arguments() const {
537651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return arg_const_range(arg_begin(), arg_end());
538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
5408b54999a831bb195c08541ca995ef0505c96193fMark Lacey  const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
5418b54999a831bb195c08541ca995ef0505c96193fMark Lacey  const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
5428b54999a831bb195c08541ca995ef0505c96193fMark Lacey  arg_iterator arg_begin() { return getArgsBuffer() + 1; }
5438b54999a831bb195c08541ca995ef0505c96193fMark Lacey  arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
5448b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5458b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned  arg_size() const { return NumArgs; }
5468b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5478b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool isVariadic() const { return Required.allowsOptionalArgs(); }
5488b54999a831bb195c08541ca995ef0505c96193fMark Lacey  RequiredArgs getRequiredArgs() const { return Required; }
549176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  unsigned getNumRequiredArgs() const {
550176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size();
551176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
5528b54999a831bb195c08541ca995ef0505c96193fMark Lacey
553651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool isInstanceMethod() const { return InstanceMethod; }
554651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
5550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  bool isChainCall() const { return ChainCall; }
5560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
5578b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool isNoReturn() const { return NoReturn; }
5588b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5598b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// In ARC, whether this function retains its return value.  This
5608b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// is not always reliable for call sites.
5618b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool isReturnsRetained() const { return ReturnsRetained; }
5628b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5638b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// getASTCallingConvention() - Return the AST-specified calling
5648b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// convention.
5658b54999a831bb195c08541ca995ef0505c96193fMark Lacey  CallingConv getASTCallingConvention() const {
5668b54999a831bb195c08541ca995ef0505c96193fMark Lacey    return CallingConv(ASTCallingConvention);
5678b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
5688b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5698b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// getCallingConvention - Return the user specified calling
5708b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// convention, which has been translated into an LLVM CC.
5718b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned getCallingConvention() const { return CallingConvention; }
5728b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5738b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// getEffectiveCallingConvention - Return the actual calling convention to
5748b54999a831bb195c08541ca995ef0505c96193fMark Lacey  /// use, which may depend on the ABI.
5758b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned getEffectiveCallingConvention() const {
5768b54999a831bb195c08541ca995ef0505c96193fMark Lacey    return EffectiveCallingConvention;
5778b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
5788b54999a831bb195c08541ca995ef0505c96193fMark Lacey  void setEffectiveCallingConvention(unsigned Value) {
5798b54999a831bb195c08541ca995ef0505c96193fMark Lacey    EffectiveCallingConvention = Value;
5808b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
5818b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5828b54999a831bb195c08541ca995ef0505c96193fMark Lacey  bool getHasRegParm() const { return HasRegParm; }
5838b54999a831bb195c08541ca995ef0505c96193fMark Lacey  unsigned getRegParm() const { return RegParm; }
5848b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5858b54999a831bb195c08541ca995ef0505c96193fMark Lacey  FunctionType::ExtInfo getExtInfo() const {
5868b54999a831bb195c08541ca995ef0505c96193fMark Lacey    return FunctionType::ExtInfo(isNoReturn(),
5878b54999a831bb195c08541ca995ef0505c96193fMark Lacey                                 getHasRegParm(), getRegParm(),
5888b54999a831bb195c08541ca995ef0505c96193fMark Lacey                                 getASTCallingConvention(),
5898b54999a831bb195c08541ca995ef0505c96193fMark Lacey                                 isReturnsRetained());
5908b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
5918b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5928b54999a831bb195c08541ca995ef0505c96193fMark Lacey  CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
5938b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5948b54999a831bb195c08541ca995ef0505c96193fMark Lacey  ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
5958b54999a831bb195c08541ca995ef0505c96193fMark Lacey  const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
5968b54999a831bb195c08541ca995ef0505c96193fMark Lacey
5974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
5984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!HasExtParameterInfos) return {};
5994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return llvm::makeArrayRef(getExtParameterInfosBuffer(), NumArgs);
6004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
6014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ExtParameterInfo getExtParameterInfo(unsigned argIndex) const {
6024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(argIndex <= NumArgs);
6034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!HasExtParameterInfos) return ExtParameterInfo();
6044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return getExtParameterInfos()[argIndex];
6054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
6064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
607651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Return true if this function uses inalloca arguments.
608651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool usesInAlloca() const { return ArgStruct; }
609651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
610651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Get the struct type used to represent all the arguments in memory.
611651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::StructType *getArgStruct() const { return ArgStruct; }
61287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CharUnits getArgStructAlignment() const {
61387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return CharUnits::fromQuantity(ArgStructAlign);
61487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
61587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  void setArgStruct(llvm::StructType *Ty, CharUnits Align) {
61687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ArgStruct = Ty;
61787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    ArgStructAlign = Align.getQuantity();
61887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
619651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
6208b54999a831bb195c08541ca995ef0505c96193fMark Lacey  void Profile(llvm::FoldingSetNodeID &ID) {
6218b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddInteger(getASTCallingConvention());
622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ID.AddBoolean(InstanceMethod);
6230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    ID.AddBoolean(ChainCall);
6248b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddBoolean(NoReturn);
6258b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddBoolean(ReturnsRetained);
6268b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddBoolean(HasRegParm);
6278b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddInteger(RegParm);
6288b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddInteger(Required.getOpaqueData());
6294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ID.AddBoolean(HasExtParameterInfos);
6304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (HasExtParameterInfos) {
6314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (auto paramInfo : getExtParameterInfos())
6324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ID.AddInteger(paramInfo.getOpaqueValue());
6334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
6348b54999a831bb195c08541ca995ef0505c96193fMark Lacey    getReturnType().Profile(ID);
635651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto &I : arguments())
636651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      I.type.Profile(ID);
6378b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
6388b54999a831bb195c08541ca995ef0505c96193fMark Lacey  static void Profile(llvm::FoldingSetNodeID &ID,
639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      bool InstanceMethod,
6400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                      bool ChainCall,
6418b54999a831bb195c08541ca995ef0505c96193fMark Lacey                      const FunctionType::ExtInfo &info,
6424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                      ArrayRef<ExtParameterInfo> paramInfos,
6438b54999a831bb195c08541ca995ef0505c96193fMark Lacey                      RequiredArgs required,
6448b54999a831bb195c08541ca995ef0505c96193fMark Lacey                      CanQualType resultType,
6458b54999a831bb195c08541ca995ef0505c96193fMark Lacey                      ArrayRef<CanQualType> argTypes) {
6468b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddInteger(info.getCC());
647651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ID.AddBoolean(InstanceMethod);
6480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    ID.AddBoolean(ChainCall);
6498b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddBoolean(info.getNoReturn());
6508b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddBoolean(info.getProducesResult());
6518b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddBoolean(info.getHasRegParm());
6528b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddInteger(info.getRegParm());
6538b54999a831bb195c08541ca995ef0505c96193fMark Lacey    ID.AddInteger(required.getOpaqueData());
6544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ID.AddBoolean(!paramInfos.empty());
6554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!paramInfos.empty()) {
6564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      for (auto paramInfo : paramInfos)
6574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ID.AddInteger(paramInfo.getOpaqueValue());
6584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
6598b54999a831bb195c08541ca995ef0505c96193fMark Lacey    resultType.Profile(ID);
6608b54999a831bb195c08541ca995ef0505c96193fMark Lacey    for (ArrayRef<CanQualType>::iterator
6618b54999a831bb195c08541ca995ef0505c96193fMark Lacey           i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
6628b54999a831bb195c08541ca995ef0505c96193fMark Lacey      i->Profile(ID);
6638b54999a831bb195c08541ca995ef0505c96193fMark Lacey    }
6648b54999a831bb195c08541ca995ef0505c96193fMark Lacey  }
6658b54999a831bb195c08541ca995ef0505c96193fMark Lacey};
6668b54999a831bb195c08541ca995ef0505c96193fMark Lacey
66787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// CGCalleeInfo - Class to encapsulate the information about a callee to be
66887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// used during the generation of call/invoke instructions.
66987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass CGCalleeInfo {
67087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  /// \brief The function proto type of the callee.
67187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  const FunctionProtoType *CalleeProtoTy;
67287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  /// \brief The function declaration of the callee.
67387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  const Decl *CalleeDecl;
67487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
67587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarpublic:
67687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl(nullptr) {}
67787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGCalleeInfo(const FunctionProtoType *calleeProtoTy, const Decl *calleeDecl)
67887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {}
67987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGCalleeInfo(const FunctionProtoType *calleeProtoTy)
68087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      : CalleeProtoTy(calleeProtoTy), CalleeDecl(nullptr) {}
68187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  CGCalleeInfo(const Decl *calleeDecl)
68287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar      : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {}
68387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
68487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  const FunctionProtoType *getCalleeFunctionProtoType() {
68587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    return CalleeProtoTy;
68687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  }
68787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  const Decl *getCalleeDecl() { return CalleeDecl; }
68887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar};
68987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
6908b54999a831bb195c08541ca995ef0505c96193fMark Lacey}  // end namespace CodeGen
6918b54999a831bb195c08541ca995ef0505c96193fMark Lacey}  // end namespace clang
6928b54999a831bb195c08541ca995ef0505c96193fMark Lacey
6938b54999a831bb195c08541ca995ef0505c96193fMark Lacey#endif
694