Clang Project

clang_source_code/include/clang/CodeGen/SwiftCallingConv.h
1//==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Defines constants and types related to Swift ABI lowering.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
14#define LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
15
16#include "clang/AST/CanonicalType.h"
17#include "clang/AST/CharUnits.h"
18#include "clang/AST/Type.h"
19#include "llvm/Support/TrailingObjects.h"
20#include <cassert>
21
22namespace llvm {
23  class IntegerType;
24  class Type;
25  class StructType;
26  class VectorType;
27}
28
29namespace clang {
30class Decl;
31class FieldDecl;
32class ASTRecordLayout;
33
34namespace CodeGen {
35class ABIArgInfo;
36class CodeGenModule;
37class CGFunctionInfo;
38
39namespace swiftcall {
40
41class SwiftAggLowering {
42  CodeGenModule &CGM;
43
44  struct StorageEntry {
45    CharUnits Begin;
46    CharUnits End;
47    llvm::Type *Type;
48
49    CharUnits getWidth() const {
50      return End - Begin;
51    }
52  };
53  SmallVector<StorageEntry4Entries;
54  bool Finished = false;
55
56public:
57  SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
58
59  void addOpaqueData(CharUnits beginCharUnits end) {
60    addEntry(nullptrbeginend);
61  }
62
63  void addTypedData(QualType typeCharUnits begin);
64  void addTypedData(const RecordDecl *recordCharUnits begin);
65  void addTypedData(const RecordDecl *recordCharUnits begin,
66                    const ASTRecordLayout &layout);
67  void addTypedData(llvm::Type *typeCharUnits begin);
68  void addTypedData(llvm::Type *typeCharUnits beginCharUnits end);
69
70  void finish();
71
72  /// Does this lowering require passing any data?
73  bool empty() const {
74     (0) . __assert_fail ("Finished && \"didn't finish lowering before calling empty()\"", "/home/seafit/code_projects/clang_source/clang/include/clang/CodeGen/SwiftCallingConv.h", 74, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Finished && "didn't finish lowering before calling empty()");
75    return Entries.empty();
76  }
77
78  /// According to the target Swift ABI, should a value with this lowering
79  /// be passed indirectly?
80  ///
81  /// Note that this decision is based purely on the data layout of the
82  /// value and does not consider whether the type is address-only,
83  /// must be passed indirectly to match a function abstraction pattern, or
84  /// anything else that is expected to be handled by high-level lowering.
85  ///
86  /// \param asReturnValue - if true, answer whether it should be passed
87  ///   indirectly as a return value; if false, answer whether it should be
88  ///   passed indirectly as an argument
89  bool shouldPassIndirectly(bool asReturnValueconst;
90
91  using EnumerationCallback =
92    llvm::function_ref<void(CharUnits offset, CharUnits end, llvm::Type *type)>;
93
94  /// Enumerate the expanded components of this type.
95  ///
96  /// The component types will always be legal vector, floating-point,
97  /// integer, or pointer types.
98  void enumerateComponents(EnumerationCallback callbackconst;
99
100  /// Return the types for a coerce-and-expand operation.
101  ///
102  /// The first type matches the memory layout of the data that's been
103  /// added to this structure, including explicit [N x i8] arrays for any
104  /// internal padding.
105  ///
106  /// The second type removes any internal padding members and, if only
107  /// one element remains, is simply that element type.
108  std::pair<llvm::StructType*, llvm::Type*> getCoerceAndExpandTypes() const;
109
110private:
111  void addBitFieldData(const FieldDecl *fieldCharUnits begin,
112                       uint64_t bitOffset);
113  void addLegalTypedData(llvm::Type *typeCharUnits beginCharUnits end);
114  void addEntry(llvm::Type *typeCharUnits beginCharUnits end);
115  void splitVectorEntry(unsigned index);
116  static bool shouldMergeEntries(const StorageEntry &first,
117                                 const StorageEntry &second,
118                                 CharUnits chunkSize);
119};
120
121/// Should an aggregate which expands to the given type sequence
122/// be passed/returned indirectly under swiftcall?
123bool shouldPassIndirectly(CodeGenModule &CGM,
124                          ArrayRef<llvm::Type*> types,
125                          bool asReturnValue);
126
127/// Return the maximum voluntary integer size for the current target.
128CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);
129
130/// Return the Swift CC's notion of the natural alignment of a type.
131CharUnits getNaturalAlignment(CodeGenModule &CGMllvm::Type *type);
132
133/// Is the given integer type "legal" for Swift's perspective on the
134/// current platform?
135bool isLegalIntegerType(CodeGenModule &CGMllvm::IntegerType *type);
136
137/// Is the given vector type "legal" for Swift's perspective on the
138/// current platform?
139bool isLegalVectorType(CodeGenModule &CGMCharUnits vectorSize,
140                       llvm::VectorType *vectorTy);
141bool isLegalVectorType(CodeGenModule &CGMCharUnits vectorSize,
142                       llvm::Type *eltTyunsigned numElts);
143
144/// Minimally split a legal vector type.
145std::pair<llvm::Type*, unsigned>
146splitLegalVectorType(CodeGenModule &CGMCharUnits vectorSize,
147                     llvm::VectorType *vectorTy);
148
149/// Turn a vector type in a sequence of legal component vector types.
150///
151/// The caller may assume that the sum of the data sizes of the resulting
152/// types will equal the data size of the vector type.
153void legalizeVectorType(CodeGenModule &CGMCharUnits vectorSize,
154                        llvm::VectorType *vectorTy,
155                        llvm::SmallVectorImpl<llvm::Type*> &types);
156
157/// Is the given record type required to be passed and returned indirectly
158/// because of language restrictions?
159///
160/// This considers *only* mandatory indirectness due to language restrictions,
161/// such as C++'s non-trivially-copyable types and Objective-C's __weak
162/// references.  A record for which this returns true may still be passed
163/// indirectly for other reasons, such as being too large to fit in a
164/// reasonable number of registers.
165bool mustPassRecordIndirectly(CodeGenModule &CGMconst RecordDecl *record);
166
167/// Classify the rules for how to return a particular type.
168ABIArgInfo classifyReturnType(CodeGenModule &CGMCanQualType type);
169
170/// Classify the rules for how to pass a particular type.
171ABIArgInfo classifyArgumentType(CodeGenModule &CGMCanQualType type);
172
173/// Compute the ABI information of a swiftcall function.  This is a
174/// private interface for Clang.
175void computeABIInfo(CodeGenModule &CGMCGFunctionInfo &FI);
176
177/// Is swifterror lowered to a register by the target ABI?
178bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);
179
180// end namespace swiftcall
181// end namespace CodeGen
182// end namespace clang
183
184#endif
185
clang::CodeGen::swiftcall::SwiftAggLowering::CGM
clang::CodeGen::swiftcall::SwiftAggLowering::StorageEntry
clang::CodeGen::swiftcall::SwiftAggLowering::StorageEntry::Begin
clang::CodeGen::swiftcall::SwiftAggLowering::StorageEntry::End
clang::CodeGen::swiftcall::SwiftAggLowering::StorageEntry::Type
clang::CodeGen::swiftcall::SwiftAggLowering::StorageEntry::getWidth
clang::CodeGen::swiftcall::SwiftAggLowering::Entries
clang::CodeGen::swiftcall::SwiftAggLowering::Finished
clang::CodeGen::swiftcall::SwiftAggLowering::addOpaqueData
clang::CodeGen::swiftcall::SwiftAggLowering::addTypedData
clang::CodeGen::swiftcall::SwiftAggLowering::addTypedData
clang::CodeGen::swiftcall::SwiftAggLowering::addTypedData
clang::CodeGen::swiftcall::SwiftAggLowering::addTypedData
clang::CodeGen::swiftcall::SwiftAggLowering::addTypedData
clang::CodeGen::swiftcall::SwiftAggLowering::finish
clang::CodeGen::swiftcall::SwiftAggLowering::empty
clang::CodeGen::swiftcall::SwiftAggLowering::shouldPassIndirectly
clang::CodeGen::swiftcall::SwiftAggLowering::enumerateComponents
clang::CodeGen::swiftcall::SwiftAggLowering::getCoerceAndExpandTypes
clang::CodeGen::swiftcall::SwiftAggLowering::addBitFieldData
clang::CodeGen::swiftcall::SwiftAggLowering::addLegalTypedData
clang::CodeGen::swiftcall::SwiftAggLowering::addEntry
clang::CodeGen::swiftcall::SwiftAggLowering::splitVectorEntry
clang::CodeGen::swiftcall::SwiftAggLowering::shouldMergeEntries