llvm/clang/lib/CodeGen/CGObjC.cpp

//===---- CGObjC.cpp - Emit LLVM Code for Objective-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
//
//===----------------------------------------------------------------------===//
//
// This contains code to emit Objective-C code as LLVM code.
//
//===----------------------------------------------------------------------===//

#include "CGDebugInfo.h"
#include "CGObjCRuntime.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/StmtObjC.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/CodeGen/CodeGenABITypes.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include <optional>
usingnamespaceclang;
usingnamespaceCodeGen;

TryEmitResult;
static TryEmitResult
tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e);
static RValue AdjustObjCObjectType(CodeGenFunction &CGF,
                                   QualType ET,
                                   RValue Result);

/// Given the address of a variable of pointer type, find the correct
/// null to store into it.
static llvm::Constant *getNullForVariable(Address addr) {}

/// Emits an instance of NSConstantString representing the object.
llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E)
{}

/// EmitObjCBoxedExpr - This routine generates code to call
/// the appropriate expression boxing method. This will either be
/// one of +[NSNumber numberWith<Type>:], or +[NSString stringWithUTF8String:],
/// or [NSValue valueWithBytes:objCType:].
///
llvm::Value *
CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) {}

llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
                                    const ObjCMethodDecl *MethodWithObjects) {}

llvm::Value *CodeGenFunction::EmitObjCArrayLiteral(const ObjCArrayLiteral *E) {}

llvm::Value *CodeGenFunction::EmitObjCDictionaryLiteral(
                                            const ObjCDictionaryLiteral *E) {}

/// Emit a selector.
llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {}

llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {}

/// Adjust the type of an Objective-C object that doesn't match up due
/// to type erasure at various points, e.g., related result types or the use
/// of parameterized classes.
static RValue AdjustObjCObjectType(CodeGenFunction &CGF, QualType ExpT,
                                   RValue Result) {}

/// Decide whether to extend the lifetime of the receiver of a
/// returns-inner-pointer message.
static bool
shouldExtendReceiverForInnerPointerMessage(const ObjCMessageExpr *message) {}

/// Given an expression of ObjC pointer type, check whether it was
/// immediately loaded from an ARC __weak l-value.
static const Expr *findWeakLValue(const Expr *E) {}

/// The ObjC runtime may provide entrypoints that are likely to be faster
/// than an ordinary message send of the appropriate selector.
///
/// The entrypoints are guaranteed to be equivalent to just sending the
/// corresponding message.  If the entrypoint is implemented naively as just a
/// message send, using it is a trade-off: it sacrifices a few cycles of
/// overhead to save a small amount of code.  However, it's possible for
/// runtimes to detect and special-case classes that use "standard"
/// behavior; if that's dynamically a large proportion of all objects, using
/// the entrypoint will also be faster than using a message send.
///
/// If the runtime does support a required entrypoint, then this method will
/// generate a call and return the resulting value.  Otherwise it will return
/// std::nullopt and the caller can generate a msgSend instead.
static std::optional<llvm::Value *> tryGenerateSpecializedMessageSend(
    CodeGenFunction &CGF, QualType ResultType, llvm::Value *Receiver,
    const CallArgList &Args, Selector Sel, const ObjCMethodDecl *method,
    bool isClassMessage) {}

CodeGen::RValue CGObjCRuntime::GeneratePossiblySpecializedMessageSend(
    CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
    Selector Sel, llvm::Value *Receiver, const CallArgList &Args,
    const ObjCInterfaceDecl *OID, const ObjCMethodDecl *Method,
    bool isClassMessage) {}

static void AppendFirstImpliedRuntimeProtocols(
    const ObjCProtocolDecl *PD,
    llvm::UniqueVector<const ObjCProtocolDecl *> &PDs) {}

std::vector<const ObjCProtocolDecl *>
CGObjCRuntime::GetRuntimeProtocolList(ObjCProtocolDecl::protocol_iterator begin,
                                      ObjCProtocolDecl::protocol_iterator end) {}

/// Instead of '[[MyClass alloc] init]', try to generate
/// 'objc_alloc_init(MyClass)'. This provides a code size improvement on the
/// caller side, as well as the optimized objc_alloc.
static std::optional<llvm::Value *>
tryEmitSpecializedAllocInit(CodeGenFunction &CGF, const ObjCMessageExpr *OME) {}

RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
                                            ReturnValueSlot Return) {}

namespace {
struct FinishARCDealloc final : EHScopeStack::Cleanup {};
}

/// StartObjCMethod - Begin emission of an ObjCMethod. This generates
/// the LLVM function and sets the other context used by
/// CodeGenFunction.
void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
                                      const ObjCContainerDecl *CD) {}

static llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
                                              LValue lvalue, QualType type);

/// Generate an Objective-C method.  An Objective-C method is a C function with
/// its pointer, name, and types registered in the class structure.
void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {}

/// emitStructGetterCall - Call the runtime function to load a property
/// into the return value slot.
static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar,
                                 bool isAtomic, bool hasStrong) {}

/// Determine whether the given architecture supports unaligned atomic
/// accesses.  They don't have to be fast, just faster than a function
/// call and a mutex.
static bool hasUnalignedAtomics(llvm::Triple::ArchType arch) {}

/// Return the maximum size that permits atomic accesses for the given
/// architecture.
static CharUnits getMaxAtomicAccessSize(CodeGenModule &CGM,
                                        llvm::Triple::ArchType arch) {}

namespace {
  class PropertyImplStrategy {};
}

/// Pick an implementation strategy for the given property synthesis.
PropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM,
                                     const ObjCPropertyImplDecl *propImpl) {}

/// Generate an Objective-C property getter function.
///
/// The given Decl must be an ObjCImplementationDecl. \@synthesize
/// is illegal within a category.
void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
                                         const ObjCPropertyImplDecl *PID) {}

static bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl) {}

/// emitCPPObjectAtomicGetterCall - Call the runtime function to
/// copy the ivar into the resturn slot.
static void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF,
                                          llvm::Value *returnAddr,
                                          ObjCIvarDecl *ivar,
                                          llvm::Constant *AtomicHelperFn) {}

// emitCmdValueForGetterSetterBody - Handle emitting the load necessary for
// the `_cmd` selector argument for getter/setter bodies. For direct methods,
// this returns an undefined/poison value; this matches behavior prior to `_cmd`
// being removed from the direct method ABI as the getter/setter caller would
// never load one. For non-direct methods, this emits a load of the implicit
// `_cmd` storage.
static llvm::Value *emitCmdValueForGetterSetterBody(CodeGenFunction &CGF,
                                                   ObjCMethodDecl *MD) {}

void
CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
                                        const ObjCPropertyImplDecl *propImpl,
                                        const ObjCMethodDecl *GetterMethodDecl,
                                        llvm::Constant *AtomicHelperFn) {}

/// emitStructSetterCall - Call the runtime function to store the value
/// from the first formal parameter into the given ivar.
static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD,
                                 ObjCIvarDecl *ivar) {}

/// emitCPPObjectAtomicSetterCall - Call the runtime function to store
/// the value from the first formal parameter into the given ivar, using
/// the Cpp API for atomic Cpp objects with non-trivial copy assignment.
static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF,
                                          ObjCMethodDecl *OMD,
                                          ObjCIvarDecl *ivar,
                                          llvm::Constant *AtomicHelperFn) {}


static bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID) {}

static bool UseOptimizedSetter(CodeGenModule &CGM) {}

void
CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
                                        const ObjCPropertyImplDecl *propImpl,
                                        llvm::Constant *AtomicHelperFn) {}

/// Generate an Objective-C property setter function.
///
/// The given Decl must be an ObjCImplementationDecl. \@synthesize
/// is illegal within a category.
void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
                                         const ObjCPropertyImplDecl *PID) {}

namespace {
  struct DestroyIvar final : EHScopeStack::Cleanup {};
}

/// Like CodeGenFunction::destroyARCStrong, but do it with a call.
static void destroyARCStrongWithStore(CodeGenFunction &CGF,
                                      Address addr,
                                      QualType type) {}

static void emitCXXDestructMethod(CodeGenFunction &CGF,
                                  ObjCImplementationDecl *impl) {}

void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
                                                 ObjCMethodDecl *MD,
                                                 bool ctor) {}

llvm::Value *CodeGenFunction::LoadObjCSelf() {}

QualType CodeGenFunction::TypeOfSelfObject() {}

void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){}

void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {}

void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {}

void CodeGenFunction::EmitObjCAtSynchronizedStmt(
                                              const ObjCAtSynchronizedStmt &S) {}

