//===--- IRGenModule.cpp - Swift Global LLVM IR Generation ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  This file implements IR generation for global declarations in Swift.
//
//===----------------------------------------------------------------------===//

#include "swift/AST/ASTContext.h"
#include "swift/AST/Module.h"
#include "swift/AST/DiagnosticsIRGen.h"
#include "swift/AST/IRGenOptions.h"
#include "swift/Basic/Dwarf.h"
#include "swift/Basic/ManglingMacros.h"
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/Runtime/RuntimeFnWrappersGen.h"
#include "swift/Runtime/Config.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CodeGenABITypes.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/CodeGen/SwiftCallingConv.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MD5.h"

#include "GenEnum.h"
#include "GenType.h"
#include "IRGenModule.h"
#include "IRGenDebugInfo.h"
#include "Linking.h"

#include <initializer_list>

using namespace swift;
using namespace irgen;
using llvm::Attribute;

const unsigned DefaultAS = 0;

/// A helper for creating LLVM struct types.
static llvm::StructType *createStructType(IRGenModule &IGM,
                                          StringRef name,
                                  std::initializer_list<llvm::Type*> types) {
  return llvm::StructType::create(IGM.getLLVMContext(),
                                  ArrayRef<llvm::Type*>(types.begin(),
                                                        types.size()),
                                  name);
};

/// A helper for creating pointer-to-struct types.
static llvm::PointerType *createStructPointerType(IRGenModule &IGM,
                                                  StringRef name,
                                  std::initializer_list<llvm::Type*> types) {
  return createStructType(IGM, name, types)->getPointerTo(DefaultAS);
};

static clang::CodeGenerator *createClangCodeGenerator(ASTContext &Context,
                                                 llvm::LLVMContext &LLVMContext,
                                                      IRGenOptions &Opts,
                                                      StringRef ModuleName) {
  auto Loader = Context.getClangModuleLoader();
  auto *Importer = static_cast<ClangImporter*>(&*Loader);
  assert(Importer && "No clang module loader!");
  auto &ClangContext = Importer->getClangASTContext();

  auto &CGO = Importer->getClangCodeGenOpts();
  CGO.OptimizationLevel = Opts.Optimize ? 3 : 0;
  CGO.DisableFPElim = Opts.DisableFPElim;
  CGO.DiscardValueNames = !Opts.shouldProvideValueNames();
  switch (Opts.DebugInfoKind) {
  case IRGenDebugInfoKind::None:
    CGO.setDebugInfo(clang::codegenoptions::DebugInfoKind::NoDebugInfo);
    break;
  case IRGenDebugInfoKind::LineTables:
    CGO.setDebugInfo(clang::codegenoptions::DebugInfoKind::DebugLineTablesOnly);
    break;
  case IRGenDebugInfoKind::ASTTypes:
    // TODO: Enable -gmodules for the clang code generator.
  case IRGenDebugInfoKind::DwarfTypes:
    CGO.setDebugInfo(clang::codegenoptions::DebugInfoKind::FullDebugInfo);
    break;
  }
  if (Opts.DebugInfoKind > IRGenDebugInfoKind::None) {
    CGO.DebugCompilationDir = Opts.DebugCompilationDir;
    CGO.DwarfVersion = Opts.DWARFVersion;
    CGO.DwarfDebugFlags = Opts.DWARFDebugFlags;
  }

  auto &HSI = Importer->getClangPreprocessor()
                  .getHeaderSearchInfo()
                  .getHeaderSearchOpts();
  auto &PPO = Importer->getClangPreprocessor().getPreprocessorOpts();
  auto *ClangCodeGen = clang::CreateLLVMCodeGen(ClangContext.getDiagnostics(),
                                                ModuleName, HSI, PPO, CGO,
                                                LLVMContext);
  ClangCodeGen->Initialize(ClangContext);
  return ClangCodeGen;
}

/// A helper for determining if the triple uses the DLL storage
static bool useDllStorage(const llvm::Triple &Triple) {
  return Triple.isOSBinFormatCOFF() && !Triple.isOSCygMing();
}

IRGenModule::IRGenModule(IRGenerator &irgen,
                         std::unique_ptr<llvm::TargetMachine> &&target,
                         SourceFile *SF, llvm::LLVMContext &LLVMContext,
                         StringRef ModuleName, StringRef OutputFilename)
    : IRGen(irgen), Context(irgen.SIL.getASTContext()),
      ClangCodeGen(createClangCodeGenerator(Context, LLVMContext, irgen.Opts,
                                            ModuleName)),
      Module(*ClangCodeGen->GetModule()), LLVMContext(Module.getContext()),
      DataLayout(target->createDataLayout()), Triple(Context.LangOpts.Target),
      TargetMachine(std::move(target)), silConv(irgen.SIL),
      OutputFilename(OutputFilename),
#ifndef NDEBUG
      EligibleConfs(getSILModule()),
