1//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
11#define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
12
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 TargetInfo;
27
28namespace CodeGen {
29  class ABIArgInfo;
30  class Address;
31  class CGCXXABI;
32  class CGFunctionInfo;
33  class CodeGenFunction;
34  class CodeGenTypes;
35  class SwiftABIInfo;
36
37namespace swiftcall {
38  class SwiftAggLowering;
39}
40
41  // FIXME: All of this stuff should be part of the target interface
42  // somehow. It is currently here because it is not clear how to factor
43  // the targets to support this, since the Targets currently live in a
44  // layer below types n'stuff.
45
46
47  /// ABIInfo - Target specific hooks for defining how a type should be
48  /// passed or returned from functions.
49  class ABIInfo {
50  public:
51    CodeGen::CodeGenTypes &CGT;
52  protected:
53    llvm::CallingConv::ID RuntimeCC;
54    llvm::CallingConv::ID BuiltinCC;
55  public:
56    ABIInfo(CodeGen::CodeGenTypes &cgt)
57      : CGT(cgt),
58        RuntimeCC(llvm::CallingConv::C),
59        BuiltinCC(llvm::CallingConv::C) {}
60
61    virtual ~ABIInfo();
62
63    virtual bool supportsSwift() const { return false; }
64
65    CodeGen::CGCXXABI &getCXXABI() const;
66    ASTContext &getContext() const;
67    llvm::LLVMContext &getVMContext() const;
68    const llvm::DataLayout &getDataLayout() const;
69    const TargetInfo &getTarget() const;
70
71    /// Return the calling convention to use for system runtime
72    /// functions.
73    llvm::CallingConv::ID getRuntimeCC() const {
74      return RuntimeCC;
75    }
76
77    /// Return the calling convention to use for compiler builtins
78    llvm::CallingConv::ID getBuiltinCC() const {
79      return BuiltinCC;
80    }
81
82    virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0;
83
84    /// EmitVAArg - Emit the target dependent code to load a value of
85    /// \arg Ty from the va_list pointed to by \arg VAListAddr.
86
87    // FIXME: This is a gaping layering violation if we wanted to drop
88    // the ABI information any lower than CodeGen. Of course, for
89    // VAArg handling it has to be at this level; there is no way to
90    // abstract this out.
91    virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF,
92                                       CodeGen::Address VAListAddr,
93                                       QualType Ty) const = 0;
94
95    bool isAndroid() const;
96
97    /// Emit the target dependent code to load a value of
98    /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr.
99    virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF,
100                                         CodeGen::Address VAListAddr,
101                                         QualType Ty) const;
102
103    virtual bool isHomogeneousAggregateBaseType(QualType Ty) const;
104
105    virtual bool isHomogeneousAggregateSmallEnough(const Type *Base,
106                                                   uint64_t Members) const;
107
108    virtual bool shouldSignExtUnsignedType(QualType Ty) const;
109
110    bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
111                                uint64_t &Members) const;
112
113    /// A convenience method to return an indirect ABIArgInfo with an
114    /// expected alignment equal to the ABI alignment of the given type.
115    CodeGen::ABIArgInfo
116    getNaturalAlignIndirect(QualType Ty, bool ByRef = true,
117                            bool Realign = false,
118                            llvm::Type *Padding = nullptr) const;
119
120    CodeGen::ABIArgInfo
121    getNaturalAlignIndirectInReg(QualType Ty, bool Realign = false) const;
122
123
124  };
125
126  /// A refining implementation of ABIInfo for targets that support swiftcall.
127  ///
128  /// If we find ourselves wanting multiple such refinements, they'll probably
129  /// be independent refinements, and we should probably find another way
130  /// to do it than simple inheritance.
131  class SwiftABIInfo : public ABIInfo {
132  public:
133    SwiftABIInfo(CodeGen::CodeGenTypes &cgt) : ABIInfo(cgt) {}
134
135    bool supportsSwift() const final override { return true; }
136
137    virtual bool shouldPassIndirectlyForSwift(CharUnits totalSize,
138                                              ArrayRef<llvm::Type*> types,
139                                              bool asReturnValue) const = 0;
140
141    virtual bool isLegalVectorTypeForSwift(CharUnits totalSize,
142                                           llvm::Type *eltTy,
143                                           unsigned elts) const;
144
145    static bool classof(const ABIInfo *info) {
146      return info->supportsSwift();
147    }
148  };
149
150}  // end namespace CodeGen
151}  // end namespace clang
152
153#endif
154