llvm/clang/include/clang/CodeGen/SwiftCallingConv.h

//==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Defines constants and types related to Swift ABI lowering. The same ABI
// lowering applies to both sync and async functions.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H
#define LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H

#include "clang/AST/CanonicalType.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Type.h"
#include "llvm/Support/TrailingObjects.h"
#include <cassert>

namespace llvm {
  class IntegerType;
  class Type;
  class StructType;
  class VectorType;
}

namespace clang {
class FieldDecl;
class ASTRecordLayout;

namespace CodeGen {
class ABIArgInfo;
class CodeGenModule;
class CGFunctionInfo;

namespace swiftcall {

class SwiftAggLowering {};

/// Should an aggregate which expands to the given type sequence
/// be passed/returned indirectly under swiftcall?
bool shouldPassIndirectly(CodeGenModule &CGM,
                          ArrayRef<llvm::Type*> types,
                          bool asReturnValue);

/// Return the maximum voluntary integer size for the current target.
CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM);

/// Return the Swift CC's notion of the natural alignment of a type.
CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type);

/// Is the given integer type "legal" for Swift's perspective on the
/// current platform?
bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type);

/// Is the given vector type "legal" for Swift's perspective on the
/// current platform?
bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
                       llvm::VectorType *vectorTy);
bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
                       llvm::Type *eltTy, unsigned numElts);

/// Minimally split a legal vector type.
std::pair<llvm::Type*, unsigned>
splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize,
                     llvm::VectorType *vectorTy);

/// Turn a vector type in a sequence of legal component vector types.
///
/// The caller may assume that the sum of the data sizes of the resulting
/// types will equal the data size of the vector type.
void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize,
                        llvm::VectorType *vectorTy,
                        llvm::SmallVectorImpl<llvm::Type*> &types);

/// Is the given record type required to be passed and returned indirectly
/// because of language restrictions?
///
/// This considers *only* mandatory indirectness due to language restrictions,
/// such as C++'s non-trivially-copyable types and Objective-C's __weak
/// references.  A record for which this returns true may still be passed
/// indirectly for other reasons, such as being too large to fit in a
/// reasonable number of registers.
bool mustPassRecordIndirectly(CodeGenModule &CGM, const RecordDecl *record);

/// Classify the rules for how to return a particular type.
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type);

/// Classify the rules for how to pass a particular type.
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type);

/// Compute the ABI information of a swiftcall function.  This is a
/// private interface for Clang.
void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);

/// Is swifterror lowered to a register by the target ABI?
bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM);

} // end namespace swiftcall
} // end namespace CodeGen
} // end namespace clang

#endif