namespace {
  struct CallObjCRelease final : EHScopeStack::Cleanup {};
}

/// Produce the code for a CK_ARCConsumeObject.  Does a primitive
/// release at the end of the full-expression.
llvm::Value *CodeGenFunction::EmitObjCConsumeObject(QualType type,
                                                    llvm::Value *object) {}

llvm::Value *CodeGenFunction::EmitObjCExtendObjectLifetime(QualType type,
                                                           llvm::Value *value) {}

/// Given a number of pointers, inform the optimizer that they're
/// being intrinsically used up until this point in the program.
void CodeGenFunction::EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values) {}

/// Emit a call to "clang.arc.noop.use", which consumes the result of a call
/// that has operand bundle "clang.arc.attachedcall".
void CodeGenFunction::EmitARCNoopIntrinsicUse(ArrayRef<llvm::Value *> values) {}

static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, llvm::Value *RTF) {}

static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM,
                                         llvm::FunctionCallee RTF) {}

static llvm::Function *getARCIntrinsic(llvm::Intrinsic::ID IntID,
                                       CodeGenModule &CGM) {}

/// Perform an operation having the signature
///   i8* (i8*)
/// where a null input causes a no-op and returns null.
static llvm::Value *emitARCValueOperation(
    CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType,
    llvm::Function *&fn, llvm::Intrinsic::ID IntID,
    llvm::CallInst::TailCallKind tailKind = llvm::CallInst::TCK_None) {}

/// Perform an operation having the following signature:
///   i8* (i8**)
static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF, Address addr,
                                         llvm::Function *&fn,
                                         llvm::Intrinsic::ID IntID) {}

/// Perform an operation having the following signature:
///   i8* (i8**, i8*)
static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF, Address addr,
                                          llvm::Value *value,
                                          llvm::Function *&fn,
                                          llvm::Intrinsic::ID IntID,
                                          bool ignored) {}

/// Perform an operation having the following signature:
///   void (i8**, i8**)
static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src,
                                 llvm::Function *&fn,
                                 llvm::Intrinsic::ID IntID) {}

/// Perform an operation having the signature
///   i8* (i8*)
/// where a null input causes a no-op and returns null.
static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF,
                                           llvm::Value *value,
                                           llvm::Type *returnType,
                                           llvm::FunctionCallee &fn,
                                           StringRef fnName) {}

/// Produce the code to do a retain.  Based on the type, calls one of:
///   call i8* \@objc_retain(i8* %value)
///   call i8* \@objc_retainBlock(i8* %value)
llvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) {}

/// Retain the given object, with normal retain semantics.
///   call i8* \@objc_retain(i8* %value)
llvm::Value *CodeGenFunction::EmitARCRetainNonBlock(llvm::Value *value) {}

/// Retain the given block, with _Block_copy semantics.
///   call i8* \@objc_retainBlock(i8* %value)
///
/// \param mandatory - If false, emit the call with metadata
/// indicating that it's okay for the optimizer to eliminate this call
/// if it can prove that the block never escapes except down the stack.
llvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value,
                                                 bool mandatory) {}

static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF) {}

static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value,
                                               bool IsRetainRV,
                                               CodeGenFunction &CGF) {}

/// Retain the given object which is the result of a function call.
///   call i8* \@objc_retainAutoreleasedReturnValue(i8* %value)
///
/// Yes, this function name is one character away from a different
/// call with completely different semantics.
llvm::Value *
CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {}

/// Claim a possibly-autoreleased return value at +0.  This is only
/// valid to do in contexts which do not rely on the retain to keep
/// the object valid for all of its uses; for example, when
/// the value is ignored, or when it is being assigned to an
/// __unsafe_unretained variable.
///
///   call i8* \@objc_unsafeClaimAutoreleasedReturnValue(i8* %value)
llvm::Value *
CodeGenFunction::EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value) {}

/// Release the given object.
///   call void \@objc_release(i8* %value)
void CodeGenFunction::EmitARCRelease(llvm::Value *value,
                                     ARCPreciseLifetime_t precise) {}

/// Destroy a __strong variable.
///
/// At -O0, emit a call to store 'null' into the address;
/// instrumenting tools prefer this because the address is exposed,
/// but it's relatively cumbersome to optimize.
///
/// At -O1 and above, just load and call objc_release.
///
///   call void \@objc_storeStrong(i8** %addr, i8* null)
void CodeGenFunction::EmitARCDestroyStrong(Address addr,
                                           ARCPreciseLifetime_t precise) {}

