#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);
static llvm::Constant *getNullForVariable(Address addr) { … }
llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E)
{ … }
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) { … }
llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) { … }
llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) { … }
static RValue AdjustObjCObjectType(CodeGenFunction &CGF, QualType ExpT,
RValue Result) { … }
static bool
shouldExtendReceiverForInnerPointerMessage(const ObjCMessageExpr *message) { … }
static const Expr *findWeakLValue(const Expr *E) { … }
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) { … }
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 { … };
}
void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
const ObjCContainerDecl *CD) { … }
static llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
LValue lvalue, QualType type);
void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { … }
static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar,
bool isAtomic, bool hasStrong) { … }
static bool hasUnalignedAtomics(llvm::Triple::ArchType arch) { … }
static CharUnits getMaxAtomicAccessSize(CodeGenModule &CGM,
llvm::Triple::ArchType arch) { … }
namespace {
class PropertyImplStrategy { … };
}
PropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM,
const ObjCPropertyImplDecl *propImpl) { … }
void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
const ObjCPropertyImplDecl *PID) { … }
static bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl) { … }
static void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF,
llvm::Value *returnAddr,
ObjCIvarDecl *ivar,
llvm::Constant *AtomicHelperFn) { … }
static llvm::Value *emitCmdValueForGetterSetterBody(CodeGenFunction &CGF,
ObjCMethodDecl *MD) { … }
void
CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
const ObjCPropertyImplDecl *propImpl,
const ObjCMethodDecl *GetterMethodDecl,
llvm::Constant *AtomicHelperFn) { … }
static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD,
ObjCIvarDecl *ivar) { … }
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) { … }
void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
const ObjCPropertyImplDecl *PID) { … }
namespace {
struct DestroyIvar final : EHScopeStack::Cleanup { … };
}
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 { … };
}
llvm::Value *CodeGenFunction::EmitObjCConsumeObject(QualType type,
llvm::Value *object) { … }
llvm::Value *CodeGenFunction::EmitObjCExtendObjectLifetime(QualType type,
llvm::Value *value) { … }
void CodeGenFunction::EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values) { … }
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) { … }
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) { … }
static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF, Address addr,
llvm::Function *&fn,
llvm::Intrinsic::ID IntID) { … }
static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF, Address addr,
llvm::Value *value,
llvm::Function *&fn,
llvm::Intrinsic::ID IntID,
bool ignored) { … }
static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src,
llvm::Function *&fn,
llvm::Intrinsic::ID IntID) { … }
static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF,
llvm::Value *value,
llvm::Type *returnType,
llvm::FunctionCallee &fn,
StringRef fnName) { … }
llvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) { … }
llvm::Value *CodeGenFunction::EmitARCRetainNonBlock(llvm::Value *value) { … }
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) { … }
llvm::Value *
CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) { … }
llvm::Value *
CodeGenFunction::EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value) { … }
void CodeGenFunction::EmitARCRelease(llvm::Value *value,
ARCPreciseLifetime_t precise) { … }
void CodeGenFunction::EmitARCDestroyStrong(Address addr,
ARCPreciseLifetime_t precise) { … }
llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(Address addr,
llvm::Value *value,
bool ignored) { … }
llvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst,
llvm::Value *newValue,
bool ignored) { … }
llvm::Value *CodeGenFunction::EmitARCAutorelease(llvm::Value *value) { … }
llvm::Value *
CodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) { … }
llvm::Value *
CodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) { … }
llvm::Value *CodeGenFunction::EmitARCRetainAutorelease(QualType type,
llvm::Value *value) { … }
llvm::Value *
CodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) { … }
llvm::Value *CodeGenFunction::EmitARCLoadWeak(Address addr) { … }
llvm::Value *CodeGenFunction::EmitARCLoadWeakRetained(Address addr) { … }
llvm::Value *CodeGenFunction::EmitARCStoreWeak(Address addr,
llvm::Value *value,
bool ignored) { … }
void CodeGenFunction::EmitARCInitWeak(Address addr, llvm::Value *value) { … }
void CodeGenFunction::EmitARCDestroyWeak(Address addr) { … }
void CodeGenFunction::EmitARCMoveWeak(Address dst, Address 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) { … }
llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() { … }
void CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) { … }
llvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() { … }
llvm::Value *CodeGenFunction::EmitObjCAlloc(llvm::Value *value,
llvm::Type *resultType) { … }
llvm::Value *CodeGenFunction::EmitObjCAllocWithZone(llvm::Value *value,
llvm::Type *resultType) { … }
llvm::Value *CodeGenFunction::EmitObjCAllocInit(llvm::Value *value,
llvm::Type *resultType) { … }
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) { … }
llvm::Value *CodeGenFunction::EmitObjCAutorelease(llvm::Value *value,
llvm::Type *returnType) { … }
llvm::Value *CodeGenFunction::EmitObjCRetainNonBlock(llvm::Value *value,
llvm::Type *returnType) { … }
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;
static llvm::Value *emitARCOperationAfterCall(CodeGenFunction &CGF,
llvm::Value *value,
ValueTransform doAfterCall,
ValueTransform doFallback) { … }
static llvm::Value *emitARCRetainCallResult(CodeGenFunction &CGF,
const Expr *e) { … }
static llvm::Value *emitARCUnsafeClaimCallResult(CodeGenFunction &CGF,
const Expr *e) { … }
llvm::Value *CodeGenFunction::EmitARCReclaimReturnedObject(const Expr *E,
bool allowUnsafeClaim) { … }
static bool shouldEmitSeparateBlockRetain(const Expr *e) { … }
namespace {
template <typename Impl, typename Result> class ARCExprEmitter { … };
}
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) { … }
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) { … }
template <typename Impl, typename Result>
Result ARCExprEmitter<Impl,Result>::visit(const Expr *e) { … }
namespace {
struct ARCRetainExprEmitter :
public ARCExprEmitter<ARCRetainExprEmitter, TryEmitResult> { … };
}
static TryEmitResult
tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) { … }
static llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
LValue lvalue,
QualType type) { … }
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 {
struct ARCUnsafeUnretainedExprEmitter :
public ARCExprEmitter<ARCUnsafeUnretainedExprEmitter, llvm::Value*> { … };
}
static llvm::Value *emitARCUnsafeUnretainedScalarExpr(CodeGenFunction &CGF,
const Expr *e) { … }
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) { … }
void CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) { … }
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() { … }