Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:52

0001 //==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Defines constants and types related to Swift ABI lowering. The same ABI
0010 // lowering applies to both sync and async functions.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
0015 #define LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
0016 
0017 #include "clang/AST/CanonicalType.h"
0018 #include "clang/AST/CharUnits.h"
0019 #include "clang/AST/Type.h"
0020 #include "llvm/Support/TrailingObjects.h"
0021 #include <cassert>
0022 
0023 namespace llvm {
0024   class IntegerType;
0025   class Type;
0026   class StructType;
0027   class VectorType;
0028 }
0029 
0030 namespace clang {
0031 class FieldDecl;
0032 class ASTRecordLayout;
0033 
0034 namespace CodeGen {
0035 class ABIArgInfo;
0036 class CodeGenModule;
0037 class CGFunctionInfo;
0038 
0039 namespace swiftcall {
0040 
0041 class SwiftAggLowering {
0042   CodeGenModule &CGM;
0043 
0044   struct StorageEntry {
0045     CharUnits Begin;
0046     CharUnits End;
0047     llvm::Type *Type;
0048 
0049     CharUnits getWidth() const {
0050       return End - Begin;
0051     }
0052   };
0053   SmallVector<StorageEntry, 4> Entries;
0054   bool Finished = false;
0055 
0056 public:
0057   SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
0058 
0059   void addOpaqueData(CharUnits begin, CharUnits end) {
0060     addEntry(nullptr, begin, end);
0061   }
0062 
0063   void addTypedData(QualType type, CharUnits begin);
0064   void addTypedData(const RecordDecl *record, CharUnits begin);
0065   void addTypedData(const RecordDecl *record, CharUnits begin,
0066                     const ASTRecordLayout &layout);
0067   void addTypedData(llvm::Type *type, CharUnits begin);
0068   void addTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
0069 
0070   void finish();
0071 
0072   /// Does this lowering require passing any data?
0073   bool empty() const {
0074     assert(Finished && "didn't finish lowering before calling empty()");
0075     return Entries.empty();
0076   }
0077 
0078   /// According to the target Swift ABI, should a value with this lowering
0079   /// be passed indirectly?
0080   ///
0081   /// Note that this decision is based purely on the data layout of the
0082   /// value and does not consider whether the type is address-only,
0083   /// must be passed indirectly to match a function abstraction pattern, or
0084   /// anything else that is expected to be handled by high-level lowering.
0085   ///
0086   /// \param asReturnValue - if true, answer whether it should be passed
0087   ///   indirectly as a return value; if false, answer whether it should be
0088   ///   passed indirectly as an argument
0089   bool shouldPassIndirectly(bool asReturnValue) const;
0090 
0091   using EnumerationCallback =
0092     llvm::function_ref<void(CharUnits offset, CharUnits end, llvm::Type *type)>;
0093 
0094   /// Enumerate the expanded components of this type.
0095   ///
0096   /// The component types will always be legal vector, floating-point,
0097   /// integer, or pointer types.
0098   void enumerateComponents(EnumerationCallback callback) const;
0099 
0100   /// Return the types for a coerce-and-expand operation.
0101   ///
0102   /// The first type matches the memory layout of the data that's been
0103   /// added to this structure, including explicit [N x i8] arrays for any
0104   /// internal padding.
0105   ///
0106   /// The second type removes any internal padding members and, if only
0107   /// one element remains, is simply that element type.
0108   std::pair<llvm::StructType*, llvm::Type*> getCoerceAndExpandTypes() const;
0109 
0110 private:
0111   void addBitFieldData(const FieldDecl *field, CharUnits begin,
0112                        uint64_t bitOffset);
0113   void addLegalTypedData(llvm::Type *type, CharUnits begin, CharUnits end);
0114   void addEntry(llvm::Type *type, CharUnits begin, CharUnits end);
0115   void splitVectorEntry(unsigned index);
0116   static bool shouldMergeEntries(const StorageEntry &first,
0117                                  const StorageEntry &second,
0118                                  CharUnits chunkSize);
0119 };
0120 
0121 /// Should an aggregate which expands to the given type sequence
0122 /// be passed/returned indirectly under swiftcall?
0123 bool shouldPassIndirectly(CodeGenModule &CGM,
0124                           ArrayRef<llvm::Type*> types,
0125                           bool asReturnValue);
0126 
0127 /// Return the maximum voluntary integer size for the current target.
0128 CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);
0129 
0130 /// Return the Swift CC's notion of the natural alignment of a type.
0131 CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type);
0132 
0133 /// Is the given integer type "legal" for Swift's perspective on the
0134 /// current platform?
0135 bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);
0136 
0137 /// Is the given vector type "legal" for Swift's perspective on the
0138 /// current platform?
0139 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
0140                        llvm::VectorType *vectorTy);
0141 bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
0142                        llvm::Type *eltTy, unsigned numElts);
0143 
0144 /// Minimally split a legal vector type.
0145 std::pair<llvm::Type*, unsigned>
0146 splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
0147                      llvm::VectorType *vectorTy);
0148 
0149 /// Turn a vector type in a sequence of legal component vector types.
0150 ///
0151 /// The caller may assume that the sum of the data sizes of the resulting
0152 /// types will equal the data size of the vector type.
0153 void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
0154                         llvm::VectorType *vectorTy,
0155                         llvm::SmallVectorImpl<llvm::Type*> &types);
0156 
0157 /// Is the given record type required to be passed and returned indirectly
0158 /// because of language restrictions?
0159 ///
0160 /// This considers *only* mandatory indirectness due to language restrictions,
0161 /// such as C++'s non-trivially-copyable types and Objective-C's __weak
0162 /// references.  A record for which this returns true may still be passed
0163 /// indirectly for other reasons, such as being too large to fit in a
0164 /// reasonable number of registers.
0165 bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record);
0166 
0167 /// Classify the rules for how to return a particular type.
0168 ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type);
0169 
0170 /// Classify the rules for how to pass a particular type.
0171 ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);
0172 
0173 /// Compute the ABI information of a swiftcall function.  This is a
0174 /// private interface for Clang.
0175 void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
0176 
0177 /// Is swifterror lowered to a register by the target ABI?
0178 bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);
0179 
0180 } // end namespace swiftcall
0181 } // end namespace CodeGen
0182 } // end namespace clang
0183 
0184 #endif