/// Store into a strong object.  Always calls this:
///   call void \@objc_storeStrong(i8** %addr, i8* %value)
llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(Address addr,
                                                     llvm::Value *value,
                                                     bool ignored) {}

/// Store into a strong object.  Sometimes calls this:
///   call void \@objc_storeStrong(i8** %addr, i8* %value)
/// Other times, breaks it down into components.
llvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst,
                                                 llvm::Value *newValue,
                                                 bool ignored) {}

/// Autorelease the given object.
///   call i8* \@objc_autorelease(i8* %value)
llvm::Value *CodeGenFunction::EmitARCAutorelease(llvm::Value *value) {}

/// Autorelease the given object.
///   call i8* \@objc_autoreleaseReturnValue(i8* %value)
llvm::Value *
CodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) {}

/// Do a fused retain/autorelease of the given object.
///   call i8* \@objc_retainAutoreleaseReturnValue(i8* %value)
llvm::Value *
CodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) {}

/// Do a fused retain/autorelease of the given object.
///   call i8* \@objc_retainAutorelease(i8* %value)
/// or
///   %retain = call i8* \@objc_retainBlock(i8* %value)
///   call i8* \@objc_autorelease(i8* %retain)
llvm::Value *CodeGenFunction::EmitARCRetainAutorelease(QualType type,
                                                       llvm::Value *value) {}

/// Do a fused retain/autorelease of the given object.
///   call i8* \@objc_retainAutorelease(i8* %value)
llvm::Value *
CodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) {}

/// i8* \@objc_loadWeak(i8** %addr)
/// Essentially objc_autorelease(objc_loadWeakRetained(addr)).
llvm::Value *CodeGenFunction::EmitARCLoadWeak(Address addr) {}

/// i8* \@objc_loadWeakRetained(i8** %addr)
llvm::Value *CodeGenFunction::EmitARCLoadWeakRetained(Address addr) {}

/// i8* \@objc_storeWeak(i8** %addr, i8* %value)
/// Returns %value.
llvm::Value *CodeGenFunction::EmitARCStoreWeak(Address addr,
                                               llvm::Value *value,
                                               bool ignored) {}

/// i8* \@objc_initWeak(i8** %addr, i8* %value)
/// Returns %value.  %addr is known to not have a current weak entry.
/// Essentially equivalent to:
///   *addr = nil; objc_storeWeak(addr, value);
void CodeGenFunction::EmitARCInitWeak(Address addr, llvm::Value *value) {}

/// void \@objc_destroyWeak(i8** %addr)
/// Essentially objc_storeWeak(addr, nil).
void CodeGenFunction::EmitARCDestroyWeak(Address addr) {}

/// void \@objc_moveWeak(i8** %dest, i8** %src)
/// Disregards the current value in %dest.  Leaves %src pointing to nothing.
/// Essentially (objc_copyWeak(dest, src), objc_destroyWeak(src)).
void CodeGenFunction::EmitARCMoveWeak(Address dst, Address src) {}

/// void \@objc_copyWeak(i8** %dest, i8** %src)
/// Disregards the current value in %dest.  Essentially
///   objc_release(objc_initWeak(dest, objc_readWeakRetained(src)))
void CodeGenFunction::EmitARCCopyWeak(Address dst, Address src) {}

void CodeGenFunction::emitARCCopyAssignWeak(QualType Ty, Address DstAddr,
                                            Address SrcAddr) {}

void CodeGenFunction::emitARCMoveAssignWeak(QualType Ty, Address DstAddr,
                                            Address SrcAddr) {}

/// Produce the code to do a objc_autoreleasepool_push.
///   call i8* \@objc_autoreleasePoolPush(void)
llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() {}

/// Produce the code to do a primitive release.
///   call void \@objc_autoreleasePoolPop(i8* %ptr)
void CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) {}

/// Produce the code to do an MRR version objc_autoreleasepool_push.
/// Which is: [[NSAutoreleasePool alloc] init];
/// Where alloc is declared as: + (id) alloc; in NSAutoreleasePool class.
/// init is declared as: - (id) init; in its NSObject super class.
///
llvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() {}

/// Allocate the given objc object.
///   call i8* \@objc_alloc(i8* %value)
llvm::Value *CodeGenFunction::EmitObjCAlloc(llvm::Value *value,
                                            llvm::Type *resultType) {}

