1 //==-- SwiftCallingConv.h - Swift ABI lowering -----------------------------==//
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/ADT/FoldingSet.h"
21 #include "llvm/Support/TrailingObjects.h"
34 class ASTRecordLayout;
43 class SwiftAggLowering {
51 CharUnits getWidth() const {
55 SmallVector<StorageEntry, 4> Entries;
56 bool Finished = false;
59 SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
61 void addOpaqueData(CharUnits begin, CharUnits end) {
62 addEntry(nullptr, begin, end);
65 void addTypedData(QualType type, CharUnits begin);
66 void addTypedData(const RecordDecl *record, CharUnits begin);
67 void addTypedData(const RecordDecl *record, CharUnits begin,
68 const ASTRecordLayout &layout);
69 void addTypedData(llvm::Type *type, CharUnits begin);
70 void addTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
74 /// Does this lowering require passing any data?
76 assert(Finished && "didn't finish lowering before calling empty()");
77 return Entries.empty();
80 /// According to the target Swift ABI, should a value with this lowering
81 /// be passed indirectly?
83 /// Note that this decision is based purely on the data layout of the
84 /// value and does not consider whether the type is address-only,
85 /// must be passed indirectly to match a function abstraction pattern, or
86 /// anything else that is expected to be handled by high-level lowering.
88 /// \param asReturnValue - if true, answer whether it should be passed
89 /// indirectly as a return value; if false, answer whether it should be
90 /// passed indirectly as an argument
91 bool shouldPassIndirectly(bool asReturnValue) const;
93 using EnumerationCallback =
94 llvm::function_ref<void(CharUnits offset, llvm::Type *type)>;
96 /// Enumerate the expanded components of this type.
98 /// The component types will always be legal vector, floating-point,
99 /// integer, or pointer types.
100 void enumerateComponents(EnumerationCallback callback) const;
102 /// Return the types for a coerce-and-expand operation.
104 /// The first type matches the memory layout of the data that's been
105 /// added to this structure, including explicit [N x i8] arrays for any
106 /// internal padding.
108 /// The second type removes any internal padding members and, if only
109 /// one element remains, is simply that element type.
110 std::pair<llvm::StructType*, llvm::Type*> getCoerceAndExpandTypes() const;
113 void addBitFieldData(const FieldDecl *field, CharUnits begin,
115 void addLegalTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
116 void addEntry(llvm::Type *type, CharUnits begin, CharUnits end);
117 void splitVectorEntry(unsigned index);
120 /// Return the maximum voluntary integer size for the current target.
121 CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);
123 /// Return the Swift CC's notion of the natural alignment of a type.
124 CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type);
126 /// Is the given integer type "legal" for Swift's perspective on the
127 /// current platform?
128 bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
130 /// Is the given vector type "legal" for Swift's perspective on the
131 /// current platform?
132 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
133 llvm::VectorType *vectorTy);
134 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
135 llvm::Type *eltTy, unsigned numElts);
137 /// Minimally split a legal vector type.
138 std::pair<llvm::Type*, unsigned>
139 splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
140 llvm::VectorType *vectorTy);
142 /// Turn a vector type in a sequence of legal component vector types.
144 /// The caller may assume that the sum of the data sizes of the resulting
145 /// types will equal the data size of the vector type.
146 void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
147 llvm::VectorType *vectorTy,
148 llvm::SmallVectorImpl<llvm::Type*> &types);
150 /// Should a C++ record type be passed and returned indirectly?
151 bool shouldPassCXXRecordIndirectly(CodeGenModule &CGM,
152 const CXXRecordDecl *record);
154 /// Classify the rules for how to return a particular type.
155 ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type);
157 /// Classify the rules for how to pass a particular type.
158 ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);
160 /// Compute the ABI information of a swiftcall function. This is a
161 /// private interface for Clang.
162 void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
164 } // end namespace swiftcall
165 } // end namespace CodeGen
166 } // end namespace clang