#endif
      TargetInfo(SwiftTargetInfo::get(*this)), DebugInfo(nullptr),
      ModuleHash(nullptr), ObjCInterop(Context.LangOpts.EnableObjCInterop),
      Types(*new TypeConverter(*this)) {
  irgen.addGenModule(SF, this);

  auto &opts = irgen.Opts;

  EnableValueNames = opts.shouldProvideValueNames();
  
  VoidTy = llvm::Type::getVoidTy(getLLVMContext());
  Int1Ty = llvm::Type::getInt1Ty(getLLVMContext());
  Int8Ty = llvm::Type::getInt8Ty(getLLVMContext());
  Int16Ty = llvm::Type::getInt16Ty(getLLVMContext());
  Int32Ty = llvm::Type::getInt32Ty(getLLVMContext());
  Int64Ty = llvm::Type::getInt64Ty(getLLVMContext());
  Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
  Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
  SizeTy = DataLayout.getIntPtrType(getLLVMContext(), /*addrspace*/ 0);

  auto CI = static_cast<ClangImporter*>(&*Context.getClangModuleLoader());
  assert(CI && "no clang module loader");
  auto &clangASTContext = CI->getClangASTContext();

  ObjCBoolTy = Int1Ty;
  if (clangASTContext.getTargetInfo().useSignedCharForObjCBool())
    ObjCBoolTy = Int8Ty;

  RefCountedStructTy =
    llvm::StructType::create(getLLVMContext(), "swift.refcounted");
  RefCountedPtrTy = RefCountedStructTy->getPointerTo(/*addrspace*/ 0);
  RefCountedNull = llvm::ConstantPointerNull::get(RefCountedPtrTy);

  // For now, native weak references are just a pointer.
  WeakReferencePtrTy =
    createStructPointerType(*this, "swift.weak", { RefCountedPtrTy });

  // Native unowned references are just a pointer.
  UnownedReferencePtrTy =
    createStructPointerType(*this, "swift.unowned", { RefCountedPtrTy });

  // A type metadata record is the structure pointed to by the canonical
  // address point of a type metadata.  This is at least one word, and
  // potentially more than that, past the start of the actual global
  // structure.
  TypeMetadataStructTy = createStructType(*this, "swift.type", {
    MetadataKindTy          // MetadataKind Kind;
  });
  TypeMetadataPtrTy = TypeMetadataStructTy->getPointerTo(DefaultAS);

  // A protocol descriptor describes a protocol. It is not type metadata in
  // and of itself, but is referenced in the structure of existential type
  // metadata records.
  ProtocolDescriptorStructTy = createStructType(*this, "swift.protocol", {
    Int8PtrTy,              // objc isa
    Int8PtrTy,              // name
    Int8PtrTy,              // inherited protocols
    Int8PtrTy,              // required objc instance methods
    Int8PtrTy,              // required objc class methods
    Int8PtrTy,              // optional objc instance methods
    Int8PtrTy,              // optional objc class methods
    Int8PtrTy,              // objc properties
    Int32Ty,                // size
    Int32Ty,                // flags
    Int16Ty,                // minimum witness count
    Int16Ty,                // default witness count
    Int32Ty                 // padding
  });
  
  ProtocolDescriptorPtrTy = ProtocolDescriptorStructTy->getPointerTo();
  
  // A tuple type metadata record has a couple extra fields.
  auto tupleElementTy = createStructType(*this, "swift.tuple_element_type", {
    TypeMetadataPtrTy,      // Metadata *Type;
    SizeTy                  // size_t Offset;
  });
  TupleTypeMetadataPtrTy = createStructPointerType(*this, "swift.tuple_type", {
    TypeMetadataStructTy,   // (base)
    SizeTy,                 // size_t NumElements;
    Int8PtrTy,              // const char *Labels;
    llvm::ArrayType::get(tupleElementTy, 0) // Element Elements[];
  });

  // A full type metadata record is basically just an adjustment to the
  // address point of a type metadata.  Resilience may cause
  // additional data to be laid out prior to this address point.
  FullTypeMetadataStructTy = createStructType(*this, "swift.full_type", {
    WitnessTablePtrTy,
    TypeMetadataStructTy
  });
  FullTypeMetadataPtrTy = FullTypeMetadataStructTy->getPointerTo(DefaultAS);

  // A metadata pattern is a structure from which generic type
  // metadata are allocated.  We leave this struct type intentionally
  // opaque, because the compiler basically never needs to access
  // anything from one.
  TypeMetadataPatternStructTy =
    llvm::StructType::create(getLLVMContext(), "swift.type_pattern");
  TypeMetadataPatternPtrTy =
    TypeMetadataPatternStructTy->getPointerTo(DefaultAS);

  DeallocatingDtorTy = llvm::FunctionType::get(VoidTy, RefCountedPtrTy, false);
  llvm::Type *dtorPtrTy = DeallocatingDtorTy->getPointerTo();

  // A full heap metadata is basically just an additional small prefix
  // on a full metadata, used for metadata corresponding to heap
  // allocations.
  FullHeapMetadataStructTy =
                  createStructType(*this, "swift.full_heapmetadata", {
    dtorPtrTy,
    WitnessTablePtrTy,
    TypeMetadataStructTy
  });
  FullHeapMetadataPtrTy = FullHeapMetadataStructTy->getPointerTo(DefaultAS);

  // A full box metadata is non-type heap metadata for a heap allocation of a
  // single value. The box tracks the offset to the value inside the box.
  FullBoxMetadataStructTy =
                  createStructType(*this, "swift.full_boxmetadata", {
    dtorPtrTy,
    WitnessTablePtrTy,
    TypeMetadataStructTy,
    Int32Ty,
    CaptureDescriptorPtrTy,
  });
  FullBoxMetadataPtrTy = FullBoxMetadataStructTy->getPointerTo(DefaultAS);


  llvm::Type *refCountedElts[] = { TypeMetadataPtrTy, Int32Ty, Int32Ty };
  RefCountedStructTy->setBody(refCountedElts);

  PtrSize = Size(DataLayout.getPointerSize(DefaultAS));

  FunctionPairTy = createStructType(*this, "swift.function", {
    FunctionPtrTy,
    RefCountedPtrTy,
  });
  
  OpaquePtrTy = llvm::StructType::create(LLVMContext, "swift.opaque")
                  ->getPointerTo(DefaultAS);

  ProtocolConformanceRecordTy
    = createStructType(*this, "swift.protocol_conformance", {
      RelativeAddressTy,
      RelativeAddressTy,
      RelativeAddressTy,
      Int32Ty
    });
  ProtocolConformanceRecordPtrTy
    = ProtocolConformanceRecordTy->getPointerTo(DefaultAS);

  NominalTypeDescriptorTy
    = llvm::StructType::create(LLVMContext, "swift.type_descriptor");
  NominalTypeDescriptorPtrTy
    = NominalTypeDescriptorTy->getPointerTo(DefaultAS);

  TypeMetadataRecordTy
    = createStructType(*this, "swift.type_metadata_record", {
      RelativeAddressTy,
      Int32Ty
    });
  TypeMetadataRecordPtrTy
    = TypeMetadataRecordTy->getPointerTo(DefaultAS);

  FieldDescriptorTy
    = llvm::StructType::create(LLVMContext, "swift.field_descriptor");
  FieldDescriptorPtrTy = FieldDescriptorTy->getPointerTo(DefaultAS);

  FixedBufferTy = nullptr;
  for (unsigned i = 0; i != MaxNumValueWitnesses; ++i)
    ValueWitnessTys[i] = nullptr;

  ObjCPtrTy = llvm::StructType::create(getLLVMContext(), "objc_object")
                ->getPointerTo(DefaultAS);
  BridgeObjectPtrTy = llvm::StructType::create(getLLVMContext(), "swift.bridge")
                ->getPointerTo(DefaultAS);

  ObjCClassStructTy = llvm::StructType::create(LLVMContext, "objc_class");
  ObjCClassPtrTy = ObjCClassStructTy->getPointerTo(DefaultAS);
  llvm::Type *objcClassElts[] = {
    ObjCClassPtrTy,
    ObjCClassPtrTy,
    OpaquePtrTy,
    OpaquePtrTy,
    IntPtrTy
  };
  ObjCClassStructTy->setBody(objcClassElts);

  ObjCSuperStructTy = llvm::StructType::create(LLVMContext, "objc_super");
  ObjCSuperPtrTy = ObjCSuperStructTy->getPointerTo(DefaultAS);
  llvm::Type *objcSuperElts[] = {
    ObjCPtrTy,
    ObjCClassPtrTy
  };
  ObjCSuperStructTy->setBody(objcSuperElts);
  
  ObjCBlockStructTy = llvm::StructType::create(LLVMContext, "objc_block");
  ObjCBlockPtrTy = ObjCBlockStructTy->getPointerTo(DefaultAS);
  llvm::Type *objcBlockElts[] = {
    ObjCClassPtrTy, // isa
    Int32Ty,        // flags
    Int32Ty,        // reserved
    FunctionPtrTy,  // invoke function pointer
    Int8PtrTy,      // TODO: block descriptor pointer.
                    // We will probably need a struct type for that at some
                    // point too.
  };
  ObjCBlockStructTy->setBody(objcBlockElts);
  
  auto ErrorStructTy = llvm::StructType::create(LLVMContext, "swift.error");
  // ErrorStruct is currently opaque to the compiler.
  ErrorPtrTy = ErrorStructTy->getPointerTo(DefaultAS);
  
  llvm::Type *openedErrorTriple[] = {
    OpaquePtrTy,
    TypeMetadataPtrTy,
    WitnessTablePtrTy,
  };
  OpenedErrorTripleTy = llvm::StructType::get(getLLVMContext(),
                                              openedErrorTriple,
                                              /*packed*/ false);
  OpenedErrorTriplePtrTy = OpenedErrorTripleTy->getPointerTo(DefaultAS);
  
  InvariantMetadataID = LLVMContext.getMDKindID("invariant.load");
  InvariantNode = llvm::MDNode::get(LLVMContext, {});
  DereferenceableID = LLVMContext.getMDKindID("dereferenceable");
  
  C_CC = llvm::CallingConv::C;
  // TODO: use "tinycc" on platforms that support it
  DefaultCC = SWIFT_LLVM_CC(DefaultCC);
  // If it is an interpreter, don't use try to use any
  // advanced calling conventions and use instead a
  // more conservative C calling convention. This
  // makes sure that none of the registers eventually
  // used by the dynamic linker are used by generated code.
  // TODO: Check that the deployment target supports the new
  // calling convention. Older versions of the runtime library
  // may not contain the entries using the new calling convention.

  // Only use the new calling conventions on platforms that support it.
  auto Arch = Triple.getArch();
  (void)Arch;
  if (SWIFT_RT_USE_RegisterPreservingCC &&
      Arch == llvm::Triple::ArchType::aarch64)
    RegisterPreservingCC = SWIFT_LLVM_CC(RegisterPreservingCC);
  else
    RegisterPreservingCC = DefaultCC;

  SwiftCC = SWIFT_LLVM_CC(SwiftCC);
  UseSwiftCC = (SwiftCC == llvm::CallingConv::Swift);

  if (IRGen.Opts.DebugInfoKind > IRGenDebugInfoKind::None)
    DebugInfo = new IRGenDebugInfo(IRGen.Opts, *CI, *this, Module, SF);

  initClangTypeConverter();

  IsSwiftErrorInRegister =
    clang::CodeGen::swiftcall::isSwiftErrorLoweredInRegister(
      ClangCodeGen->CGM());
}

