//===- ARCRuntimeEntryPoints.h - ObjC ARC Optimization ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file
/// This file contains a class ARCRuntimeEntryPoints for use in
/// creating/managing references to entry points to the arc objective c runtime.
///
/// WARNING: This file knows about certain library functions. It recognizes them
/// by name, and hardwires knowledge of their semantics.
///
/// WARNING: This file knows about how certain Objective-C library functions are
/// used. Naive LLVM IR transformations which would otherwise be
/// behavior-preserving may break these assumptions.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H
#define LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H

#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>

namespace llvm {

class Constant;
class LLVMContext;

namespace objcarc {

enum class ARCRuntimeEntryPointKind {
  AutoreleaseRV,
  Release,
  Retain,
  RetainBlock,
  Autorelease,
  StoreStrong,
  RetainRV,
  RetainAutorelease,
  RetainAutoreleaseRV,
};

/// Declarations for ObjC runtime functions and constants. These are initialized
/// lazily to avoid cluttering up the Module with unused declarations.
class ARCRuntimeEntryPoints {
public:
  ARCRuntimeEntryPoints() = default;

  void init(Module *M) {
    TheModule = M;
    AutoreleaseRV = nullptr;
    Release = nullptr;
    Retain = nullptr;
    RetainBlock = nullptr;
    Autorelease = nullptr;
    StoreStrong = nullptr;
    RetainRV = nullptr;
    RetainAutorelease = nullptr;
    RetainAutoreleaseRV = nullptr;
  }

  Constant *get(ARCRuntimeEntryPointKind kind) {
    assert(TheModule != nullptr && "Not initialized.");

    switch (kind) {
    case ARCRuntimeEntryPointKind::AutoreleaseRV:
      return getI8XRetI8XEntryPoint(AutoreleaseRV,
                                    "objc_autoreleaseReturnValue", true);
    case ARCRuntimeEntryPointKind::Release:
      return getVoidRetI8XEntryPoint(Release, "objc_release");
    case ARCRuntimeEntryPointKind::Retain:
      return getI8XRetI8XEntryPoint(Retain, "objc_retain", true);
    case ARCRuntimeEntryPointKind::RetainBlock:
      return getI8XRetI8XEntryPoint(RetainBlock, "objc_retainBlock", false);
    case ARCRuntimeEntryPointKind::Autorelease:
      return getI8XRetI8XEntryPoint(Autorelease, "objc_autorelease", true);
    case ARCRuntimeEntryPointKind::StoreStrong:
      return getI8XRetI8XXI8XEntryPoint(StoreStrong, "objc_storeStrong");
    case ARCRuntimeEntryPointKind::RetainRV:
      return getI8XRetI8XEntryPoint(RetainRV,
                                    "objc_retainAutoreleasedReturnValue", true);
    case ARCRuntimeEntryPointKind::RetainAutorelease:
      return getI8XRetI8XEntryPoint(RetainAutorelease, "objc_retainAutorelease",
                                    true);
    case ARCRuntimeEntryPointKind::RetainAutoreleaseRV:
      return getI8XRetI8XEntryPoint(RetainAutoreleaseRV,
                                    "objc_retainAutoreleaseReturnValue", true);
    }

    llvm_unreachable("Switch should be a covered switch.");
  }

private:
  /// Cached reference to the module which we will insert declarations into.
  Module *TheModule = nullptr;

  /// Declaration for ObjC runtime function objc_autoreleaseReturnValue.
  Constant *AutoreleaseRV = nullptr;

  /// Declaration for ObjC runtime function objc_release.
  Constant *Release = nullptr;

  /// Declaration for ObjC runtime function objc_retain.
  Constant *Retain = nullptr;

  /// Declaration for ObjC runtime function objc_retainBlock.
  Constant *RetainBlock = nullptr;

  /// Declaration for ObjC runtime function objc_autorelease.
  Constant *Autorelease = nullptr;

  /// Declaration for objc_storeStrong().
  Constant *StoreStrong = nullptr;

  /// Declaration for objc_retainAutoreleasedReturnValue().
  Constant *RetainRV = nullptr;

  /// Declaration for objc_retainAutorelease().
  Constant *RetainAutorelease = nullptr;

  /// Declaration for objc_retainAutoreleaseReturnValue().
  Constant *RetainAutoreleaseRV = nullptr;

  Constant *getVoidRetI8XEntryPoint(Constant *&Decl, StringRef Name) {
    if (Decl)
      return Decl;

    LLVMContext &C = TheModule->getContext();
    Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
    AttributeList Attr = AttributeList().addAttribute(
        C, AttributeList::FunctionIndex, Attribute::NoUnwind);
    FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
                                          /*isVarArg=*/false);
    return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
  }

  Constant *getI8XRetI8XEntryPoint(Constant *&Decl, StringRef Name,
                                   bool NoUnwind = false) {
    if (Decl)
      return Decl;

    LLVMContext &C = TheModule->getContext();
    Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
    Type *Params[] = { I8X };
    FunctionType *Fty = FunctionType::get(I8X, Params, /*isVarArg=*/false);
    AttributeList Attr = AttributeList();

    if (NoUnwind)
      Attr = Attr.addAttribute(C, AttributeList::FunctionIndex,
                               Attribute::NoUnwind);

    return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
  }

  Constant *getI8XRetI8XXI8XEntryPoint(Constant *&Decl, StringRef Name) {
    if (Decl)
      return Decl;

    LLVMContext &C = TheModule->getContext();
    Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
    Type *I8XX = PointerType::getUnqual(I8X);
    Type *Params[] = { I8XX, I8X };

    AttributeList Attr = AttributeList().addAttribute(
        C, AttributeList::FunctionIndex, Attribute::NoUnwind);
    Attr = Attr.addParamAttribute(C, 0, Attribute::NoCapture);

    FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
                                          /*isVarArg=*/false);

    return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
  }
};

} // end namespace objcarc

} // end namespace llvm

#endif // LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H
