Home | History | Annotate | Line # | Download | only in CodeGen
      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 
     17 namespace llvm {
     18   class Value;
     19   class LLVMContext;
     20   class DataLayout;
     21   class Type;
     22 }
     23 
     24 namespace clang {
     25   class ASTContext;
     26   class CodeGenOptions;
     27   class TargetInfo;
     28 
     29 namespace CodeGen {
     30   class ABIArgInfo;
     31   class Address;
     32   class CGCXXABI;
     33   class CGFunctionInfo;
     34   class CodeGenFunction;
     35   class CodeGenTypes;
     36   class SwiftABIInfo;
     37 
     38 namespace swiftcall {
     39   class SwiftAggLowering;
     40 }
     41 
     42   // FIXME: All of this stuff should be part of the target interface
     43   // somehow. It is currently here because it is not clear how to factor
     44   // the targets to support this, since the Targets currently live in a
     45   // layer below types n'stuff.
     46 
     47 
     48   /// ABIInfo - Target specific hooks for defining how a type should be
     49   /// passed or returned from functions.
     50   class ABIInfo {
     51   public:
     52     CodeGen::CodeGenTypes &CGT;
     53   protected:
     54     llvm::CallingConv::ID RuntimeCC;
     55   public:
     56     ABIInfo(CodeGen::CodeGenTypes &cgt)
     57         : CGT(cgt), RuntimeCC(llvm::CallingConv::C) {}
     58 
     59     virtual ~ABIInfo();
     60 
     61     virtual bool supportsSwift() const { return false; }
     62 
     63     virtual bool allowBFloatArgsAndRet() 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     const CodeGenOptions &getCodeGenOpts() const;
     71 
     72     /// Return the calling convention to use for system runtime
     73     /// functions.
     74     llvm::CallingConv::ID getRuntimeCC() const {
     75       return RuntimeCC;
     76     }
     77 
     78     virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0;
     79 
     80     /// EmitVAArg - Emit the target dependent code to load a value of
     81     /// \arg Ty from the va_list pointed to by \arg VAListAddr.
     82 
     83     // FIXME: This is a gaping layering violation if we wanted to drop
     84     // the ABI information any lower than CodeGen. Of course, for
     85     // VAArg handling it has to be at this level; there is no way to
     86     // abstract this out.
     87     virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF,
     88                                        CodeGen::Address VAListAddr,
     89                                        QualType Ty) const = 0;
     90 
     91     bool isAndroid() const;
     92 
     93     /// Emit the target dependent code to load a value of
     94     /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr.
     95     virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF,
     96                                          CodeGen::Address VAListAddr,
     97                                          QualType Ty) const;
     98 
     99     virtual bool isHomogeneousAggregateBaseType(QualType Ty) const;
    100 
    101     virtual bool isHomogeneousAggregateSmallEnough(const Type *Base,
    102                                                    uint64_t Members) const;
    103 
    104     bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
    105                                 uint64_t &Members) const;
    106 
    107     // Implement the Type::IsPromotableIntegerType for ABI specific needs. The
    108     // only difference is that this considers _ExtInt as well.
    109     bool isPromotableIntegerTypeForABI(QualType Ty) const;
    110 
    111     /// A convenience method to return an indirect ABIArgInfo with an
    112     /// expected alignment equal to the ABI alignment of the given type.
    113     CodeGen::ABIArgInfo
    114     getNaturalAlignIndirect(QualType Ty, bool ByVal = true,
    115                             bool Realign = false,
    116                             llvm::Type *Padding = nullptr) const;
    117 
    118     CodeGen::ABIArgInfo
    119     getNaturalAlignIndirectInReg(QualType Ty, bool Realign = false) const;
    120 
    121 
    122   };
    123 
    124   /// A refining implementation of ABIInfo for targets that support swiftcall.
    125   ///
    126   /// If we find ourselves wanting multiple such refinements, they'll probably
    127   /// be independent refinements, and we should probably find another way
    128   /// to do it than simple inheritance.
    129   class SwiftABIInfo : public ABIInfo {
    130   public:
    131     SwiftABIInfo(CodeGen::CodeGenTypes &cgt) : ABIInfo(cgt) {}
    132 
    133     bool supportsSwift() const final override { return true; }
    134 
    135     virtual bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> types,
    136                                               bool asReturnValue) const = 0;
    137 
    138     virtual bool isLegalVectorTypeForSwift(CharUnits totalSize,
    139                                            llvm::Type *eltTy,
    140                                            unsigned elts) const;
    141 
    142     virtual bool isSwiftErrorInRegister() const = 0;
    143 
    144     static bool classof(const ABIInfo *info) {
    145       return info->supportsSwift();
    146     }
    147   };
    148 }  // end namespace CodeGen
    149 }  // end namespace clang
    150 
    151 #endif
    152