IRGenModule::~IRGenModule() {
  destroyClangTypeConverter();
  delete &Types;
  delete DebugInfo;
}

static bool isReturnAttribute(llvm::Attribute::AttrKind Attr);

// Explicitly listing these constants is an unfortunate compromise for
// making the database file much more compact.
//
// They have to be non-local because otherwise we'll get warnings when
// a particular x-macro expansion doesn't use one.
namespace RuntimeConstants {
  const auto ReadNone = llvm::Attribute::ReadNone;
  const auto ReadOnly = llvm::Attribute::ReadOnly;
  const auto NoReturn = llvm::Attribute::NoReturn;
  const auto NoUnwind = llvm::Attribute::NoUnwind;
  const auto ZExt = llvm::Attribute::ZExt;
} // namespace RuntimeConstants

// We don't use enough attributes to justify generalizing the
// RuntimeFunctions.def FUNCTION macro. Instead, special case the one attribute
// associated with the return type not the function type.
static bool isReturnAttribute(llvm::Attribute::AttrKind Attr) {
  return Attr == llvm::Attribute::ZExt;
}

llvm::Constant *swift::getRuntimeFn(llvm::Module &Module,
                      llvm::Constant *&cache,
                      char const *name,
                      llvm::CallingConv::ID cc,
                      llvm::ArrayRef<llvm::Type*> retTypes,
                      llvm::ArrayRef<llvm::Type*> argTypes,
                      ArrayRef<Attribute::AttrKind> attrs) {
  if (cache)
    return cache;
  
  llvm::Type *retTy;
  if (retTypes.size() == 1)
    retTy = *retTypes.begin();
  else
    retTy = llvm::StructType::get(Module.getContext(),
                                  {retTypes.begin(), retTypes.end()},
                                  /*packed*/ false);
  auto fnTy = llvm::FunctionType::get(retTy,
                                      {argTypes.begin(), argTypes.end()},
                                      /*isVararg*/ false);

  cache = Module.getOrInsertFunction(name, fnTy);

  // Add any function attributes and set the calling convention.
  if (auto fn = dyn_cast<llvm::Function>(cache)) {
    fn->setCallingConv(cc);

    if (::useDllStorage(llvm::Triple(Module.getTargetTriple())) &&
        (fn->getLinkage() == llvm::GlobalValue::ExternalLinkage ||
         fn->getLinkage() == llvm::GlobalValue::AvailableExternallyLinkage))
      fn->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);

    llvm::AttrBuilder buildFnAttr;
    llvm::AttrBuilder buildRetAttr;

    for (auto Attr : attrs) {
      if (isReturnAttribute(Attr))
        buildRetAttr.addAttribute(Attr);
      else
        buildFnAttr.addAttribute(Attr);
    }
    // FIXME: getting attributes here without setting them does
    // nothing. This cannot be fixed until the attributes are correctly specified.
    fn->getAttributes().
      addAttributes(Module.getContext(),
                    llvm::AttributeSet::FunctionIndex,
                    llvm::AttributeSet::get(Module.getContext(),
                                            llvm::AttributeSet::FunctionIndex,
                                            buildFnAttr));
    fn->getAttributes().
      addAttributes(Module.getContext(),
                    llvm::AttributeSet::ReturnIndex,
                    llvm::AttributeSet::get(Module.getContext(),
                                            llvm::AttributeSet::ReturnIndex,
                                            buildRetAttr));
  }

  return cache;
}

