clang  19.0.0git
SwiftCallingConv.h
Go to the documentation of this file.
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. The same ABI
10 // lowering applies to both sync and async functions.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
15 #define LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
16 
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 FieldDecl;
32 class ASTRecordLayout;
33 
34 namespace CodeGen {
35 class ABIArgInfo;
36 class CodeGenModule;
37 class CGFunctionInfo;
38 
39 namespace swiftcall {
40 
42  CodeGenModule &CGM;
43 
44  struct StorageEntry {
46  CharUnits End;
47  llvm::Type *Type;
48 
49  CharUnits getWidth() const {
50  return End - Begin;
51  }
52  };
54  bool Finished = false;
55 
56 public:
57  SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
58 
59  void addOpaqueData(CharUnits begin, CharUnits end) {
60  addEntry(nullptr, begin, end);
61  }
62 
63  void addTypedData(QualType type, CharUnits begin);
64  void addTypedData(const RecordDecl *record, CharUnits begin);
65  void addTypedData(const RecordDecl *record, CharUnits begin,
66  const ASTRecordLayout &layout);
67  void addTypedData(llvm::Type *type, CharUnits begin);
68  void addTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
69 
70  void finish();
71 
72  /// Does this lowering require passing any data?
73  bool empty() const {
74  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 asReturnValue) const;
90 
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 callback) const;
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 
110 private:
111  void addBitFieldData(const FieldDecl *field, CharUnits begin,
112  uint64_t bitOffset);
113  void addLegalTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
114  void addEntry(llvm::Type *type, CharUnits begin, CharUnits 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?
125  bool asReturnValue);
126 
127 /// Return the maximum voluntary integer size for the current target.
129 
130 /// Return the Swift CC's notion of the natural alignment of a type.
132 
133 /// Is the given integer type "legal" for Swift's perspective on the
134 /// current platform?
135 bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
136 
137 /// Is the given vector type "legal" for Swift's perspective on the
138 /// current platform?
139 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
140  llvm::VectorType *vectorTy);
141 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
142  llvm::Type *eltTy, unsigned numElts);
143 
144 /// Minimally split a legal vector type.
145 std::pair<llvm::Type*, unsigned>
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.
153 void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
154  llvm::VectorType *vectorTy,
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.
165 bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record);
166 
167 /// Classify the rules for how to return a particular type.
169 
170 /// Classify the rules for how to pass a particular type.
172 
173 /// Compute the ABI information of a swiftcall function. This is a
174 /// private interface for Clang.
176 
177 /// Is swifterror lowered to a register by the target ABI?
179 
180 } // end namespace swiftcall
181 } // end namespace CodeGen
182 } // end namespace clang
183 
184 #endif
MatchType Type
C Language Family Type Representation.
SourceLocation End
SourceLocation Begin
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Definition: RecordLayout.h:38
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
void addOpaqueData(CharUnits begin, CharUnits end)
std::pair< llvm::StructType *, llvm::Type * > getCoerceAndExpandTypes() const
Return the types for a coerce-and-expand operation.
void enumerateComponents(EnumerationCallback callback) const
Enumerate the expanded components of this type.
llvm::function_ref< void(CharUnits offset, CharUnits end, llvm::Type *type)> EnumerationCallback
bool empty() const
Does this lowering require passing any data?
void addTypedData(QualType type, CharUnits begin)
bool shouldPassIndirectly(bool asReturnValue) const
According to the target Swift ABI, should a value with this lowering be passed indirectly?
Represents a member of a struct/union/class.
Definition: Decl.h:3060
A (possibly-)qualified type.
Definition: Type.h:940
Represents a struct/union/class.
Definition: Decl.h:4171
The base class of the type hierarchy.
Definition: Type.h:1813
bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM)
Is swifterror lowered to a register by the target ABI?
bool shouldPassIndirectly(CodeGenModule &CGM, ArrayRef< llvm::Type * > types, bool asReturnValue)
Should an aggregate which expands to the given type sequence be passed/returned indirectly under swif...
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record)
Is the given record type required to be passed and returned indirectly because of language restrictio...
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type)
Is the given integer type "legal" for Swift's perspective on the current platform?
void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy, llvm::SmallVectorImpl< llvm::Type * > &types)
Turn a vector type in a sequence of legal component vector types.
void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI)
Compute the ABI information of a swiftcall function.
bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy)
Is the given vector type "legal" for Swift's perspective on the current platform?
std::pair< llvm::Type *, unsigned > splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy)
Minimally split a legal vector type.
CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type)
Return the Swift CC's notion of the natural alignment of a type.
CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM)
Return the maximum voluntary integer size for the current target.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
unsigned long uint64_t
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30