1 //==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Defines constants and types related to Swift ABI lowering.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
15 #define LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
17 #include "clang/AST/CanonicalType.h"
18 #include "clang/AST/CharUnits.h"
19 #include "clang/AST/Type.h"
20 #include "llvm/Support/TrailingObjects.h"
33 class ASTRecordLayout;
42 class SwiftAggLowering {
50 CharUnits getWidth() const {
54 SmallVector<StorageEntry, 4> Entries;
55 bool Finished = false;
58 SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
60 void addOpaqueData(CharUnits begin, CharUnits end) {
61 addEntry(nullptr, begin, end);
64 void addTypedData(QualType type, CharUnits begin);
65 void addTypedData(const RecordDecl *record, CharUnits begin);
66 void addTypedData(const RecordDecl *record, CharUnits begin,
67 const ASTRecordLayout &layout);
68 void addTypedData(llvm::Type *type, CharUnits begin);
69 void addTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
73 /// Does this lowering require passing any data?
75 assert(Finished && "didn't finish lowering before calling empty()");
76 return Entries.empty();
79 /// According to the target Swift ABI, should a value with this lowering
80 /// be passed indirectly?
82 /// Note that this decision is based purely on the data layout of the
83 /// value and does not consider whether the type is address-only,
84 /// must be passed indirectly to match a function abstraction pattern, or
85 /// anything else that is expected to be handled by high-level lowering.
87 /// \param asReturnValue - if true, answer whether it should be passed
88 /// indirectly as a return value; if false, answer whether it should be
89 /// passed indirectly as an argument
90 bool shouldPassIndirectly(bool asReturnValue) const;
92 using EnumerationCallback =
93 llvm::function_ref<void(CharUnits offset, CharUnits end, llvm::Type *type)>;
95 /// Enumerate the expanded components of this type.
97 /// The component types will always be legal vector, floating-point,
98 /// integer, or pointer types.
99 void enumerateComponents(EnumerationCallback callback) const;
101 /// Return the types for a coerce-and-expand operation.
103 /// The first type matches the memory layout of the data that's been
104 /// added to this structure, including explicit [N x i8] arrays for any
105 /// internal padding.
107 /// The second type removes any internal padding members and, if only
108 /// one element remains, is simply that element type.
109 std::pair<llvm::StructType*, llvm::Type*> getCoerceAndExpandTypes() const;
112 void addBitFieldData(const FieldDecl *field, CharUnits begin,
114 void addLegalTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
115 void addEntry(llvm::Type *type, CharUnits begin, CharUnits end);
116 void splitVectorEntry(unsigned index);
119 /// Should an aggregate which expands to the given type sequence
120 /// be passed/returned indirectly under swiftcall?
121 bool shouldPassIndirectly(CodeGenModule &CGM,
122 ArrayRef<llvm::Type*> types,
125 /// Return the maximum voluntary integer size for the current target.
126 CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);
128 /// Return the Swift CC's notion of the natural alignment of a type.
129 CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type);
131 /// Is the given integer type "legal" for Swift's perspective on the
132 /// current platform?
133 bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
135 /// Is the given vector type "legal" for Swift's perspective on the
136 /// current platform?
137 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
138 llvm::VectorType *vectorTy);
139 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
140 llvm::Type *eltTy, unsigned numElts);
142 /// Minimally split a legal vector type.
143 std::pair<llvm::Type*, unsigned>
144 splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
145 llvm::VectorType *vectorTy);
147 /// Turn a vector type in a sequence of legal component vector types.
149 /// The caller may assume that the sum of the data sizes of the resulting
150 /// types will equal the data size of the vector type.
151 void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
152 llvm::VectorType *vectorTy,
153 llvm::SmallVectorImpl<llvm::Type*> &types);
155 /// Is the given record type required to be passed and returned indirectly
156 /// because of language restrictions?
158 /// This considers *only* mandatory indirectness due to language restrictions,
159 /// such as C++'s non-trivially-copyable types and Objective-C's __weak
160 /// references. A record for which this returns true may still be passed
161 /// indirectly for other reasons, such as being too large to fit in a
162 /// reasonable number of registers.
163 bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record);
165 /// Classify the rules for how to return a particular type.
166 ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type);
168 /// Classify the rules for how to pass a particular type.
169 ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);
171 /// Compute the ABI information of a swiftcall function. This is a
172 /// private interface for Clang.
173 void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
175 /// Is swifterror lowered to a register by the target ABI?
176 bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);
178 } // end namespace swiftcall
179 } // end namespace CodeGen
180 } // end namespace clang