llvm::Constant *swift::getWrapperFn(llvm::Module &Module,
                                    llvm::Constant *&cache,
                                    char const *name,
                                    char const *symbol,
                                    llvm::CallingConv::ID cc,
                                    llvm::ArrayRef<llvm::Type *> retTypes,
                                    llvm::ArrayRef<llvm::Type *> argTypes,
                                    ArrayRef<Attribute::AttrKind> attrs) {
  assert(symbol && "Symbol name should be defined for a wrapper function");
  // Wrapper names should have a prefix to distinguish them from the
  // actual runtime functions.
  llvm::SmallString<128> wrapperNameStr;
  llvm::raw_svector_ostream buffer(wrapperNameStr);
  buffer << SWIFT_WRAPPER_PREFIX;
  buffer << name;
  const char *wrapperName = wrapperNameStr.c_str();
  auto fn = getRuntimeFn(Module, cache, wrapperName, cc,
                         retTypes, argTypes, attrs);
  auto *fun = dyn_cast<llvm::Function>(fn);
  assert(fun && "Wrapper should be an llvm::Function");
  // Do not inline wrappers, because this would result in a code size increase.
  fun->addAttribute(llvm::AttributeSet::FunctionIndex,
                    llvm::Attribute::NoInline);
  assert(fun->hasFnAttribute(llvm::Attribute::NoInline) &&
         "Wrappers should not be inlined");
  if (fun->empty()) {
    // All wrappers should have ODR linkage so that a linker can detect them
    // and leave only one copy.
    fun->setLinkage(llvm::Function::LinkOnceODRLinkage);
    fun->setVisibility(llvm::Function::HiddenVisibility);
    fun->setDLLStorageClass(llvm::Function::DefaultStorageClass);
    fun->setDoesNotThrow();

    // Add the body of a wrapper.
    // It simply invokes the actual implementation of the runtime entry
    // by means of indirect call through a pointer stored in the
    // global variable.
    llvm::IRBuilder<> Builder(Module.getContext());
    llvm::BasicBlock *bb =
        llvm::BasicBlock::Create(Module.getContext(), "entry", fun);
    Builder.SetInsertPoint(bb);
    auto fnTy = fun->getFunctionType();
    auto fnPtrTy = llvm::PointerType::getUnqual(fnTy);

    auto *globalFnPtr = new llvm::GlobalVariable(
        Module, fnPtrTy, false, llvm::GlobalValue::ExternalLinkage, nullptr,
        symbol);
    if (::useDllStorage(llvm::Triple(Module.getTargetTriple())))
      globalFnPtr->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);

    // Forward all arguments.
    llvm::SmallVector<llvm::Value *, 4> args;
    for (auto &arg: fun->args()) {
      args.push_back(&arg);
    }


    auto fnPtr = Builder.CreateLoad(globalFnPtr, "load");
    auto call = Builder.CreateCall(fnPtr, args);
    call->setCallingConv(cc);
    call->setTailCall(true);

    auto VoidTy = llvm::Type::getVoidTy(Module.getContext());
    if (retTypes.size() == 1 && *retTypes.begin() == VoidTy)
      Builder.CreateRetVoid();
    else
      Builder.CreateRet(call);
  }

  return fn;
}

#define QUOTE(...) __VA_ARGS__
#define STR(X)     #X

#define FUNCTION_FOR_CONV_DefaultCC(ID, NAME, CC, RETURNS, ARGS, ATTRS)        \
  FUNCTION_IMPL(ID, NAME, CC, QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS))

