]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/CodeGen/SwiftCallingConv.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / CodeGen / SwiftCallingConv.h
1 //==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Defines constants and types related to Swift ABI lowering.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
15 #define LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
16
17 #include "clang/AST/CanonicalType.h"
18 #include "clang/AST/CharUnits.h"
19 #include "clang/AST/Type.h"
20 #include "llvm/Support/TrailingObjects.h"
21 #include <cassert>
22
23 namespace llvm {
24   class IntegerType;
25   class Type;
26   class StructType;
27   class VectorType;
28 }
29
30 namespace clang {
31 class Decl;
32 class FieldDecl;
33 class ASTRecordLayout;
34
35 namespace CodeGen {
36 class ABIArgInfo;
37 class CodeGenModule;
38 class CGFunctionInfo;
39
40 namespace swiftcall {
41
42 class SwiftAggLowering {
43   CodeGenModule &CGM;
44
45   struct StorageEntry {
46     CharUnits Begin;
47     CharUnits End;
48     llvm::Type *Type;
49
50     CharUnits getWidth() const {
51       return End - Begin;
52     }
53   };
54   SmallVector<StorageEntry, 4> Entries;
55   bool Finished = false;
56
57 public:
58   SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
59
60   void addOpaqueData(CharUnits begin, CharUnits end) {
61     addEntry(nullptr, begin, end);
62   }
63
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);
70
71   void finish();
72
73   /// Does this lowering require passing any data?
74   bool empty() const {
75     assert(Finished && "didn't finish lowering before calling empty()");
76     return Entries.empty();
77   }
78
79   /// According to the target Swift ABI, should a value with this lowering
80   /// be passed indirectly?
81   ///
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.
86   ///
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;
91
92   using EnumerationCallback =
93     llvm::function_ref<void(CharUnits offset, CharUnits end, llvm::Type *type)>;
94
95   /// Enumerate the expanded components of this type.
96   ///
97   /// The component types will always be legal vector, floating-point,
98   /// integer, or pointer types.
99   void enumerateComponents(EnumerationCallback callback) const;
100
101   /// Return the types for a coerce-and-expand operation.
102   ///
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.
106   ///
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;
110
111 private:
112   void addBitFieldData(const FieldDecl *field, CharUnits begin,
113                        uint64_t bitOffset);
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);
117   static bool shouldMergeEntries(const StorageEntry &first,
118                                  const StorageEntry &second,
119                                  CharUnits chunkSize);
120 };
121
122 /// Should an aggregate which expands to the given type sequence
123 /// be passed/returned indirectly under swiftcall?
124 bool shouldPassIndirectly(CodeGenModule &CGM,
125                           ArrayRef<llvm::Type*> types,
126                           bool asReturnValue);
127
128 /// Return the maximum voluntary integer size for the current target.
129 CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);
130
131 /// Return the Swift CC's notion of the natural alignment of a type.
132 CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type);
133
134 /// Is the given integer type "legal" for Swift's perspective on the
135 /// current platform?
136 bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
137
138 /// Is the given vector type "legal" for Swift's perspective on the
139 /// current platform?
140 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
141                        llvm::VectorType *vectorTy);
142 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
143                        llvm::Type *eltTy, unsigned numElts);
144
145 /// Minimally split a legal vector type.
146 std::pair<llvm::Type*, unsigned>
147 splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
148                      llvm::VectorType *vectorTy);
149
150 /// Turn a vector type in a sequence of legal component vector types.
151 ///
152 /// The caller may assume that the sum of the data sizes of the resulting
153 /// types will equal the data size of the vector type.
154 void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
155                         llvm::VectorType *vectorTy,
156                         llvm::SmallVectorImpl<llvm::Type*> &types);
157
158 /// Is the given record type required to be passed and returned indirectly
159 /// because of language restrictions?
160 ///
161 /// This considers *only* mandatory indirectness due to language restrictions,
162 /// such as C++'s non-trivially-copyable types and Objective-C's __weak
163 /// references.  A record for which this returns true may still be passed
164 /// indirectly for other reasons, such as being too large to fit in a
165 /// reasonable number of registers.
166 bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record);
167
168 /// Classify the rules for how to return a particular type.
169 ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type);
170
171 /// Classify the rules for how to pass a particular type.
172 ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);
173
174 /// Compute the ABI information of a swiftcall function.  This is a
175 /// private interface for Clang.
176 void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
177
178 /// Is swifterror lowered to a register by the target ABI?
179 bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);
180
181 } // end namespace swiftcall
182 } // end namespace CodeGen
183 } // end namespace clang
184
185 #endif