/// Allocate the given objc object.
///   call i8* \@objc_allocWithZone(i8* %value)
llvm::Value *CodeGenFunction::EmitObjCAllocWithZone(llvm::Value *value,
                                                    llvm::Type *resultType) {}

llvm::Value *CodeGenFunction::EmitObjCAllocInit(llvm::Value *value,
                                                llvm::Type *resultType) {}

/// Produce the code to do a primitive release.
/// [tmp drain];
void CodeGenFunction::EmitObjCMRRAutoreleasePoolPop(llvm::Value *Arg) {}

void CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF,
                                              Address addr,
                                              QualType type) {}

void CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF,
                                                Address addr,
                                                QualType type) {}

void CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF,
                                     Address addr,
                                     QualType type) {}

void CodeGenFunction::emitARCIntrinsicUse(CodeGenFunction &CGF, Address addr,
                                          QualType type) {}

/// Autorelease the given object.
///   call i8* \@objc_autorelease(i8* %value)
llvm::Value *CodeGenFunction::EmitObjCAutorelease(llvm::Value *value,
                                                  llvm::Type *returnType) {}

/// Retain the given object, with normal retain semantics.
///   call i8* \@objc_retain(i8* %value)
llvm::Value *CodeGenFunction::EmitObjCRetainNonBlock(llvm::Value *value,
                                                     llvm::Type *returnType) {}

/// Release the given object.
///   call void \@objc_release(i8* %value)
void CodeGenFunction::EmitObjCRelease(llvm::Value *value,
                                      ARCPreciseLifetime_t precise) {}

namespace {
  struct CallObjCAutoreleasePoolObject final : EHScopeStack::Cleanup {};
  struct CallObjCMRRAutoreleasePoolObject final : EHScopeStack::Cleanup {};
}

void CodeGenFunction::EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr) {}

static bool shouldRetainObjCLifetime(Qualifiers::ObjCLifetime lifetime) {}

static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
                                                  LValue lvalue,
                                                  QualType type) {}

static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
                                                  const Expr *e) {}

ValueTransform;

/// Insert code immediately after a call.

// FIXME: We should find a way to emit the runtime call immediately
// after the call is emitted to eliminate the need for this function.
static llvm::Value *emitARCOperationAfterCall(CodeGenFunction &CGF,
                                              llvm::Value *value,
                                              ValueTransform doAfterCall,
                                              ValueTransform doFallback) {}

/// Given that the given expression is some sort of call (which does
/// not return retained), emit a retain following it.
static llvm::Value *emitARCRetainCallResult(CodeGenFunction &CGF,
                                            const Expr *e) {}

/// Given that the given expression is some sort of call (which does
/// not return retained), perform an unsafeClaim following it.
static llvm::Value *emitARCUnsafeClaimCallResult(CodeGenFunction &CGF,
                                                 const Expr *e) {}

llvm::Value *CodeGenFunction::EmitARCReclaimReturnedObject(const Expr *E,
                                                      bool allowUnsafeClaim) {}

/// Determine whether it might be important to emit a separate
/// objc_retain_block on the result of the given expression, or
/// whether it's okay to just emit it in a +1 context.
static bool shouldEmitSeparateBlockRetain(const Expr *e) {}

namespace {
/// A CRTP base class for emitting expressions of retainable object
/// pointer type in ARC.
template <typename Impl, typename Result> class ARCExprEmitter {};
}

/// Try to emit a PseudoObjectExpr under special ARC rules.
///
/// This massively duplicates emitPseudoObjectRValue.
template <typename Impl, typename Result>
Result
ARCExprEmitter<Impl,Result>::visitPseudoObjectExpr(const PseudoObjectExpr *E) {}

template <typename Impl, typename Result>
Result ARCExprEmitter<Impl, Result>::visitBlockExpr(const BlockExpr *e) {}

template <typename Impl, typename Result>
Result ARCExprEmitter<Impl,Result>::visitCastExpr(const CastExpr *e) {}

template <typename Impl, typename Result>
Result
ARCExprEmitter<Impl,Result>::visitBinaryOperator(const BinaryOperator *e) {}

template <typename Impl, typename Result>
Result ARCExprEmitter<Impl,Result>::visitBinAssign(const BinaryOperator *e) {}