#define FUNCTION_FOR_CONV_C_CC(ID, NAME, CC, RETURNS, ARGS, ATTRS)             \
  FUNCTION_IMPL(ID, NAME, CC, QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS))

#define FUNCTION_FOR_CONV_RegisterPreservingCC(ID, NAME, CC, RETURNS, ARGS,    \
                                               ATTRS)                          \
  FUNCTION_WITH_GLOBAL_SYMBOL_IMPL(ID, NAME, SWIFT_RT_ENTRY_REF(NAME), CC,     \
                                   QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS))

#define FUNCTION(ID, NAME, CC, RETURNS, ARGS, ATTRS)                           \
  FUNCTION_FOR_CONV_##CC(ID, NAME, CC, QUOTE(RETURNS), QUOTE(ARGS),            \
                         QUOTE(ATTRS))

#define FUNCTION_WITH_GLOBAL_SYMBOL_FOR_CONV_DefaultCC(ID, NAME, SYMBOL, CC,   \
                                                       RETURNS, ARGS, ATTRS)   \
  FUNCTION_IMPL(ID, NAME, CC, QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS))

#define FUNCTION_WITH_GLOBAL_SYMBOL_FOR_CONV_C_CC(ID, NAME, SYMBOL, CC,        \
                                                  RETURNS, ARGS, ATTRS)        \
  FUNCTION_IMPL(ID, NAME, CC, QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS))

#define FUNCTION_WITH_GLOBAL_SYMBOL_FOR_CONV_RegisterPreservingCC(             \
    ID, NAME, SYMBOL, CC, RETURNS, ARGS, ATTRS)                                \
  FUNCTION_WITH_GLOBAL_SYMBOL_IMPL(ID, NAME, SYMBOL, CC, QUOTE(RETURNS),       \
                                   QUOTE(ARGS), QUOTE(ATTRS))

#define FUNCTION_WITH_GLOBAL_SYMBOL_AND_IMPL(ID, NAME, SYMBOL, IMPL, CC,       \
                                             RETURNS, ARGS, ATTRS)             \
  FUNCTION_WITH_GLOBAL_SYMBOL_FOR_CONV_##CC(                                   \
      ID, NAME, SYMBOL, CC, QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS))

#define RETURNS(...)                                                           \
  { __VA_ARGS__ }
#define ARGS(...) { __VA_ARGS__ }
#define NO_ARGS {}
#define ATTRS(...) { __VA_ARGS__ }
#define NO_ATTRS {}

#define FUNCTION_IMPL(ID, NAME, CC, RETURNS, ARGS, ATTRS)                      \
  llvm::Constant *IRGenModule::get##ID##Fn() {                                 \
    using namespace RuntimeConstants;                                          \
    return getRuntimeFn(Module, ID##Fn, #NAME, CC, RETURNS, ARGS, ATTRS);      \
  }

#define FUNCTION_WITH_GLOBAL_SYMBOL_IMPL(ID, NAME, SYMBOL_NAME, CC, RETURNS,   \
                                         ARGS, ATTRS)                          \
  llvm::Constant *IRGenModule::get##ID##Fn() {                                 \
    using namespace RuntimeConstants;                                          \
    return getWrapperFn(Module, ID##Fn, #NAME, STR(SYMBOL_NAME), CC, RETURNS,  \
                        ARGS, ATTRS);                                          \
  }

#include "swift/Runtime/RuntimeFunctions.def"

std::pair<llvm::GlobalVariable *, llvm::Constant *>
IRGenModule::createStringConstant(StringRef Str,
  bool willBeRelativelyAddressed, StringRef sectionName) {
  // If not, create it.  This implicitly adds a trailing null.
  auto init = llvm::ConstantDataArray::getString(LLVMContext, Str);
  auto global = new llvm::GlobalVariable(Module, init->getType(), true,
                                         llvm::GlobalValue::PrivateLinkage,
                                         init);
  // FIXME: ld64 crashes resolving relative references to coalesceable symbols.
  // rdar://problem/22674524
  // If we intend to relatively address this string, don't mark it with
  // unnamed_addr to prevent it from going into the cstrings section and getting
  // coalesced.
  if (!willBeRelativelyAddressed)
    global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

  if (!sectionName.empty())
    global->setSection(sectionName);

  // Drill down to make an i8*.
  auto zero = llvm::ConstantInt::get(SizeTy, 0);
  llvm::Constant *indices[] = { zero, zero };
  auto address = llvm::ConstantExpr::getInBoundsGetElementPtr(
    global->getValueType(), global, indices);

  return { global, address };
}

llvm::Constant *IRGenModule::getEmptyTupleMetadata() {
  if (EmptyTupleMetadata)
    return EmptyTupleMetadata;

  EmptyTupleMetadata = Module.getOrInsertGlobal(
                          MANGLE_AS_STRING(METADATA_SYM(EMPTY_TUPLE_MANGLING)),
                          FullTypeMetadataStructTy);
  if (useDllStorage())
    cast<llvm::GlobalVariable>(EmptyTupleMetadata)
        ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
  return EmptyTupleMetadata;
}

llvm::Constant *IRGenModule::getObjCEmptyCachePtr() {
  if (ObjCEmptyCachePtr)
    return ObjCEmptyCachePtr;

  if (ObjCInterop) {
    // struct objc_cache _objc_empty_cache;
    ObjCEmptyCachePtr = Module.getOrInsertGlobal("_objc_empty_cache",
                                                 OpaquePtrTy->getElementType());
    if (useDllStorage())
      cast<llvm::GlobalVariable>(ObjCEmptyCachePtr)
          ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
  } else {
    // FIXME: Remove even the null value per rdar://problem/18801263
    ObjCEmptyCachePtr = llvm::ConstantPointerNull::get(OpaquePtrTy);
  }
  return ObjCEmptyCachePtr;
}

