blob: ff4ae44a42c332cf1ba0d6cc8c22826d3b501aa0 [file] [log] [blame]
//===----- ABIInfo.h - ABI information access & encapsulation ---*- 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
#define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
#include "clang/AST/Attr.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Type.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Type.h"
namespace llvm {
class Value;
class LLVMContext;
class DataLayout;
class Type;
} // namespace llvm
namespace clang {
class ASTContext;
class CodeGenOptions;
class TargetInfo;
namespace CodeGen {
class ABIArgInfo;
class Address;
class CGCXXABI;
class CGFunctionInfo;
class CodeGenFunction;
class CodeGenTypes;
// FIXME: All of this stuff should be part of the target interface
// somehow. It is currently here because it is not clear how to factor
// the targets to support this, since the Targets currently live in a
// layer below types n'stuff.
/// ABIInfo - Target specific hooks for defining how a type should be
/// passed or returned from functions.
class ABIInfo {
protected:
CodeGen::CodeGenTypes &CGT;
llvm::CallingConv::ID RuntimeCC;
public:
ABIInfo(CodeGen::CodeGenTypes &cgt)
: CGT(cgt), RuntimeCC(llvm::CallingConv::C) {}
virtual ~ABIInfo();
virtual bool allowBFloatArgsAndRet() const { return false; }
CodeGen::CGCXXABI &getCXXABI() const;
ASTContext &getContext() const;
llvm::LLVMContext &getVMContext() const;
const llvm::DataLayout &getDataLayout() const;
const TargetInfo &getTarget() const;
const CodeGenOptions &getCodeGenOpts() const;
/// Return the calling convention to use for system runtime
/// functions.
llvm::CallingConv::ID getRuntimeCC() const { return RuntimeCC; }
virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0;
/// EmitVAArg - Emit the target dependent code to load a value of
/// \arg Ty from the va_list pointed to by \arg VAListAddr.
// FIXME: This is a gaping layering violation if we wanted to drop
// the ABI information any lower than CodeGen. Of course, for
// VAArg handling it has to be at this level; there is no way to
// abstract this out.
virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF,
CodeGen::Address VAListAddr,
QualType Ty) const = 0;
bool isAndroid() const;
bool isOHOSFamily() const;
/// Emit the target dependent code to load a value of
/// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr.
virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF,
CodeGen::Address VAListAddr,
QualType Ty) const;
virtual bool isHomogeneousAggregateBaseType(QualType Ty) const;
virtual bool isHomogeneousAggregateSmallEnough(const Type *Base,
uint64_t Members) const;
virtual bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const;
/// isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous
/// aggregate. Base is set to the base element type, and Members is set
/// to the number of base elements.
bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
uint64_t &Members) const;
// Implement the Type::IsPromotableIntegerType for ABI specific needs. The
// only difference is that this considers bit-precise integer types as well.
bool isPromotableIntegerTypeForABI(QualType Ty) const;
/// A convenience method to return an indirect ABIArgInfo with an
/// expected alignment equal to the ABI alignment of the given type.
CodeGen::ABIArgInfo
getNaturalAlignIndirect(QualType Ty, bool ByVal = true, bool Realign = false,
llvm::Type *Padding = nullptr) const;
CodeGen::ABIArgInfo getNaturalAlignIndirectInReg(QualType Ty,
bool Realign = false) const;
virtual void appendAttributeMangling(TargetAttr *Attr,
raw_ostream &Out) const;
virtual void appendAttributeMangling(TargetVersionAttr *Attr,
raw_ostream &Out) const;
virtual void appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
raw_ostream &Out) const;
virtual void appendAttributeMangling(StringRef AttrStr,
raw_ostream &Out) const;
};
/// Target specific hooks for defining how a type should be passed or returned
/// from functions with one of the Swift calling conventions.
class SwiftABIInfo {
protected:
CodeGenTypes &CGT;
bool SwiftErrorInRegister;
bool occupiesMoreThan(ArrayRef<llvm::Type *> scalarTypes,
unsigned maxAllRegisters) const;
public:
SwiftABIInfo(CodeGen::CodeGenTypes &CGT, bool SwiftErrorInRegister)
: CGT(CGT), SwiftErrorInRegister(SwiftErrorInRegister) {}
virtual ~SwiftABIInfo();
/// Returns true if an aggregate which expands to the given type sequence
/// should be passed / returned indirectly.
virtual bool shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys,
bool AsReturnValue) const;
/// Returns true if the given vector type is legal from Swift's calling
/// convention perspective.
virtual bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
unsigned NumElts) const;
/// Returns true if swifterror is lowered to a register by the target ABI.
bool isSwiftErrorInRegister() const { return SwiftErrorInRegister; };
};
} // end namespace CodeGen
} // end namespace clang
#endif