/// The default rule for __unsafe_unretained emits the RHS recursively,
/// stores into the unsafe variable, and propagates the result outward.
template <typename Impl, typename Result>
Result ARCExprEmitter<Impl,Result>::
                    visitBinAssignUnsafeUnretained(const BinaryOperator *e) {}

template <typename Impl, typename Result>
Result
ARCExprEmitter<Impl,Result>::visitBinAssignAutoreleasing(const BinaryOperator *e) {}

template <typename Impl, typename Result>
Result
ARCExprEmitter<Impl,Result>::visitBinAssignWeak(const BinaryOperator *e) {}

template <typename Impl, typename Result>
Result
ARCExprEmitter<Impl,Result>::visitBinAssignStrong(const BinaryOperator *e) {}

/// The general expression-emission logic.
template <typename Impl, typename Result>
Result ARCExprEmitter<Impl,Result>::visit(const Expr *e) {}

namespace {

/// An emitter for +1 results.
struct ARCRetainExprEmitter :
  public ARCExprEmitter<ARCRetainExprEmitter, TryEmitResult> {};
}

static TryEmitResult
tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {}

static llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
                                                LValue lvalue,
                                                QualType type) {}

/// EmitARCRetainScalarExpr - Semantically equivalent to
/// EmitARCRetainObject(e->getType(), EmitScalarExpr(e)), but making a
/// best-effort attempt to peephole expressions that naturally produce
/// retained objects.
llvm::Value *CodeGenFunction::EmitARCRetainScalarExpr(const Expr *e) {}

llvm::Value *
CodeGenFunction::EmitARCRetainAutoreleaseScalarExpr(const Expr *e) {}

llvm::Value *CodeGenFunction::EmitARCExtendBlockObject(const Expr *e) {}

llvm::Value *CodeGenFunction::EmitObjCThrowOperand(const Expr *expr) {}

namespace {

/// An emitter for assigning into an __unsafe_unretained context.
struct ARCUnsafeUnretainedExprEmitter :
  public ARCExprEmitter<ARCUnsafeUnretainedExprEmitter, llvm::Value*> {};
}

static llvm::Value *emitARCUnsafeUnretainedScalarExpr(CodeGenFunction &CGF,
                                                      const Expr *e) {}

/// EmitARCUnsafeUnretainedScalarExpr - Semantically equivalent to
/// immediately releasing the resut of EmitARCRetainScalarExpr, but
/// avoiding any spurious retains, including by performing reclaims
/// with objc_unsafeClaimAutoreleasedReturnValue.
llvm::Value *CodeGenFunction::EmitARCUnsafeUnretainedScalarExpr(const Expr *e) {}

std::pair<LValue,llvm::Value*>
CodeGenFunction::EmitARCStoreUnsafeUnretained(const BinaryOperator *e,
                                              bool ignored) {}

std::pair<LValue,llvm::Value*>
CodeGenFunction::EmitARCStoreStrong(const BinaryOperator *e,
                                    bool ignored) {}

std::pair<LValue,llvm::Value*>
CodeGenFunction::EmitARCStoreAutoreleasing(const BinaryOperator *e) {}

void CodeGenFunction::EmitObjCAutoreleasePoolStmt(
                                          const ObjCAutoreleasePoolStmt &ARPS) {}

/// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
/// make sure it survives garbage collection until this point.
void CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {}

/// GenerateObjCAtomicSetterCopyHelperFunction - Given a c++ object type with
/// non-trivial copy assignment function, produce following helper function.
/// static void copyHelper(Ty *dest, const Ty *source) { *dest = *source; }
///
llvm::Constant *
CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
                                        const ObjCPropertyImplDecl *PID) {}

llvm::Constant *CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(
    const ObjCPropertyImplDecl *PID) {}

llvm::Value *
CodeGenFunction::EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty) {}

static unsigned getBaseMachOPlatformID(const llvm::Triple &TT) {}

static llvm::Value *emitIsPlatformVersionAtLeast(CodeGenFunction &CGF,
                                                 const VersionTuple &Version) {}

llvm::Value *
CodeGenFunction::EmitBuiltinAvailable(const VersionTuple &Version) {}

static bool isFoundationNeededForDarwinAvailabilityCheck(
    const llvm::Triple &TT, const VersionTuple &TargetVersion) {}

void CodeGenModule::emitAtAvailableLinkGuard() {}

CGObjCRuntime::~CGObjCRuntime() {}