1//===----- ABIInfo.h - ABI information access & encapsulation ---*- 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#ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
10#define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
11
12#include "clang/AST/CharUnits.h"
13#include "clang/AST/Type.h"
14#include "llvm/IR/CallingConv.h"
15#include "llvm/IR/Type.h"
16
17namespace llvm {
18  class Value;
19  class LLVMContext;
20  class DataLayout;
21  class Type;
22}
23
24namespace clang {
25  class ASTContext;
26  class CodeGenOptions;
27  class TargetInfo;
28
29namespace CodeGen {
30  class ABIArgInfo;
31  class Address;
32  class CGCXXABI;
33  class CGFunctionInfo;
34  class CodeGenFunction;
35  class CodeGenTypes;
36
37  // FIXME: All of this stuff should be part of the target interface
38  // somehow. It is currently here because it is not clear how to factor
39  // the targets to support this, since the Targets currently live in a
40  // layer below types n'stuff.
41
42
43  /// ABIInfo - Target specific hooks for defining how a type should be
44  /// passed or returned from functions.
45  class ABIInfo {
46  protected:
47    CodeGen::CodeGenTypes &CGT;
48    llvm::CallingConv::ID RuntimeCC;
49  public:
50    ABIInfo(CodeGen::CodeGenTypes &cgt)
51        : CGT(cgt), RuntimeCC(llvm::CallingConv::C) {}
52
53    virtual ~ABIInfo();
54
55    virtual bool allowBFloatArgsAndRet() const { return false; }
56
57    CodeGen::CGCXXABI &getCXXABI() const;
58    ASTContext &getContext() const;
59    llvm::LLVMContext &getVMContext() const;
60    const llvm::DataLayout &getDataLayout() const;
61    const TargetInfo &getTarget() const;
62    const CodeGenOptions &getCodeGenOpts() const;
63
64    /// Return the calling convention to use for system runtime
65    /// functions.
66    llvm::CallingConv::ID getRuntimeCC() const {
67      return RuntimeCC;
68    }
69
70    virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0;
71
72    /// EmitVAArg - Emit the target dependent code to load a value of
73    /// \arg Ty from the va_list pointed to by \arg VAListAddr.
74
75    // FIXME: This is a gaping layering violation if we wanted to drop
76    // the ABI information any lower than CodeGen. Of course, for
77    // VAArg handling it has to be at this level; there is no way to
78    // abstract this out.
79    virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF,
80                                       CodeGen::Address VAListAddr,
81                                       QualType Ty) const = 0;
82
83    bool isAndroid() const;
84
85    /// Emit the target dependent code to load a value of
86    /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr.
87    virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF,
88                                         CodeGen::Address VAListAddr,
89                                         QualType Ty) const;
90
91    virtual bool isHomogeneousAggregateBaseType(QualType Ty) const;
92
93    virtual bool isHomogeneousAggregateSmallEnough(const Type *Base,
94                                                   uint64_t Members) const;
95    virtual bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const;
96
97    bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
98                                uint64_t &Members) const;
99
100    // Implement the Type::IsPromotableIntegerType for ABI specific needs. The
101    // only difference is that this considers bit-precise integer types as well.
102    bool isPromotableIntegerTypeForABI(QualType Ty) const;
103
104    /// A convenience method to return an indirect ABIArgInfo with an
105    /// expected alignment equal to the ABI alignment of the given type.
106    CodeGen::ABIArgInfo
107    getNaturalAlignIndirect(QualType Ty, bool ByVal = true,
108                            bool Realign = false,
109                            llvm::Type *Padding = nullptr) const;
110
111    CodeGen::ABIArgInfo
112    getNaturalAlignIndirectInReg(QualType Ty, bool Realign = false) const;
113  };
114
115  /// Target specific hooks for defining how a type should be passed or returned
116  /// from functions with one of the Swift calling conventions.
117  class SwiftABIInfo {
118  protected:
119    CodeGenTypes &CGT;
120    bool SwiftErrorInRegister;
121
122  public:
123    SwiftABIInfo(CodeGen::CodeGenTypes &CGT, bool SwiftErrorInRegister)
124        : CGT(CGT), SwiftErrorInRegister(SwiftErrorInRegister) {}
125
126    virtual ~SwiftABIInfo();
127
128    /// Returns true if an aggregate which expands to the given type sequence
129    /// should be passed / returned indirectly.
130    virtual bool shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys,
131                                      bool AsReturnValue) const;
132
133    /// Returns true if the given vector type is legal from Swift's calling
134    /// convention perspective.
135    virtual bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
136                                   unsigned NumElts) const;
137
138    /// Returns true if swifterror is lowered to a register by the target ABI.
139    bool isSwiftErrorInRegister() const { return SwiftErrorInRegister; };
140  };
141}  // end namespace CodeGen
142}  // end namespace clang
143
144#endif
145