llvm::Constant *IRGenModule::getObjCEmptyVTablePtr() {
  // IMP _objc_empty_vtable;

  // On recent Darwin platforms, this symbol is defined at
  // runtime as an absolute symbol with the value of null. Older ObjCs
  // didn't guarantee _objc_empty_vtable to be nil, but Swift doesn't
  // deploy far enough back for that to be a concern.

  // FIXME: When !ObjCInterop, we should remove even the null value per
  // rdar://problem/18801263

  if (!ObjCEmptyVTablePtr)
    ObjCEmptyVTablePtr = llvm::ConstantPointerNull::get(OpaquePtrTy);

  return ObjCEmptyVTablePtr;
}

Address IRGenModule::getAddrOfObjCISAMask() {
  // This symbol is only exported by the runtime if the platform uses
  // isa masking.
  assert(TargetInfo.hasISAMasking());
  if (!ObjCISAMaskPtr) {
    ObjCISAMaskPtr = Module.getOrInsertGlobal("swift_isaMask", IntPtrTy);
    if (useDllStorage())
      cast<llvm::GlobalVariable>(ObjCISAMaskPtr)
          ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
  }
  return Address(ObjCISAMaskPtr, getPointerAlignment());
}

ModuleDecl *IRGenModule::getSwiftModule() const {
  return IRGen.SIL.getSwiftModule();
}

Lowering::TypeConverter &IRGenModule::getSILTypes() const {
  return IRGen.SIL.Types;
}

llvm::Module *IRGenModule::getModule() const {
  return ClangCodeGen->GetModule();
}

llvm::Module *IRGenModule::releaseModule() {
  return ClangCodeGen->ReleaseModule();
}

llvm::AttributeSet IRGenModule::getAllocAttrs() {
  if (AllocAttrs.isEmpty()) {
    AllocAttrs = llvm::AttributeSet::get(LLVMContext,
                                         llvm::AttributeSet::ReturnIndex,
                                         llvm::Attribute::NoAlias);
    AllocAttrs = AllocAttrs.addAttribute(LLVMContext,
                               llvm::AttributeSet::FunctionIndex,
                               llvm::Attribute::NoUnwind);
  }
  return AllocAttrs;
}

/// Construct initial attributes from options.
llvm::AttributeSet IRGenModule::constructInitialAttributes() {
  llvm::AttributeSet attrsUpdated;
  // Add DisableFPElim. 
  if (!IRGen.Opts.DisableFPElim) {
    attrsUpdated = attrsUpdated.addAttribute(LLVMContext,
                     llvm::AttributeSet::FunctionIndex,
                     "no-frame-pointer-elim", "false");
  } else {
    attrsUpdated = attrsUpdated.addAttribute(
        LLVMContext, llvm::AttributeSet::FunctionIndex,
        "no-frame-pointer-elim", "true");
    attrsUpdated = attrsUpdated.addAttribute(
        LLVMContext, llvm::AttributeSet::FunctionIndex,
        "no-frame-pointer-elim-non-leaf");
  }

  // Add target-cpu and target-features if they are non-null.
  auto *Clang = static_cast<ClangImporter *>(Context.getClangModuleLoader());
  clang::TargetOptions &ClangOpts = Clang->getTargetInfo().getTargetOpts();

  std::string &CPU = ClangOpts.CPU;
  if (CPU != "")
    attrsUpdated = attrsUpdated.addAttribute(LLVMContext,
                     llvm::AttributeSet::FunctionIndex, "target-cpu", CPU);

  std::vector<std::string> &Features = ClangOpts.Features;
  if (!Features.empty()) {
    SmallString<64> allFeatures;
    interleave(Features, [&](const std::string &s) {
      allFeatures.append(s);
    }, [&]{
      allFeatures.push_back(',');
    });
    attrsUpdated = attrsUpdated.addAttribute(LLVMContext,
                     llvm::AttributeSet::FunctionIndex, "target-features",
                     allFeatures);
  }
  return attrsUpdated;
}

llvm::Constant *IRGenModule::getSize(Size size) {
  return llvm::ConstantInt::get(SizeTy, size.getValue());
}

static void appendEncodedName(raw_ostream &os, StringRef name) {
  if (clang::isValidIdentifier(name)) {
    os << "_" << name;
  } else {
    for (auto c : name)
      os.write_hex(static_cast<uint8_t>(c));
  }
}

static void appendEncodedName(llvm::SmallVectorImpl<char> &buf,
                              StringRef name) {
  llvm::raw_svector_ostream os{buf};
  appendEncodedName(os, name);
}

static StringRef encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
                                           StringRef name) {
  llvm::raw_svector_ostream os{buf};
  os << "_swift_FORCE_LOAD_$";
  appendEncodedName(os, name);
  return os.str();
}

