clang 20.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
23namespace llvm {
24 class IntegerType;
25 class Type;
26 class StructType;
27 class VectorType;
28}
29
30namespace clang {
31class FieldDecl;
32class ASTRecordLayout;
33
34namespace CodeGen {
35class ABIArgInfo;
36class CodeGenModule;
37class CGFunctionInfo;
38
39namespace 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
56public:
57 SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
58
60 addEntry(nullptr, begin, end);
61 }
62
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
110private:
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?
135bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
136
137/// Is the given vector type "legal" for Swift's perspective on the
138/// current platform?
139bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
140 llvm::VectorType *vectorTy);
141bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
142 llvm::Type *eltTy, unsigned numElts);
143
144/// Minimally split a legal vector type.
145std::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.
153void 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.
165bool 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 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:3030
A (possibly-)qualified type.
Definition: Type.h:941
Represents a struct/union/class.
Definition: Decl.h:4141
The base class of the type hierarchy.
Definition: Type.h:1829
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.
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30