//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
#define LLVM_CLANG_LIB_CODEGEN_ABIINFO_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 clang {
  class ASTContext;
  class TargetInfo;

namespace CodeGen {
  class ABIArgInfo;
  class Address;
  class CGCXXABI;
  class CGFunctionInfo;
  class CodeGenFunction;
  class CodeGenTypes;
  class SwiftABIInfo;

namespace swiftcall {
  class SwiftAggLowering;
}

  // 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 {
  public:
    CodeGen::CodeGenTypes &CGT;
  protected:
    llvm::CallingConv::ID RuntimeCC;
    llvm::CallingConv::ID BuiltinCC;
  public:
    ABIInfo(CodeGen::CodeGenTypes &cgt)
      : CGT(cgt),
        RuntimeCC(llvm::CallingConv::C),
        BuiltinCC(llvm::CallingConv::C) {}

    virtual ~ABIInfo();

    virtual bool supportsSwift() const { return false; }

    CodeGen::CGCXXABI &getCXXABI() const;
    ASTContext &getContext() const;
    llvm::LLVMContext &getVMContext() const;
    const llvm::DataLayout &getDataLayout() const;
    const TargetInfo &getTarget() const;

    /// Return the calling convention to use for system runtime
    /// functions.
    llvm::CallingConv::ID getRuntimeCC() const {
      return RuntimeCC;
    }

    /// Return the calling convention to use for compiler builtins
    llvm::CallingConv::ID getBuiltinCC() const {
      return BuiltinCC;
    }

    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;

    /// 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 shouldSignExtUnsignedType(QualType Ty) const;

    bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
                                uint64_t &Members) 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 ByRef = true,
                            bool Realign = false,
                            llvm::Type *Padding = nullptr) const;

    CodeGen::ABIArgInfo
    getNaturalAlignIndirectInReg(QualType Ty, bool Realign = false) const;


  };

  /// A refining implementation of ABIInfo for targets that support swiftcall.
  ///
  /// If we find ourselves wanting multiple such refinements, they'll probably
  /// be independent refinements, and we should probably find another way
  /// to do it than simple inheritance.
  class SwiftABIInfo : public ABIInfo {
  public:
    SwiftABIInfo(CodeGen::CodeGenTypes &cgt) : ABIInfo(cgt) {}

    bool supportsSwift() const final override { return true; }

    virtual bool shouldPassIndirectlyForSwift(CharUnits totalSize,
                                              ArrayRef<llvm::Type*> types,
                                              bool asReturnValue) const = 0;

    virtual bool isLegalVectorTypeForSwift(CharUnits totalSize,
                                           llvm::Type *eltTy,
                                           unsigned elts) const;

    static bool classof(const ABIInfo *info) {
      return info->supportsSwift();
    }
  };

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

#endif