llvm::SmallString<32> getTargetDependentLibraryOption(const llvm::Triple &T,
                                                      StringRef library) {
  llvm::SmallString<32> buffer;

  if (T.isWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {
    bool quote = library.find(' ') != StringRef::npos;

    buffer += "/DEFAULTLIB:";
    if (quote)
      buffer += '"';
    buffer += library;
    if (!library.endswith_lower(".lib"))
      buffer += ".lib";
    if (quote)
      buffer += '"';
  } else if (T.isPS4()) {
    bool quote = library.find(' ') != StringRef::npos;

    buffer += "\01";
    if (quote)
      buffer += '"';
    buffer += library;
    if (quote)
      buffer += '"';
  } else {
    buffer += "-l";
    buffer += library;
  }

  return buffer;
}

void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) {
  llvm::LLVMContext &ctx = Module.getContext();

  switch (linkLib.getKind()) {
  case LibraryKind::Library: {
    llvm::SmallString<32> opt =
        getTargetDependentLibraryOption(Triple, linkLib.getName());
    AutolinkEntries.push_back(
        llvm::MDNode::get(ctx, llvm::MDString::get(ctx, opt)));
    break;
  }
  case LibraryKind::Framework: {
    // If we're supposed to disable autolinking of this framework, bail out.
    auto &frameworks = IRGen.Opts.DisableAutolinkFrameworks;
    if (std::find(frameworks.begin(), frameworks.end(), linkLib.getName())
          != frameworks.end())
      return;

    llvm::Metadata *args[] = {
      llvm::MDString::get(ctx, "-framework"),
      llvm::MDString::get(ctx, linkLib.getName())
    };
    AutolinkEntries.push_back(llvm::MDNode::get(ctx, args));
    break;
  }
  }

  if (linkLib.shouldForceLoad()) {
    llvm::SmallString<64> buf;
    encodeForceLoadSymbolName(buf, linkLib.getName());
    auto symbolAddr = Module.getOrInsertGlobal(buf.str(), Int1Ty);
    if (useDllStorage())
      cast<llvm::GlobalVariable>(symbolAddr)
          ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);

    buf += "_$";
    appendEncodedName(buf, IRGen.Opts.ModuleName);

    if (!Module.getGlobalVariable(buf.str())) {
      auto ref = new llvm::GlobalVariable(Module, symbolAddr->getType(),
                                          /*isConstant=*/true,
                                          llvm::GlobalValue::WeakAnyLinkage,
                                          symbolAddr, buf.str());
      ref->setVisibility(llvm::GlobalValue::HiddenVisibility);
      auto casted = llvm::ConstantExpr::getBitCast(ref, Int8PtrTy);
      LLVMUsed.push_back(casted);
    }
  }
}

static bool replaceModuleFlagsEntry(llvm::LLVMContext &Ctx,
                                    llvm::Module &Module, StringRef EntryName,
                                    llvm::Module::ModFlagBehavior Behavior,
                                    llvm::Metadata *Val) {
  auto *ModuleFlags = Module.getModuleFlagsMetadata();

  for (unsigned I = 0, E = ModuleFlags->getNumOperands(); I != E; ++I) {
    llvm::MDNode *Op = ModuleFlags->getOperand(I);
    llvm::MDString *ID = cast<llvm::MDString>(Op->getOperand(1));

    if (ID->getString().equals(EntryName)) {

      // Create the new entry.
      llvm::Type *Int32Ty = llvm::Type::getInt32Ty(Ctx);
      llvm::Metadata *Ops[3] = {llvm::ConstantAsMetadata::get(
                                    llvm::ConstantInt::get(Int32Ty, Behavior)),
                                llvm::MDString::get(Ctx, EntryName), Val};

      ModuleFlags->setOperand(I, llvm::MDNode::get(Ctx, Ops));
      return true;
    }
  }
  llvm_unreachable("Could not replace old linker options entry?");
}

void IRGenModule::emitAutolinkInfo() {

  // FIXME: This constant should be vended by LLVM somewhere.
  static const char * const LinkerOptionsFlagName = "Linker Options";

  // Collect the linker options already in the module (from ClangCodeGen).
  auto *LinkerOptions = Module.getModuleFlag(LinkerOptionsFlagName);
  if (LinkerOptions)
    for (const auto &LinkOption : cast<llvm::MDNode>(LinkerOptions)->operands())
      AutolinkEntries.push_back(LinkOption);

  // Remove duplicates.
  llvm::SmallPtrSet<llvm::Metadata*, 4> knownAutolinkEntries;
  AutolinkEntries.erase(std::remove_if(AutolinkEntries.begin(),
                                       AutolinkEntries.end(),
                                       [&](llvm::Metadata *entry) -> bool {
                                         return !knownAutolinkEntries.insert(
                                                   entry).second;
                                       }),
                        AutolinkEntries.end());

  if ((TargetInfo.OutputObjectFormat == llvm::Triple::COFF &&
       !Triple.isOSCygMing()) ||
      TargetInfo.OutputObjectFormat == llvm::Triple::MachO || Triple.isPS4()) {
    llvm::LLVMContext &ctx = Module.getContext();

    if (!LinkerOptions) {
      // Create a new linker flag entry.
      Module.addModuleFlag(llvm::Module::AppendUnique, LinkerOptionsFlagName,
                           llvm::MDNode::get(ctx, AutolinkEntries));
    } else {
      // Replace the old linker flag entry.
      bool FoundOldEntry = replaceModuleFlagsEntry(
          ctx, Module, LinkerOptionsFlagName, llvm::Module::AppendUnique,
          llvm::MDNode::get(ctx, AutolinkEntries));

      (void)FoundOldEntry;
      assert(FoundOldEntry && "Could not replace old linker options entry?");
    }
  } else {
    assert((TargetInfo.OutputObjectFormat == llvm::Triple::ELF ||
            Triple.isOSCygMing()) &&
           "expected ELF output format or COFF format for Cygwin/MinGW");

    // Merge the entries into null-separated string.
    llvm::SmallString<64> EntriesString;
    for (auto &EntryNode : AutolinkEntries) {
      const llvm::MDNode *MD = cast<llvm::MDNode>(EntryNode);
      for (auto &Entry : MD->operands()) {
        const llvm::MDString *MS = cast<llvm::MDString>(Entry);
        EntriesString += MS->getString();
        EntriesString += '\0';
      }
    }
    auto EntriesConstant = llvm::ConstantDataArray::getString(
        LLVMContext, EntriesString, /*AddNull=*/false);

    auto var =
        new llvm::GlobalVariable(*getModule(), EntriesConstant->getType(), true,
                                 llvm::GlobalValue::PrivateLinkage,
                                 EntriesConstant, "_swift1_autolink_entries");
    var->setSection(".swift1_autolink_entries");
    var->setAlignment(getPointerAlignment().getValue());

    addUsedGlobal(var);
  }

  if (!IRGen.Opts.ForceLoadSymbolName.empty()) {
    llvm::SmallString<64> buf;
    encodeForceLoadSymbolName(buf, IRGen.Opts.ForceLoadSymbolName);
    auto symbol =
        new llvm::GlobalVariable(Module, Int1Ty, /*isConstant=*/false,
                                 llvm::GlobalValue::CommonLinkage,
                                 llvm::Constant::getNullValue(Int1Ty),
                                 buf.str());
    if (useDllStorage())
      symbol->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
  }
}

