//===- ARCRuntimeEntryPoints.h - ObjC ARC Optimization ----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \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/IR/Attributes.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>

namespace llvm {

class Function;
class Module;

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;
  }

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

    switch (kind) {
    case ARCRuntimeEntryPointKind::AutoreleaseRV:
      return getIntrinsicEntryPoint(AutoreleaseRV,
                                    Intrinsic::objc_autoreleaseReturnValue);
    case ARCRuntimeEntryPointKind::Release:
      return getIntrinsicEntryPoint(Release, Intrinsic::objc_release);
    case ARCRuntimeEntryPointKind::Retain:
      return getIntrinsicEntryPoint(Retain, Intrinsic::objc_retain);
    case ARCRuntimeEntryPointKind::RetainBlock:
      return getIntrinsicEntryPoint(RetainBlock, Intrinsic::objc_retainBlock);
    case ARCRuntimeEntryPointKind::Autorelease:
      return getIntrinsicEntryPoint(Autorelease, Intrinsic::objc_autorelease);
    case ARCRuntimeEntryPointKind::StoreStrong:
      return getIntrinsicEntryPoint(StoreStrong, Intrinsic::objc_storeStrong);
    case ARCRuntimeEntryPointKind::RetainRV:
      return getIntrinsicEntryPoint(RetainRV,
                                Intrinsic::objc_retainAutoreleasedReturnValue);
    case ARCRuntimeEntryPointKind::RetainAutorelease:
      return getIntrinsicEntryPoint(RetainAutorelease,
                                    Intrinsic::objc_retainAutorelease);
    case ARCRuntimeEntryPointKind::RetainAutoreleaseRV:
      return getIntrinsicEntryPoint(RetainAutoreleaseRV,
                                Intrinsic::objc_retainAutoreleaseReturnValue);
    }

    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.
  Function *AutoreleaseRV = nullptr;

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

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

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

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

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

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

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

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

  Function *getIntrinsicEntryPoint(Function *&Decl, Intrinsic::ID IntID) {
    if (Decl)
      return Decl;

    return Decl = Intrinsic::getDeclaration(TheModule, IntID);
  }
};

} // end namespace objcarc

} // end namespace llvm

#endif // LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H
