CGFunctionInfo.h revision 651f13cea278ec967336033dd032faef0e9fc2ec
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 168b54999a831bb195c08541ca995ef0505c96193fMark Lacey#ifndef LLVM_CLANG_CODEGEN_FUNCTION_INFO_H 178b54999a831bb195c08541ca995ef0505c96193fMark Lacey#define LLVM_CLANG_CODEGEN_FUNCTION_INFO_H 188b54999a831bb195c08541ca995ef0505c96193fMark Lacey 198b54999a831bb195c08541ca995ef0505c96193fMark Lacey#include "clang/AST/CanonicalType.h" 208b54999a831bb195c08541ca995ef0505c96193fMark Lacey#include "clang/AST/Type.h" 218b54999a831bb195c08541ca995ef0505c96193fMark Lacey#include "llvm/ADT/FoldingSet.h" 228b54999a831bb195c08541ca995ef0505c96193fMark Lacey#include <cassert> 238b54999a831bb195c08541ca995ef0505c96193fMark Lacey 248b54999a831bb195c08541ca995ef0505c96193fMark Laceynamespace llvm { 258b54999a831bb195c08541ca995ef0505c96193fMark Lacey class Type; 26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines class StructType; 278b54999a831bb195c08541ca995ef0505c96193fMark Lacey} 288b54999a831bb195c08541ca995ef0505c96193fMark Lacey 298b54999a831bb195c08541ca995ef0505c96193fMark Laceynamespace clang { 30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass Decl; 31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 328b54999a831bb195c08541ca995ef0505c96193fMark Laceynamespace CodeGen { 338b54999a831bb195c08541ca995ef0505c96193fMark Lacey 348b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// ABIArgInfo - Helper class to encapsulate information about how a 358b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// specific C type should be passed to or returned from a function. 368b54999a831bb195c08541ca995ef0505c96193fMark Laceyclass ABIArgInfo { 378b54999a831bb195c08541ca995ef0505c96193fMark Laceypublic: 388b54999a831bb195c08541ca995ef0505c96193fMark Lacey enum Kind { 398b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// Direct - Pass the argument directly using the normal converted LLVM 408b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// type, or by coercing to another specified type stored in 418b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// 'CoerceToType'). If an offset is specified (in UIntData), then the 428b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// argument passed is offset by some number of bytes in the memory 438b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// representation. A dummy argument is emitted before the real argument 448b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// if the specified type stored in "PaddingType" is not zero. 458b54999a831bb195c08541ca995ef0505c96193fMark Lacey Direct, 468b54999a831bb195c08541ca995ef0505c96193fMark Lacey 478b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// Extend - Valid only for integer argument types. Same as 'direct' 488b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// but also emit a zero/sign extension attribute. 498b54999a831bb195c08541ca995ef0505c96193fMark Lacey Extend, 508b54999a831bb195c08541ca995ef0505c96193fMark Lacey 518b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// Indirect - Pass the argument indirectly via a hidden pointer 528b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// with the specified alignment (0 indicates default alignment). 538b54999a831bb195c08541ca995ef0505c96193fMark Lacey Indirect, 548b54999a831bb195c08541ca995ef0505c96193fMark Lacey 558b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// Ignore - Ignore the argument (treat as void). Useful for void and 568b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// empty structs. 578b54999a831bb195c08541ca995ef0505c96193fMark Lacey Ignore, 588b54999a831bb195c08541ca995ef0505c96193fMark Lacey 598b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// Expand - Only valid for aggregate argument types. The structure should 608b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// be expanded into consecutive arguments for its constituent fields. 618b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// Currently expand is only allowed on structures whose fields 628b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// are all scalar types or are themselves expandable types. 638b54999a831bb195c08541ca995ef0505c96193fMark Lacey Expand, 648b54999a831bb195c08541ca995ef0505c96193fMark Lacey 65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// InAlloca - Pass the argument directly using the LLVM inalloca attribute. 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// This is similar to 'direct', except it only applies to arguments stored 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// in memory and forbids any implicit copies. When applied to a return 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// type, it means the value is returned indirectly via an implicit sret 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// parameter stored in the argument struct. 70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InAlloca, 71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines KindFirst = Direct, 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines KindLast = InAlloca 748b54999a831bb195c08541ca995ef0505c96193fMark Lacey }; 758b54999a831bb195c08541ca995ef0505c96193fMark Lacey 768b54999a831bb195c08541ca995ef0505c96193fMark Laceyprivate: 778b54999a831bb195c08541ca995ef0505c96193fMark Lacey Kind TheKind; 788b54999a831bb195c08541ca995ef0505c96193fMark Lacey llvm::Type *TypeData; 798b54999a831bb195c08541ca995ef0505c96193fMark Lacey llvm::Type *PaddingType; 808b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned UIntData; 818b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool BoolData0; 828b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool BoolData1; 838b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool InReg; 848b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool PaddingInReg; 858b54999a831bb195c08541ca995ef0505c96193fMark Lacey 868b54999a831bb195c08541ca995ef0505c96193fMark Lacey ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR, 878b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool PIR, llvm::Type* P) 888b54999a831bb195c08541ca995ef0505c96193fMark Lacey : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0), 898b54999a831bb195c08541ca995ef0505c96193fMark Lacey BoolData1(B1), InReg(IR), PaddingInReg(PIR) {} 908b54999a831bb195c08541ca995ef0505c96193fMark Lacey 918b54999a831bb195c08541ca995ef0505c96193fMark Laceypublic: 928b54999a831bb195c08541ca995ef0505c96193fMark Lacey ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {} 938b54999a831bb195c08541ca995ef0505c96193fMark Lacey 948b54999a831bb195c08541ca995ef0505c96193fMark Lacey static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0, 958b54999a831bb195c08541ca995ef0505c96193fMark Lacey llvm::Type *Padding = 0) { 968b54999a831bb195c08541ca995ef0505c96193fMark Lacey return ABIArgInfo(Direct, T, Offset, false, false, false, false, Padding); 978b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 988b54999a831bb195c08541ca995ef0505c96193fMark Lacey static ABIArgInfo getDirectInReg(llvm::Type *T = 0) { 998b54999a831bb195c08541ca995ef0505c96193fMark Lacey return ABIArgInfo(Direct, T, 0, false, false, true, false, 0); 1008b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1018b54999a831bb195c08541ca995ef0505c96193fMark Lacey static ABIArgInfo getExtend(llvm::Type *T = 0) { 1028b54999a831bb195c08541ca995ef0505c96193fMark Lacey return ABIArgInfo(Extend, T, 0, false, false, false, false, 0); 1038b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1048b54999a831bb195c08541ca995ef0505c96193fMark Lacey static ABIArgInfo getExtendInReg(llvm::Type *T = 0) { 1058b54999a831bb195c08541ca995ef0505c96193fMark Lacey return ABIArgInfo(Extend, T, 0, false, false, true, false, 0); 1068b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1078b54999a831bb195c08541ca995ef0505c96193fMark Lacey static ABIArgInfo getIgnore() { 1088b54999a831bb195c08541ca995ef0505c96193fMark Lacey return ABIArgInfo(Ignore, 0, 0, false, false, false, false, 0); 1098b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1108b54999a831bb195c08541ca995ef0505c96193fMark Lacey static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true 1118b54999a831bb195c08541ca995ef0505c96193fMark Lacey , bool Realign = false 1128b54999a831bb195c08541ca995ef0505c96193fMark Lacey , llvm::Type *Padding = 0) { 1138b54999a831bb195c08541ca995ef0505c96193fMark Lacey return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, false, 1148b54999a831bb195c08541ca995ef0505c96193fMark Lacey Padding); 1158b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static ABIArgInfo getInAlloca(unsigned FieldIndex) { 117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return ABIArgInfo(InAlloca, 0, FieldIndex, false, false, false, false, 0); 118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1198b54999a831bb195c08541ca995ef0505c96193fMark Lacey static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true 1208b54999a831bb195c08541ca995ef0505c96193fMark Lacey , bool Realign = false) { 1218b54999a831bb195c08541ca995ef0505c96193fMark Lacey return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, false, 0); 1228b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1238b54999a831bb195c08541ca995ef0505c96193fMark Lacey static ABIArgInfo getExpand() { 1248b54999a831bb195c08541ca995ef0505c96193fMark Lacey return ABIArgInfo(Expand, 0, 0, false, false, false, false, 0); 1258b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1268b54999a831bb195c08541ca995ef0505c96193fMark Lacey static ABIArgInfo getExpandWithPadding(bool PaddingInReg, 1278b54999a831bb195c08541ca995ef0505c96193fMark Lacey llvm::Type *Padding) { 1288b54999a831bb195c08541ca995ef0505c96193fMark Lacey return ABIArgInfo(Expand, 0, 0, false, false, false, PaddingInReg, 1298b54999a831bb195c08541ca995ef0505c96193fMark Lacey Padding); 1308b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1318b54999a831bb195c08541ca995ef0505c96193fMark Lacey 1328b54999a831bb195c08541ca995ef0505c96193fMark Lacey Kind getKind() const { return TheKind; } 1338b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool isDirect() const { return TheKind == Direct; } 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isInAlloca() const { return TheKind == InAlloca; } 1358b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool isExtend() const { return TheKind == Extend; } 1368b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool isIgnore() const { return TheKind == Ignore; } 1378b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool isIndirect() const { return TheKind == Indirect; } 1388b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool isExpand() const { return TheKind == Expand; } 1398b54999a831bb195c08541ca995ef0505c96193fMark Lacey 1408b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool canHaveCoerceToType() const { 1418b54999a831bb195c08541ca995ef0505c96193fMark Lacey return TheKind == Direct || TheKind == Extend; 1428b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1438b54999a831bb195c08541ca995ef0505c96193fMark Lacey 1448b54999a831bb195c08541ca995ef0505c96193fMark Lacey // Direct/Extend accessors 1458b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned getDirectOffset() const { 1468b54999a831bb195c08541ca995ef0505c96193fMark Lacey assert((isDirect() || isExtend()) && "Not a direct or extend kind"); 1478b54999a831bb195c08541ca995ef0505c96193fMark Lacey return UIntData; 1488b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1498b54999a831bb195c08541ca995ef0505c96193fMark Lacey 1508b54999a831bb195c08541ca995ef0505c96193fMark Lacey llvm::Type *getPaddingType() const { 1518b54999a831bb195c08541ca995ef0505c96193fMark Lacey return PaddingType; 1528b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1538b54999a831bb195c08541ca995ef0505c96193fMark Lacey 1548b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool getPaddingInReg() const { 1558b54999a831bb195c08541ca995ef0505c96193fMark Lacey return PaddingInReg; 1568b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1578b54999a831bb195c08541ca995ef0505c96193fMark Lacey 1588b54999a831bb195c08541ca995ef0505c96193fMark Lacey llvm::Type *getCoerceToType() const { 1598b54999a831bb195c08541ca995ef0505c96193fMark Lacey assert(canHaveCoerceToType() && "Invalid kind!"); 1608b54999a831bb195c08541ca995ef0505c96193fMark Lacey return TypeData; 1618b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1628b54999a831bb195c08541ca995ef0505c96193fMark Lacey 1638b54999a831bb195c08541ca995ef0505c96193fMark Lacey void setCoerceToType(llvm::Type *T) { 1648b54999a831bb195c08541ca995ef0505c96193fMark Lacey assert(canHaveCoerceToType() && "Invalid kind!"); 1658b54999a831bb195c08541ca995ef0505c96193fMark Lacey TypeData = T; 1668b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1678b54999a831bb195c08541ca995ef0505c96193fMark Lacey 1688b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool getInReg() const { 1698b54999a831bb195c08541ca995ef0505c96193fMark Lacey assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"); 1708b54999a831bb195c08541ca995ef0505c96193fMark Lacey return InReg; 1718b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1728b54999a831bb195c08541ca995ef0505c96193fMark Lacey 1738b54999a831bb195c08541ca995ef0505c96193fMark Lacey // Indirect accessors 1748b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned getIndirectAlign() const { 1758b54999a831bb195c08541ca995ef0505c96193fMark Lacey assert(TheKind == Indirect && "Invalid kind!"); 1768b54999a831bb195c08541ca995ef0505c96193fMark Lacey return UIntData; 1778b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1788b54999a831bb195c08541ca995ef0505c96193fMark Lacey 1798b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool getIndirectByVal() const { 1808b54999a831bb195c08541ca995ef0505c96193fMark Lacey assert(TheKind == Indirect && "Invalid kind!"); 1818b54999a831bb195c08541ca995ef0505c96193fMark Lacey return BoolData0; 1828b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1838b54999a831bb195c08541ca995ef0505c96193fMark Lacey 1848b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool getIndirectRealign() const { 1858b54999a831bb195c08541ca995ef0505c96193fMark Lacey assert(TheKind == Indirect && "Invalid kind!"); 1868b54999a831bb195c08541ca995ef0505c96193fMark Lacey return BoolData1; 1878b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 1888b54999a831bb195c08541ca995ef0505c96193fMark Lacey 189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned getInAllocaFieldIndex() const { 190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(TheKind == InAlloca && "Invalid kind!"); 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return UIntData; 192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief Return true if this field of an inalloca struct should be returned 195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// to implement a struct return calling convention. 196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool getInAllocaSRet() const { 197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(TheKind == InAlloca && "Invalid kind!"); 198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return BoolData0; 199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void setInAllocaSRet(bool SRet) { 202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(TheKind == InAlloca && "Invalid kind!"); 203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoolData0 = SRet; 204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2068b54999a831bb195c08541ca995ef0505c96193fMark Lacey void dump() const; 2078b54999a831bb195c08541ca995ef0505c96193fMark Lacey}; 2088b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2098b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// A class for recording the number of arguments that a function 2108b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// signature requires. 2118b54999a831bb195c08541ca995ef0505c96193fMark Laceyclass RequiredArgs { 2128b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// The number of required arguments, or ~0 if the signature does 2138b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// not permit optional arguments. 2148b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned NumRequired; 2158b54999a831bb195c08541ca995ef0505c96193fMark Laceypublic: 2168b54999a831bb195c08541ca995ef0505c96193fMark Lacey enum All_t { All }; 2178b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2188b54999a831bb195c08541ca995ef0505c96193fMark Lacey RequiredArgs(All_t _) : NumRequired(~0U) {} 2198b54999a831bb195c08541ca995ef0505c96193fMark Lacey explicit RequiredArgs(unsigned n) : NumRequired(n) { 2208b54999a831bb195c08541ca995ef0505c96193fMark Lacey assert(n != ~0U); 2218b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 2228b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2238b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// Compute the arguments required by the given formal prototype, 2248b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// given that there may be some additional, non-formal arguments 2258b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// in play. 2268b54999a831bb195c08541ca995ef0505c96193fMark Lacey static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, 2278b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned additional) { 2288b54999a831bb195c08541ca995ef0505c96193fMark Lacey if (!prototype->isVariadic()) return All; 229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return RequiredArgs(prototype->getNumParams() + additional); 2308b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 2318b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2328b54999a831bb195c08541ca995ef0505c96193fMark Lacey static RequiredArgs forPrototype(const FunctionProtoType *prototype) { 2338b54999a831bb195c08541ca995ef0505c96193fMark Lacey return forPrototypePlus(prototype, 0); 2348b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 2358b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2368b54999a831bb195c08541ca995ef0505c96193fMark Lacey static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) { 2378b54999a831bb195c08541ca995ef0505c96193fMark Lacey return forPrototype(prototype.getTypePtr()); 2388b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 2398b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2408b54999a831bb195c08541ca995ef0505c96193fMark Lacey static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype, 2418b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned additional) { 2428b54999a831bb195c08541ca995ef0505c96193fMark Lacey return forPrototypePlus(prototype.getTypePtr(), additional); 2438b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 2448b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2458b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool allowsOptionalArgs() const { return NumRequired != ~0U; } 2468b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned getNumRequiredArgs() const { 2478b54999a831bb195c08541ca995ef0505c96193fMark Lacey assert(allowsOptionalArgs()); 2488b54999a831bb195c08541ca995ef0505c96193fMark Lacey return NumRequired; 2498b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 2508b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2518b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned getOpaqueData() const { return NumRequired; } 2528b54999a831bb195c08541ca995ef0505c96193fMark Lacey static RequiredArgs getFromOpaqueData(unsigned value) { 2538b54999a831bb195c08541ca995ef0505c96193fMark Lacey if (value == ~0U) return All; 2548b54999a831bb195c08541ca995ef0505c96193fMark Lacey return RequiredArgs(value); 2558b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 2568b54999a831bb195c08541ca995ef0505c96193fMark Lacey}; 2578b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2588b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// CGFunctionInfo - Class to encapsulate the information about a 2598b54999a831bb195c08541ca995ef0505c96193fMark Lacey/// function definition. 2608b54999a831bb195c08541ca995ef0505c96193fMark Laceyclass CGFunctionInfo : public llvm::FoldingSetNode { 2618b54999a831bb195c08541ca995ef0505c96193fMark Lacey struct ArgInfo { 2628b54999a831bb195c08541ca995ef0505c96193fMark Lacey CanQualType type; 2638b54999a831bb195c08541ca995ef0505c96193fMark Lacey ABIArgInfo info; 2648b54999a831bb195c08541ca995ef0505c96193fMark Lacey }; 2658b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2668b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// The LLVM::CallingConv to use for this function (as specified by the 2678b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// user). 2688b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned CallingConvention : 8; 2698b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2708b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// The LLVM::CallingConv to actually use for this function, which may 2718b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// depend on the ABI. 2728b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned EffectiveCallingConvention : 8; 2738b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2748b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// The clang::CallingConv that this was originally created with. 2758b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned ASTCallingConvention : 8; 2768b54999a831bb195c08541ca995ef0505c96193fMark Lacey 277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Whether this is an instance method. 278651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned InstanceMethod : 1; 279651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2808b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// Whether this function is noreturn. 2818b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned NoReturn : 1; 2828b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2838b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// Whether this function is returns-retained. 2848b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned ReturnsRetained : 1; 2858b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2868b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// How many arguments to pass inreg. 2878b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned HasRegParm : 1; 2888b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned RegParm : 4; 2898b54999a831bb195c08541ca995ef0505c96193fMark Lacey 2908b54999a831bb195c08541ca995ef0505c96193fMark Lacey RequiredArgs Required; 2918b54999a831bb195c08541ca995ef0505c96193fMark Lacey 292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// The struct representing all arguments passed in memory. Only used when 293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// passing non-trivial types with inalloca. Not part of the profile. 294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::StructType *ArgStruct; 295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2968b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned NumArgs; 2978b54999a831bb195c08541ca995ef0505c96193fMark Lacey ArgInfo *getArgsBuffer() { 2988b54999a831bb195c08541ca995ef0505c96193fMark Lacey return reinterpret_cast<ArgInfo*>(this+1); 2998b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 3008b54999a831bb195c08541ca995ef0505c96193fMark Lacey const ArgInfo *getArgsBuffer() const { 3018b54999a831bb195c08541ca995ef0505c96193fMark Lacey return reinterpret_cast<const ArgInfo*>(this + 1); 3028b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 3038b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3048b54999a831bb195c08541ca995ef0505c96193fMark Lacey CGFunctionInfo() : Required(RequiredArgs::All) {} 3058b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3068b54999a831bb195c08541ca995ef0505c96193fMark Laceypublic: 3078b54999a831bb195c08541ca995ef0505c96193fMark Lacey static CGFunctionInfo *create(unsigned llvmCC, 308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool InstanceMethod, 3098b54999a831bb195c08541ca995ef0505c96193fMark Lacey const FunctionType::ExtInfo &extInfo, 3108b54999a831bb195c08541ca995ef0505c96193fMark Lacey CanQualType resultType, 3118b54999a831bb195c08541ca995ef0505c96193fMark Lacey ArrayRef<CanQualType> argTypes, 3128b54999a831bb195c08541ca995ef0505c96193fMark Lacey RequiredArgs required); 3138b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3148b54999a831bb195c08541ca995ef0505c96193fMark Lacey typedef const ArgInfo *const_arg_iterator; 3158b54999a831bb195c08541ca995ef0505c96193fMark Lacey typedef ArgInfo *arg_iterator; 3168b54999a831bb195c08541ca995ef0505c96193fMark Lacey 317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typedef llvm::iterator_range<arg_iterator> arg_range; 318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typedef llvm::iterator_range<const_arg_iterator> arg_const_range; 319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines arg_range arguments() { return arg_range(arg_begin(), arg_end()); } 321651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines arg_const_range arguments() const { 322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return arg_const_range(arg_begin(), arg_end()); 323651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3258b54999a831bb195c08541ca995ef0505c96193fMark Lacey const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; } 3268b54999a831bb195c08541ca995ef0505c96193fMark Lacey const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; } 3278b54999a831bb195c08541ca995ef0505c96193fMark Lacey arg_iterator arg_begin() { return getArgsBuffer() + 1; } 3288b54999a831bb195c08541ca995ef0505c96193fMark Lacey arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; } 3298b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3308b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned arg_size() const { return NumArgs; } 3318b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3328b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool isVariadic() const { return Required.allowsOptionalArgs(); } 3338b54999a831bb195c08541ca995ef0505c96193fMark Lacey RequiredArgs getRequiredArgs() const { return Required; } 3348b54999a831bb195c08541ca995ef0505c96193fMark Lacey 335651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isInstanceMethod() const { return InstanceMethod; } 336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3378b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool isNoReturn() const { return NoReturn; } 3388b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3398b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// In ARC, whether this function retains its return value. This 3408b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// is not always reliable for call sites. 3418b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool isReturnsRetained() const { return ReturnsRetained; } 3428b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3438b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// getASTCallingConvention() - Return the AST-specified calling 3448b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// convention. 3458b54999a831bb195c08541ca995ef0505c96193fMark Lacey CallingConv getASTCallingConvention() const { 3468b54999a831bb195c08541ca995ef0505c96193fMark Lacey return CallingConv(ASTCallingConvention); 3478b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 3488b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3498b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// getCallingConvention - Return the user specified calling 3508b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// convention, which has been translated into an LLVM CC. 3518b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned getCallingConvention() const { return CallingConvention; } 3528b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3538b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// getEffectiveCallingConvention - Return the actual calling convention to 3548b54999a831bb195c08541ca995ef0505c96193fMark Lacey /// use, which may depend on the ABI. 3558b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned getEffectiveCallingConvention() const { 3568b54999a831bb195c08541ca995ef0505c96193fMark Lacey return EffectiveCallingConvention; 3578b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 3588b54999a831bb195c08541ca995ef0505c96193fMark Lacey void setEffectiveCallingConvention(unsigned Value) { 3598b54999a831bb195c08541ca995ef0505c96193fMark Lacey EffectiveCallingConvention = Value; 3608b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 3618b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3628b54999a831bb195c08541ca995ef0505c96193fMark Lacey bool getHasRegParm() const { return HasRegParm; } 3638b54999a831bb195c08541ca995ef0505c96193fMark Lacey unsigned getRegParm() const { return RegParm; } 3648b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3658b54999a831bb195c08541ca995ef0505c96193fMark Lacey FunctionType::ExtInfo getExtInfo() const { 3668b54999a831bb195c08541ca995ef0505c96193fMark Lacey return FunctionType::ExtInfo(isNoReturn(), 3678b54999a831bb195c08541ca995ef0505c96193fMark Lacey getHasRegParm(), getRegParm(), 3688b54999a831bb195c08541ca995ef0505c96193fMark Lacey getASTCallingConvention(), 3698b54999a831bb195c08541ca995ef0505c96193fMark Lacey isReturnsRetained()); 3708b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 3718b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3728b54999a831bb195c08541ca995ef0505c96193fMark Lacey CanQualType getReturnType() const { return getArgsBuffer()[0].type; } 3738b54999a831bb195c08541ca995ef0505c96193fMark Lacey 3748b54999a831bb195c08541ca995ef0505c96193fMark Lacey ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; } 3758b54999a831bb195c08541ca995ef0505c96193fMark Lacey const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; } 3768b54999a831bb195c08541ca995ef0505c96193fMark Lacey 377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief Return true if this function uses inalloca arguments. 378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool usesInAlloca() const { return ArgStruct; } 379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief Get the struct type used to represent all the arguments in memory. 381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::StructType *getArgStruct() const { return ArgStruct; } 382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void setArgStruct(llvm::StructType *Ty) { ArgStruct = Ty; } 383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3848b54999a831bb195c08541ca995ef0505c96193fMark Lacey void Profile(llvm::FoldingSetNodeID &ID) { 3858b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddInteger(getASTCallingConvention()); 386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ID.AddBoolean(InstanceMethod); 3878b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddBoolean(NoReturn); 3888b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddBoolean(ReturnsRetained); 3898b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddBoolean(HasRegParm); 3908b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddInteger(RegParm); 3918b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddInteger(Required.getOpaqueData()); 3928b54999a831bb195c08541ca995ef0505c96193fMark Lacey getReturnType().Profile(ID); 393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : arguments()) 394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines I.type.Profile(ID); 3958b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 3968b54999a831bb195c08541ca995ef0505c96193fMark Lacey static void Profile(llvm::FoldingSetNodeID &ID, 397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool InstanceMethod, 3988b54999a831bb195c08541ca995ef0505c96193fMark Lacey const FunctionType::ExtInfo &info, 3998b54999a831bb195c08541ca995ef0505c96193fMark Lacey RequiredArgs required, 4008b54999a831bb195c08541ca995ef0505c96193fMark Lacey CanQualType resultType, 4018b54999a831bb195c08541ca995ef0505c96193fMark Lacey ArrayRef<CanQualType> argTypes) { 4028b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddInteger(info.getCC()); 403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ID.AddBoolean(InstanceMethod); 4048b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddBoolean(info.getNoReturn()); 4058b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddBoolean(info.getProducesResult()); 4068b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddBoolean(info.getHasRegParm()); 4078b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddInteger(info.getRegParm()); 4088b54999a831bb195c08541ca995ef0505c96193fMark Lacey ID.AddInteger(required.getOpaqueData()); 4098b54999a831bb195c08541ca995ef0505c96193fMark Lacey resultType.Profile(ID); 4108b54999a831bb195c08541ca995ef0505c96193fMark Lacey for (ArrayRef<CanQualType>::iterator 4118b54999a831bb195c08541ca995ef0505c96193fMark Lacey i = argTypes.begin(), e = argTypes.end(); i != e; ++i) { 4128b54999a831bb195c08541ca995ef0505c96193fMark Lacey i->Profile(ID); 4138b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 4148b54999a831bb195c08541ca995ef0505c96193fMark Lacey } 4158b54999a831bb195c08541ca995ef0505c96193fMark Lacey}; 4168b54999a831bb195c08541ca995ef0505c96193fMark Lacey 4178b54999a831bb195c08541ca995ef0505c96193fMark Lacey} // end namespace CodeGen 4188b54999a831bb195c08541ca995ef0505c96193fMark Lacey} // end namespace clang 4198b54999a831bb195c08541ca995ef0505c96193fMark Lacey 4208b54999a831bb195c08541ca995ef0505c96193fMark Lacey#endif 421