void IRGenModule::cleanupClangCodeGenMetadata() {
  // Remove llvm.ident that ClangCodeGen might have left in the module.
  auto *LLVMIdent = Module.getNamedMetadata("llvm.ident");
  if (LLVMIdent)
    Module.eraseNamedMetadata(LLVMIdent);

  // LLVM's object-file emission collects a fixed set of keys for the
  // image info.
  // Using "Objective-C Garbage Collection" as the key here is a hack,
  // but LLVM's object-file emission isn't general enough to collect
  // arbitrary keys to put in the image info.

  const char *ObjectiveCGarbageCollection = "Objective-C Garbage Collection";
  if (Module.getModuleFlag(ObjectiveCGarbageCollection)) {
    bool FoundOldEntry = replaceModuleFlagsEntry(
        Module.getContext(), Module, ObjectiveCGarbageCollection,
        llvm::Module::Override,
        llvm::ConstantAsMetadata::get(
            llvm::ConstantInt::get(Int32Ty, (uint32_t)(swiftVersion << 8))));

    (void)FoundOldEntry;
    assert(FoundOldEntry && "Could not replace old module flag entry?");
  } else
    Module.addModuleFlag(llvm::Module::Override,
                         ObjectiveCGarbageCollection,
                         (uint32_t)(swiftVersion << 8));
}

bool IRGenModule::finalize() {
  const char *ModuleHashVarName = "llvm.swift_module_hash";
  if (IRGen.Opts.OutputKind == IRGenOutputKind::ObjectFile &&
      !Module.getGlobalVariable(ModuleHashVarName)) {
    // Create a global variable into which we will store the hash of the
    // module (used for incremental compilation).
    // We have to create the variable now (before we emit the global lists).
    // But we want to calculate the hash later because later we can do it
    // multi-threaded.
    llvm::MD5::MD5Result zero = { 0 };
    ArrayRef<uint8_t> ZeroArr(zero, sizeof(llvm::MD5::MD5Result));
    auto *ZeroConst = llvm::ConstantDataArray::get(Module.getContext(), ZeroArr);
    ModuleHash = new llvm::GlobalVariable(Module, ZeroConst->getType(), true,
                                          llvm::GlobalValue::PrivateLinkage,
                                          ZeroConst, ModuleHashVarName);
    switch (TargetInfo.OutputObjectFormat) {
    case llvm::Triple::MachO:
      // On Darwin the linker ignores the __LLVM segment.
      ModuleHash->setSection("__LLVM,__swift_modhash");
      break;
    case llvm::Triple::ELF:
    case llvm::Triple::COFF:
      ModuleHash->setSection(".swift_modhash");
      break;
    default:
      llvm_unreachable("Don't know how to emit the module hash for the selected"
                       "object format.");
    }
    addUsedGlobal(ModuleHash);
  }
  emitLazyPrivateDefinitions();

  // Finalize clang IR-generation.
  finalizeClangCodeGen();

  // If that failed, report failure up and skip the final clean-up.
  if (!ClangCodeGen->GetModule())
    return false;

  emitAutolinkInfo();
  emitGlobalLists();
  if (DebugInfo)
    DebugInfo->finalize();
  cleanupClangCodeGenMetadata();

  return true;
}

/// Emit lazy definitions that have to be emitted in this specific
/// IRGenModule.
void IRGenModule::emitLazyPrivateDefinitions() {
  emitLazyObjCProtocolDefinitions();
}

void IRGenModule::unimplemented(SourceLoc loc, StringRef message) {
  Context.Diags.diagnose(loc, diag::irgen_unimplemented, message);
}

void IRGenModule::fatal_unimplemented(SourceLoc loc, StringRef message) {
  Context.Diags.diagnose(loc, diag::irgen_unimplemented, message);
  llvm::report_fatal_error(llvm::Twine("unimplemented IRGen feature! ") +
                             message);
}

void IRGenModule::error(SourceLoc loc, const Twine &message) {
  SmallVector<char, 128> buffer;
  Context.Diags.diagnose(loc, diag::irgen_failure,
                         message.toStringRef(buffer));
}

bool IRGenModule::useDllStorage() { return ::useDllStorage(Triple); }

void IRGenerator::addGenModule(SourceFile *SF, IRGenModule *IGM) {
  assert(GenModules.count(SF) == 0);
  GenModules[SF] = IGM;
  if (!PrimaryIGM) {
    PrimaryIGM = IGM;
  }
  Queue.push_back(IGM);
}

IRGenModule *IRGenerator::getGenModule(DeclContext *ctxt) {
  if (GenModules.size() == 1 || !ctxt) {
    return getPrimaryIGM();
  }
  SourceFile *SF = ctxt->getParentSourceFile();
  if (!SF) {
    return getPrimaryIGM();
  }
  IRGenModule *IGM = GenModules[SF];
  assert(IGM);
  return IGM;
}

IRGenModule *IRGenerator::getGenModule(SILFunction *f) {
  if (GenModules.size() == 1) {
    return getPrimaryIGM();
  }

  if (DeclContext *ctxt = f->getDeclContext()) {
    if (SourceFile *SF = ctxt->getParentSourceFile()) {
      IRGenModule *IGM = GenModules[SF];
      assert(IGM);
      return IGM;
    }
  }
  // We have no source file for the function.
  // Let's use the IGM from which the function is referenced the first time.
  if (IRGenModule *IGM = DefaultIGMForFunction[f])
    return IGM;

  return getPrimaryIGM();
}
