26#include "llvm/ADT/STLExtras.h"
27#include "llvm/Analysis/ObjCARCUtil.h"
28#include "llvm/BinaryFormat/MachO.h"
29#include "llvm/IR/Constants.h"
30#include "llvm/IR/DataLayout.h"
31#include "llvm/IR/InlineAsm.h"
34using namespace CodeGen;
47 return llvm::ConstantPointerNull::get(cast<llvm::PointerType>(
type));
73 return ConstEmitter.tryEmitAbstract(E, E->
getType());
76 assert(BoxingMethod->
isClassMethod() &&
"BoxingMethod must be a class method");
84 llvm::Value *Receiver = Runtime.
GetClass(*
this, ClassDecl);
93 if (ValueType->isObjCBoxableRecordType()) {
98 llvm::Value *BitCast =
119 Args, ClassDecl, BoxingMethod);
130 DLE = cast<ObjCDictionaryLiteral>(E);
136 StringRef ConstantName = ALE ?
"__NSArray0__" :
"__NSDictionary0__";
138 llvm::Constant *Constant =
142 cast<llvm::LoadInst>(Ptr)->setMetadata(
143 llvm::LLVMContext::MD_invariant_load,
165 bool TrackNeededObjects =
170 for (uint64_t i = 0; i < NumElements; i++) {
179 if (TrackNeededObjects) {
180 NeededObjects.push_back(value);
196 if (TrackNeededObjects) {
197 NeededObjects.push_back(keyValue);
198 NeededObjects.push_back(valueValue);
228 llvm::Value *Receiver = Runtime.
GetClass(*
this, Class);
233 Receiver, Args, Class, MethodWithObjects);
239 if (TrackNeededObjects) {
280 if (ExpLLVMTy ==
Result.getScalarVal()->getType())
300 if (
auto opaque = dyn_cast<OpaqueValueExpr>(receiver)) {
301 if (opaque->getSourceExpr())
306 if (!ice || ice->
getCastKind() != CK_LValueToRValue)
return true;
310 if (
auto opaque = dyn_cast<OpaqueValueExpr>(receiver)) {
311 if (opaque->getSourceExpr())
320 if (isa<MemberExpr>(receiver) || isa<ObjCIvarRefExpr>(receiver))
325 if (!declRef)
return true;
327 if (!var)
return true;
332 !var->
hasAttr<ObjCPreciseLifetimeAttr>());
345 llvm_unreachable(
"invalid receiver kind");
353 if (
auto CE = dyn_cast<CastExpr>(E)) {
354 if (CE->getCastKind() == CK_LValueToRValue) {
356 return CE->getSubExpr();
380 bool isClassMessage) {
382 if (!CGM.getCodeGenOpts().ObjCConvertMessagesToRuntimeCalls)
385 auto &Runtime = CGM.getLangOpts().ObjCRuntime;
388 if (isClassMessage &&
389 Runtime.shouldUseRuntimeFunctionsForAlloc() &&
398 Args.size() == 1 && Args.front().getType()->isPointerType() &&
400 const llvm::Value* arg = Args.front().getKnownRValue().getScalarVal();
401 if (isa<llvm::ConstantPointerNull>(arg))
412 Runtime.shouldUseARCFunctionsForRetainRelease())
419 Runtime.shouldUseARCFunctionsForRetainRelease())
426 Runtime.shouldUseARCFunctionsForRetainRelease()) {
442 bool isClassMessage) {
443 if (std::optional<llvm::Value *> SpecializedResult =
445 Sel, Method, isClassMessage)) {
454 llvm::UniqueVector<const ObjCProtocolDecl *> &PDs) {
461 for (
const auto *ParentPD : PD->
protocols())
465std::vector<const ObjCProtocolDecl *>
468 std::vector<const ObjCProtocolDecl *> RuntimePds;
471 for (; begin != end; ++begin) {
472 const auto *It = *begin;
473 const auto *Can = It->getCanonicalDecl();
474 if (Can->isNonRuntimeProtocol())
475 NonRuntimePDs.insert(Can);
477 RuntimePds.push_back(Can);
481 if (NonRuntimePDs.empty())
488 llvm::UniqueVector<const ObjCProtocolDecl *> FirstImpliedProtos;
489 for (
const auto *PD : NonRuntimePDs)
495 for (
const auto *PD : RuntimePds) {
496 const auto *Can = PD->getCanonicalDecl();
497 AllImpliedProtocols.insert(Can);
498 Can->getImpliedProtocols(AllImpliedProtocols);
504 for (
const auto *PD : FirstImpliedProtos) {
505 PD->getImpliedProtocols(AllImpliedProtocols);
512 for (
const auto *PD : FirstImpliedProtos) {
513 if (!AllImpliedProtocols.contains(PD)) {
514 RuntimePds.push_back(PD);
524static std::optional<llvm::Value *>
527 if (!Runtime.shouldUseRuntimeFunctionForCombinedAllocInit())
543 Selector SubSel = SubOME->getSelector();
545 if (!SubOME->getType()->isObjCObjectPointerType() ||
549 llvm::Value *Receiver =
nullptr;
550 switch (SubOME->getReceiverKind()) {
552 if (!SubOME->getInstanceReceiver()->getType()->isObjCClassType())
558 QualType ReceiverType = SubOME->getClassReceiver();
561 assert(ID &&
"null interface should be impossible here");
605 method->
hasAttr<NSConsumesSelfAttr>());
608 bool isSuperMessage =
false;
609 bool isClassMessage =
false;
613 llvm::Value *Receiver =
nullptr;
621 Receiver = ter.getPointer();
622 if (ter.getInt()) retainSelf =
false;
630 assert(OID &&
"Invalid Objective-C class message send");
631 Receiver = Runtime.
GetClass(*
this, OID);
632 isClassMessage =
true;
639 isSuperMessage =
true;
645 isSuperMessage =
true;
646 isClassMessage =
true;
657 method->
hasAttr<ObjCReturnsInnerPointerAttr>() &&
673 if (isDelegateInit) {
675 "delegate init calls should only be marked in ARC");
684 if (isSuperMessage) {
687 bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->
getDeclContext());
699 *
this, Return, ResultType, E->
getSelector(), Receiver, Args, OID,
700 method, isClassMessage);
705 if (isDelegateInit) {
713 newSelf =
Builder.CreateBitCast(newSelf, selfTy);
730 bool isCategory = isa<ObjCCategoryImplDecl>(impl);
757 if (OMD->
hasAttr<NoDebugAttr>())
764 Fn->setVisibility(llvm::Function::HiddenVisibility);
797 if (ident->
isStr(
"dealloc"))
810 assert(isa<CompoundStmt>(OMD->
getBody()));
819 bool isAtomic,
bool hasStrong) {
860 llvm::Triple::ArchType
arch) {
870 class PropertyImplStrategy {
882 SetPropertyAndExpressionGet,
892 StrategyKind
getKind()
const {
return StrategyKind(Kind); }
894 bool hasStrongMember()
const {
return HasStrong; }
895 bool isAtomic()
const {
return IsAtomic; }
896 bool isCopy()
const {
return IsCopy; }
898 CharUnits getIvarSize()
const {
return IvarSize; }
899 CharUnits getIvarAlignment()
const {
return IvarAlignment; }
906 unsigned IsAtomic : 1;
908 unsigned HasStrong : 1;
916PropertyImplStrategy::PropertyImplStrategy(
CodeGenModule &CGM,
929 IvarSize = TInfo.
Width;
930 IvarAlignment = TInfo.Align;
936 Kind = IsAtomic ? GetSetProperty : SetPropertyAndExpressionGet;
949 }
else if (CGM.
getLangOpts().ObjCAutoRefCount && !IsAtomic) {
959 Kind = SetPropertyAndExpressionGet;
965 }
else if (!IsAtomic) {
966 Kind = SetPropertyAndExpressionGet;
971 Kind = GetSetProperty;
1002 HasStrong =
recordType->getDecl()->hasObjectMember();
1017 if (!IvarSize.isPowerOfTwo()) {
1022 llvm::Triple::ArchType
arch =
1050 llvm::Constant *AtomicHelperFn =
1053 assert(OMD &&
"Invalid call to generate getter (empty method)");
1063 if (!getter)
return true;
1075 if (
const CXXConstructExpr *construct = dyn_cast<CXXConstructExpr>(getter))
1076 return (construct->getConstructor()->isTrivial());
1080 assert(isa<ExprWithCleanups>(getter));
1087 llvm::Value *returnAddr,
1089 llvm::Constant *AtomicHelperFn) {
1098 llvm::Value *ivarAddr =
1107 llvm::FunctionCallee copyCppAtomicObjectFn =
1128 return llvm::PoisonValue::get(selType);
1138 llvm::Constant *AtomicHelperFn) {
1143 if (!AtomicHelperFn) {
1158 if (!AtomicHelperFn) {
1167 ivar, AtomicHelperFn);
1177 PropertyImplStrategy strategy(
CGM, propImpl);
1178 switch (strategy.getKind()) {
1179 case PropertyImplStrategy::Native: {
1181 if (strategy.getIvarSize().isZero())
1189 llvm::Type *bitcastType = llvm::Type::getIntNTy(
getLLVMContext(), ivarSize);
1195 load->setAtomic(llvm::AtomicOrdering::Unordered);
1202 llvm::Value *ivarVal = load;
1203 if (ivarSize > retTySize) {
1204 bitcastType = llvm::Type::getIntNTy(
getLLVMContext(), retTySize);
1205 ivarVal =
Builder.CreateTrunc(load, bitcastType);
1215 case PropertyImplStrategy::GetSetProperty: {
1216 llvm::FunctionCallee getPropertyFn =
1218 if (!getPropertyFn) {
1229 llvm::Value *ivarOffset =
1241 llvm::CallBase *CallInstruction;
1245 if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(CallInstruction))
1246 call->setTailCall();
1255 EmitReturnOfRValue(RV, propType);
1263 case PropertyImplStrategy::CopyStruct:
1265 strategy.hasStrongMember());
1268 case PropertyImplStrategy::Expression:
1269 case PropertyImplStrategy::SetPropertyAndExpressionGet: {
1308 value =
Builder.CreateBitCast(
1316 llvm_unreachable(
"bad evaluation kind");
1320 llvm_unreachable(
"bad @property implementation strategy!");
1332 llvm::Value *ivarAddr =
1372 llvm::Constant *AtomicHelperFn) {
1378 llvm::Value *ivarAddr =
1396 llvm::FunctionCallee fn =
1407 if (!setter)
return true;
1417 if (
CallExpr *call = dyn_cast<CallExpr>(setter)) {
1419 = dyn_cast_or_null<FunctionDecl>(call->getCalleeDecl()))
1420 if (callee->isTrivial())
1425 assert(isa<ExprWithCleanups>(setter));
1438 llvm::Constant *AtomicHelperFn) {
1444 if (!AtomicHelperFn) {
1463 if (!AtomicHelperFn)
1473 PropertyImplStrategy strategy(
CGM, propImpl);
1474 switch (strategy.getKind()) {
1475 case PropertyImplStrategy::Native: {
1477 if (strategy.getIvarSize().isZero())
1488 llvm::Type *bitcastType =
1490 getContext().toBits(strategy.getIvarSize()));
1501 store->setAtomic(llvm::AtomicOrdering::Unordered);
1505 case PropertyImplStrategy::GetSetProperty:
1506 case PropertyImplStrategy::SetPropertyAndExpressionGet: {
1508 llvm::FunctionCallee setOptimizedPropertyFn =
nullptr;
1509 llvm::FunctionCallee setPropertyFn =
nullptr;
1512 setOptimizedPropertyFn =
1514 strategy.isAtomic(), strategy.isCopy());
1515 if (!setOptimizedPropertyFn) {
1522 if (!setPropertyFn) {
1533 llvm::Value *ivarOffset =
1542 if (setOptimizedPropertyFn) {
1565 case PropertyImplStrategy::CopyStruct:
1569 case PropertyImplStrategy::Expression:
1582 &selfLoad,
true,
true);
1596 if (ivarRef.getType()->isObjCObjectPointerType()) {
1597 if (argLoad.getType()->isObjCObjectPointerType())
1599 else if (argLoad.getType()->isBlockPointerType())
1600 argCK = CK_BlockPointerToObjCPointerCast;
1602 argCK = CK_CPointerToObjCPointerCast;
1603 }
else if (ivarRef.getType()->isBlockPointerType()) {
1604 if (argLoad.getType()->isBlockPointerType())
1607 argCK = CK_AnyPointerToBlockPointerCast;
1608 }
else if (ivarRef.getType()->isPointerType()) {
1610 }
else if (argLoad.getType()->isAtomicType() &&
1611 !ivarRef.getType()->isAtomicType()) {
1612 argCK = CK_AtomicToNonAtomic;
1613 }
else if (!argLoad.getType()->isAtomicType() &&
1614 ivarRef.getType()->isAtomicType()) {
1615 argCK = CK_NonAtomicToAtomic;
1619 Expr *finalArg = &argLoad;
1620 if (!
getContext().hasSameUnqualifiedType(ivarRef.getType(),
1622 finalArg = &argCast;
1625 getContext(), &ivarRef, finalArg, BO_Assign, ivarRef.getType(),
1636 llvm::Constant *AtomicHelperFn =
1639 assert(OMD &&
"Invalid call to generate setter (empty method)");
1652 CodeGenFunction::Destroyer *destroyer;
1653 bool useEHCleanupForArray;
1655 DestroyIvar(llvm::Value *addr,
const ObjCIvarDecl *ivar,
1656 CodeGenFunction::Destroyer *destroyer,
1657 bool useEHCleanupForArray)
1658 : addr(addr), ivar(ivar), destroyer(destroyer),
1659 useEHCleanupForArray(useEHCleanupForArray) {}
1665 flags.isForNormalCleanup() && useEHCleanupForArray);
1680 CodeGenFunction::RunCleanupsScope scope(CGF);
1691 if (!dtorKind)
continue;
1707 CGF.
EHStack.pushCleanup<DestroyIvar>(cleanupKind, self, ivar, destroyer,
1711 assert(scope.requiresCleanups() &&
"nothing to do in .cxx_destruct?");
1725 for (
const auto *IvarInit : IMP->
inits()) {
1739 llvm::Value *SelfAsId =
1767 llvm::FunctionCallee EnumerationMutationFnPtr =
1769 if (!EnumerationMutationFnPtr) {
1780 RunCleanupsScope ForScope(*
this);
1784 if (
const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement()))
1795 static const unsigned NumItems = 16;
1808 llvm::APInt(32, NumItems),
nullptr,
1813 llvm::Value *Collection;
1844 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumItems);
1851 FastEnumSel, Collection, Args);
1854 llvm::Value *initialBufferLimit = CountRV.
getScalarVal();
1859 llvm::Value *zero = llvm::Constant::getNullValue(NSUIntegerTy);
1866 Builder.CreateICmpEQ(initialBufferLimit, zero,
"iszero"), EmptyBB,
1876 Address StateMutationsPtrPtr =
1878 llvm::Value *StateMutationsPtr
1882 llvm::Value *initialMutations =
1892 llvm::PHINode *index =
Builder.CreatePHI(NSUIntegerTy, 3,
"forcoll.index");
1893 index->addIncoming(zero, LoopInitBB);
1896 llvm::PHINode *count =
Builder.CreatePHI(NSUIntegerTy, 3,
"forcoll.count");
1897 count->addIncoming(initialBufferLimit, LoopInitBB);
1905 llvm::Value *currentMutations
1910 llvm::BasicBlock *WasNotMutatedBB =
createBasicBlock(
"forcoll.notmutated");
1912 Builder.CreateCondBr(
Builder.CreateICmpEQ(currentMutations, initialMutations),
1913 WasNotMutatedBB, WasMutatedBB);
1919 Builder.CreateBitCast(Collection, ObjCIdType);
1932 RunCleanupsScope elementVariableScope(*
this);
1933 bool elementIsVariable;
1936 if (
const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
1940 const VarDecl *D = cast<VarDecl>(SD->getSingleDecl());
1945 elementIsVariable =
true;
1950 elementLValue =
LValue();
1951 elementType = cast<Expr>(S.getElement())->getType();
1952 elementIsVariable =
false;
1954 llvm::Type *convertedElementType =
ConvertType(elementType);
1961 llvm::Value *EnumStateItems =
1966 ObjCIdType, EnumStateItems, index,
"currentitem.ptr");
1967 llvm::Value *CurrentItem =
1981 SanitizerScope SanScope(
this);
1983 assert(InterfaceTy->
getDecl() &&
"No decl for ObjC interface type");
1989 llvm::Value *IsClass =
1992 IsKindOfClassSel, CurrentItem,
1995 llvm::Constant *StaticData[] = {
1998 EmitCheck({{IsClass, SanitizerKind::ObjCCast}},
1999 SanitizerHandler::InvalidObjCCast,
2005 CurrentItem =
Builder.CreateBitCast(CurrentItem, convertedElementType,
2010 if (!elementIsVariable) {
2011 elementLValue =
EmitLValue(cast<Expr>(S.getElement()));
2020 if (elementIsVariable)
2024 BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
2026 RunCleanupsScope
Scope(*
this);
2029 BreakContinueStack.pop_back();
2032 elementVariableScope.ForceCleanup();
2040 llvm::Value *indexPlusOne =
2041 Builder.CreateAdd(index, llvm::ConstantInt::get(NSUIntegerTy, 1));
2048 Builder.CreateICmpULT(indexPlusOne, count), LoopBodyBB, FetchMoreBB,
2051 index->addIncoming(indexPlusOne, AfterBody.getBlock());
2052 count->addIncoming(count, AfterBody.getBlock());
2060 FastEnumSel, Collection, Args);
2066 index->addIncoming(zero,
Builder.GetInsertBlock());
2067 count->addIncoming(refetchCount,
Builder.GetInsertBlock());
2070 EmptyBB, LoopBodyBB);
2075 if (!elementIsVariable) {
2078 llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
2079 elementLValue =
EmitLValue(cast<Expr>(S.getElement()));
2086 ForScope.ForceCleanup();
2105 CallObjCRelease(llvm::Value *
object) :
object(
object) {}
2118 llvm::Value *
object) {
2126 llvm::Value *value) {
2152 if (
auto *F = dyn_cast<llvm::Function>(RTF)) {
2158 F->setLinkage(llvm::Function::ExternalWeakLinkage);
2164 llvm::FunctionCallee RTF) {
2180 llvm::Function *&fn, llvm::Intrinsic::ID IntID,
2181 llvm::CallInst::TailCallKind tailKind = llvm::CallInst::TCK_None) {
2182 if (isa<llvm::ConstantPointerNull>(value))
2189 llvm::Type *origType = returnType ? returnType : value->getType();
2194 call->setTailCallKind(tailKind);
2197 return CGF.
Builder.CreateBitCast(call, origType);
2203 llvm::Function *&fn,
2204 llvm::Intrinsic::ID IntID) {
2217 result = CGF.
Builder.CreateBitCast(result, origType);
2226 llvm::Function *&fn,
2227 llvm::Intrinsic::ID IntID,
2234 llvm::Type *origType = value->getType();
2236 llvm::Value *args[] = {
2242 if (ignored)
return nullptr;
2244 return CGF.
Builder.CreateBitCast(result, origType);
2250 llvm::Function *&fn,
2251 llvm::Intrinsic::ID IntID) {
2257 llvm::Value *args[] = {
2269 llvm::Type *returnType,
2270 llvm::FunctionCallee &fn,
2272 if (isa<llvm::ConstantPointerNull>(value))
2276 llvm::FunctionType *fnType =
2281 if (llvm::Function *f = dyn_cast<llvm::Function>(fn.getCallee()))
2282 if (fnName ==
"objc_retain")
2283 f->addFnAttr(llvm::Attribute::NonLazyBind);
2287 llvm::Type *origType = returnType ? returnType : value->getType();
2295 if (fnName ==
"objc_autorelease")
2296 if (
auto *Call = dyn_cast<llvm::CallInst>(Inst))
2297 Call->setTailCall();
2300 return CGF.
Builder.CreateBitCast(Inst, origType);
2307 if (
type->isBlockPointerType())
2318 llvm::Intrinsic::objc_retain);
2332 llvm::Intrinsic::objc_retainBlock);
2338 if (!mandatory && isa<llvm::Instruction>(result)) {
2339 llvm::CallInst *call
2340 = cast<llvm::CallInst>(result->stripPointerCasts());
2341 assert(call->getCalledOperand() ==
2344 call->setMetadata(
"clang.arc.copy_on_escape",
2345 llvm::MDNode::get(
Builder.getContext(), std::nullopt));
2354 llvm::InlineAsm *&marker
2362 if (assembly.empty()) {
2367 llvm::FunctionType *
type =
2368 llvm::FunctionType::get(CGF.
VoidTy,
false);
2370 marker = llvm::InlineAsm::get(
type, assembly,
"",
true);
2376 const char *retainRVMarkerKey = llvm::objcarc::getRVMarkerModuleFlagStr();
2377 if (!CGF.
CGM.
getModule().getModuleFlag(retainRVMarkerKey)) {
2380 retainRVMarkerKey, str);
2387 CGF.
Builder.CreateCall(marker, std::nullopt,
2401 llvm::Function *&EP = IsRetainRV
2404 llvm::Intrinsic::ID IID =
2405 IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue
2406 : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;
2409 llvm::Triple::ArchType Arch = CGF.
CGM.
getTriple().getArch();
2414 (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::x86_64)) {
2415 llvm::Value *bundleArgs[] = {EP};
2416 llvm::OperandBundleDef OB(
"clang.arc.attachedcall", bundleArgs);
2417 auto *oldCall = cast<llvm::CallBase>(value);
2418 llvm::CallBase *newCall = llvm::CallBase::addOperandBundle(
2419 oldCall, llvm::LLVMContext::OB_clang_arc_attachedcall, OB, oldCall);
2420 newCall->copyMetadata(*oldCall);
2421 oldCall->replaceAllUsesWith(newCall);
2422 oldCall->eraseFromParent();
2429 llvm::CallInst::TailCallKind tailKind =
2430 isNoTail ? llvm::CallInst::TCK_NoTail : llvm::CallInst::TCK_None;
2460 if (isa<llvm::ConstantPointerNull>(value))
return;
2473 call->setMetadata(
"clang.imprecise_release",
2474 llvm::MDNode::get(
Builder.getContext(), std::nullopt));
2510 llvm::Value *args[] = {
2516 if (ignored)
return nullptr;
2524 llvm::Value *newValue,
2527 bool isBlock =
type->isBlockPointerType();
2561 llvm::Intrinsic::objc_autorelease);
2570 llvm::Intrinsic::objc_autoreleaseReturnValue,
2571 llvm::CallInst::TCK_Tail);
2580 llvm::Intrinsic::objc_retainAutoreleaseReturnValue,
2581 llvm::CallInst::TCK_Tail);
2590 llvm::Value *value) {
2591 if (!
type->isBlockPointerType())
2594 if (isa<llvm::ConstantPointerNull>(value))
return value;
2596 llvm::Type *origType = value->getType();
2600 return Builder.CreateBitCast(value, origType);
2609 llvm::Intrinsic::objc_retainAutorelease);
2617 llvm::Intrinsic::objc_loadWeak);
2624 llvm::Intrinsic::objc_loadWeakRetained);
2634 llvm::Intrinsic::objc_storeWeak, ignored);
2646 if (isa<llvm::ConstantPointerNull>(value) &&
2654 llvm::Intrinsic::objc_initWeak,
true);
2676 llvm::Intrinsic::objc_moveWeak);
2685 llvm::Intrinsic::objc_copyWeak);
2720 llvm::FunctionCallee &fn =
2723 llvm::FunctionType *fnType =
2755 AllocSel, Receiver, Args);
2764 InitSel, Receiver, Args);
2771 llvm::Type *resultType) {
2780 llvm::Type *resultType) {
2783 "objc_allocWithZone");
2787 llvm::Type *resultType) {
2830 llvm::Type *returnType) {
2832 *
this, value, returnType,
2834 "objc_autorelease");
2840 llvm::Type *returnType) {
2842 *
this, value, returnType,
2850 if (isa<llvm::ConstantPointerNull>(value))
return;
2852 llvm::FunctionCallee &fn =
2855 llvm::FunctionType *fnType =
2860 if (llvm::Function *f = dyn_cast<llvm::Function>(fn.getCallee()))
2861 f->addFnAttr(llvm::Attribute::NonLazyBind);
2871 call->setMetadata(
"clang.imprecise_release",
2872 llvm::MDNode::get(
Builder.getContext(), std::nullopt));
2880 CallObjCAutoreleasePoolObject(llvm::Value *token) :
Token(token) {}
2889 CallObjCMRRAutoreleasePoolObject(llvm::Value *token) :
Token(token) {}
2916 llvm_unreachable(
"impossible lifetime!");
2922 llvm::Value *result;
2942 !
type.isConstQualified() &&
2961 !
type.isVolatileQualified() &&
2963 isa<BinaryOperator>(e) &&
2964 cast<BinaryOperator>(e)->getOpcode() == BO_Assign)
2970 if (
const auto *decl_expr = dyn_cast<DeclRefExpr>(e)) {
2981 llvm::Value *value)>
2992 CGBuilderTy::InsertPoint ip = CGF.
Builder.saveIP();
2993 auto *callBase = dyn_cast<llvm::CallBase>(value);
2995 if (callBase && llvm::objcarc::hasAttachedCallOpBundle(callBase)) {
2997 value = doFallback(CGF, value);
2998 }
else if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(value)) {
3000 CGF.
Builder.SetInsertPoint(call->getParent(),
3001 ++llvm::BasicBlock::iterator(call));
3002 value = doAfterCall(CGF, value);
3003 }
else if (llvm::InvokeInst *invoke = dyn_cast<llvm::InvokeInst>(value)) {
3005 llvm::BasicBlock *BB = invoke->getNormalDest();
3006 CGF.
Builder.SetInsertPoint(BB, BB->begin());
3007 value = doAfterCall(CGF, value);
3011 }
else if (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(value)) {
3014 CGF.
Builder.SetInsertPoint(bitcast->getParent(), bitcast->getIterator());
3015 llvm::Value *operand = bitcast->getOperand(0);
3017 bitcast->setOperand(0, operand);
3020 auto *phi = dyn_cast<llvm::PHINode>(value);
3021 if (phi && phi->getNumIncomingValues() == 2 &&
3022 isa<llvm::ConstantPointerNull>(phi->getIncomingValue(1)) &&
3023 isa<llvm::CallBase>(phi->getIncomingValue(0))) {
3026 llvm::Value *inVal = phi->getIncomingValue(0);
3028 phi->setIncomingValue(0, inVal);
3034 value = doFallback(CGF, value);
3071 bool allowUnsafeClaim) {
3072 if (allowUnsafeClaim &&
3090 if (isa<BlockExpr>(e))
3094 switch (
cast->getCastKind()) {
3096 case CK_LValueToRValue:
3097 case CK_ARCReclaimReturnedObject:
3098 case CK_ARCConsumeObject:
3099 case CK_ARCProduceObject:
3108 case CK_AnyPointerToBlockPointerCast:
3120template <
typename Impl,
typename Result>
class ARCExprEmitter {
3123 Impl &asImpl() {
return *
static_cast<Impl*
>(
this); }
3128 Result visit(
const Expr *e);
3129 Result visitCastExpr(
const CastExpr *e);
3131 Result visitBlockExpr(
const BlockExpr *e);
3155template <
typename Impl,
typename Result>
3157ARCExprEmitter<Impl,Result>::visitPseudoObjectExpr(
const PseudoObjectExpr *E) {
3167 const Expr *semantic = *i;
3171 if (
const OpaqueValueExpr *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
3172 typedef CodeGenFunction::OpaqueValueMappingData OVMA;
3177 if (ov == resultExpr) {
3178 assert(!OVMA::shouldBindAsLValue(ov));
3179 result = asImpl().visit(ov->getSourceExpr());
3180 opaqueData = OVMA::bind(CGF, ov,
3185 opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
3187 opaques.push_back(opaqueData);
3191 }
else if (semantic == resultExpr) {
3192 result = asImpl().visit(semantic);
3196 CGF.EmitIgnoredExpr(semantic);
3201 for (
unsigned i = 0, e = opaques.size(); i != e; ++i)
3202 opaques[i].unbind(CGF);
3207template <
typename Impl,
typename Result>
3208Result ARCExprEmitter<Impl, Result>::visitBlockExpr(
const BlockExpr *e) {
3210 return asImpl().visitExpr(e);
3213template <
typename Impl,
typename Result>
3214Result ARCExprEmitter<Impl,Result>::visitCastExpr(
const CastExpr *e) {
3222 case CK_CPointerToObjCPointerCast:
3223 case CK_BlockPointerToObjCPointerCast:
3224 case CK_AnyPointerToBlockPointerCast:
3226 llvm::Type *resultType = CGF.ConvertType(e->
getType());
3229 return asImpl().emitBitCast(result, resultType);
3233 case CK_LValueToRValue:
3234 return asImpl().visitLValueToRValue(e->
getSubExpr());
3235 case CK_ARCConsumeObject:
3236 return asImpl().visitConsumeObject(e->
getSubExpr());
3237 case CK_ARCExtendBlockObject:
3238 return asImpl().visitExtendBlockObject(e->
getSubExpr());
3239 case CK_ARCReclaimReturnedObject:
3240 return asImpl().visitReclaimReturnedObject(e->
getSubExpr());
3244 return asImpl().visitExpr(e);
3248template <
typename Impl,
typename Result>
3250ARCExprEmitter<Impl,Result>::visitBinaryOperator(
const BinaryOperator *e) {
3253 CGF.EmitIgnoredExpr(e->
getLHS());
3254 CGF.EnsureInsertPoint();
3255 return asImpl().visit(e->
getRHS());
3258 return asImpl().visitBinAssign(e);
3261 return asImpl().visitExpr(e);
3265template <
typename Impl,
typename Result>
3269 return asImpl().visitBinAssignUnsafeUnretained(e);
3272 return asImpl().visitBinAssignWeak(e);
3275 return asImpl().visitBinAssignAutoreleasing(e);
3278 return asImpl().visitBinAssignStrong(e);
3281 return asImpl().visitExpr(e);
3283 llvm_unreachable(
"bad ObjC ownership qualifier");
3288template <
typename Impl,
typename Result>
3289Result ARCExprEmitter<Impl,Result>::
3298 CGF.EmitStoreThroughLValue(
RValue::get(asImpl().getValueOfResult(result)),
3304template <
typename Impl,
typename Result>
3306ARCExprEmitter<Impl,Result>::visitBinAssignAutoreleasing(
const BinaryOperator *e) {
3307 return asImpl().visitExpr(e);
3310template <
typename Impl,
typename Result>
3312ARCExprEmitter<Impl,Result>::visitBinAssignWeak(
const BinaryOperator *e) {
3313 return asImpl().visitExpr(e);
3316template <
typename Impl,
typename Result>
3318ARCExprEmitter<Impl,Result>::visitBinAssignStrong(
const BinaryOperator *e) {
3319 return asImpl().visitExpr(e);
3323template <
typename Impl,
typename Result>
3324Result ARCExprEmitter<Impl,Result>::visit(
const Expr *e) {
3329 assert(!isa<ExprWithCleanups>(e));
3335 if (
const CastExpr *ce = dyn_cast<CastExpr>(e)) {
3336 return asImpl().visitCastExpr(ce);
3339 }
else if (
auto op = dyn_cast<BinaryOperator>(e)) {
3340 return asImpl().visitBinaryOperator(op);
3348 }
else if (isa<CallExpr>(e) ||
3349 (isa<ObjCMessageExpr>(e) &&
3350 !cast<ObjCMessageExpr>(e)->isDelegateInitCall())) {
3351 return asImpl().visitCall(e);
3354 }
else if (
const PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) {
3355 return asImpl().visitPseudoObjectExpr(pseudo);
3356 }
else if (
auto *be = dyn_cast<BlockExpr>(e))
3357 return asImpl().visitBlockExpr(be);
3359 return asImpl().visitExpr(e);
3365struct ARCRetainExprEmitter :
3366 public ARCExprEmitter<ARCRetainExprEmitter, TryEmitResult> {
3371 return result.getPointer();
3375 llvm::Value *value = result.getPointer();
3376 value = CGF.Builder.CreateBitCast(value, resultType);
3377 result.setPointer(value);
3388 llvm::Value *result = CGF.EmitScalarExpr(e);
3396 if (CGF.CGM.getCodeGenOpts().ObjCAvoidHeapifyLocalBlocks &&
3398 result.setInt(
true);
3406 llvm::Value *result;
3411 result = CGF.EmitScalarExpr(e);
3418 if (subresult.getInt()) {
3423 result = subresult.getPointer();
3427 result = CGF.EmitARCRetainBlock(result,
true);
3449 llvm::Value *result = CGF.EmitScalarExpr(e);
3457 return ARCRetainExprEmitter(CGF).visit(e);
3464 llvm::Value *value = result.getPointer();
3465 if (!result.getInt())
3477 RunCleanupsScope scope(*
this);
3482 llvm::Value *value = result.getPointer();
3483 if (!result.getInt())
3492 RunCleanupsScope scope(*
this);
3497 llvm::Value *value = result.getPointer();
3498 if (result.getInt())
3506 llvm::Value *result;
3514 result = subresult.getPointer();
3515 doRetain = !subresult.getInt();
3542struct ARCUnsafeUnretainedExprEmitter :
3543 public ARCExprEmitter<ARCUnsafeUnretainedExprEmitter, llvm::Value*> {
3545 ARCUnsafeUnretainedExprEmitter(
CodeGenFunction &CGF) : ARCExprEmitter(CGF) {}
3547 llvm::Value *getValueOfResult(llvm::Value *value) {
3551 llvm::Value *emitBitCast(llvm::Value *value, llvm::Type *resultType) {
3552 return CGF.Builder.CreateBitCast(value, resultType);
3555 llvm::Value *visitLValueToRValue(
const Expr *e) {
3556 return CGF.EmitScalarExpr(e);
3561 llvm::Value *visitConsumeObject(
const Expr *e) {
3562 llvm::Value *value = CGF.EmitScalarExpr(e);
3563 return CGF.EmitObjCConsumeObject(e->
getType(), value);
3568 llvm::Value *visitExtendBlockObject(
const Expr *e) {
3569 return CGF.EmitARCExtendBlockObject(e);
3573 llvm::Value *visitReclaimReturnedObject(
const Expr *e) {
3574 return CGF.EmitARCReclaimReturnedObject(e,
true);
3579 llvm::Value *visitCall(
const Expr *e) {
3580 return CGF.EmitScalarExpr(e);
3584 llvm::Value *visitExpr(
const Expr *e) {
3585 return CGF.EmitScalarExpr(e);
3592 return ARCUnsafeUnretainedExprEmitter(CGF).visit(e);
3602 RunCleanupsScope scope(*
this);
3609std::pair<LValue,llvm::Value*>
3625 return std::pair<LValue,llvm::Value*>(std::move(lvalue), value);
3628std::pair<LValue,llvm::Value*>
3633 llvm::Value *value = result.getPointer();
3635 bool hasImmediateRetain = result.getInt();
3642 hasImmediateRetain =
true;
3648 if (hasImmediateRetain) {
3656 return std::pair<LValue,llvm::Value*>(lvalue, value);
3659std::pair<LValue,llvm::Value*>
3666 return std::pair<LValue,llvm::Value*>(lvalue, value);
3679 RunCleanupsScope
Scope(*
this);
3688 for (
const auto *I : S.body())
3699 llvm::FunctionType *extenderType
3701 llvm::InlineAsm *extender = llvm::InlineAsm::get(extenderType,
3727 CharUnits Alignment =
C.getTypeAlignInChars(Ty);
3730 return llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
3738 llvm::Constant *HelperFn =
nullptr;
3752 SrcTy =
C.getPointerType(SrcTy);
3755 ArgTys.push_back(DestTy);
3756 ArgTys.push_back(SrcTy);
3757 QualType FunctionTy =
C.getFunctionType(ReturnTy, ArgTys, {});
3761 FunctionTy,
nullptr,
SC_Static,
false,
false,
false);
3769 args.push_back(Params[0] = DstDecl);
3774 args.push_back(Params[1] = SrcDecl);
3775 FD->setParams(Params);
3782 llvm::Function *Fn =
3783 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
3784 "__assign_helper_atomic_property_",
3801 Expr *Args[2] = {DST, SRC};
3810 HelperFn = llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
3825 CharUnits Alignment =
C.getTypeAlignInChars(Ty);
3828 return llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
3836 llvm::Constant *HelperFn =
nullptr;
3850 SrcTy =
C.getPointerType(SrcTy);
3853 ArgTys.push_back(DestTy);
3854 ArgTys.push_back(SrcTy);
3855 QualType FunctionTy =
C.getFunctionType(ReturnTy, ArgTys, {});
3859 FunctionTy,
nullptr,
SC_Static,
false,
false,
false);
3867 args.push_back(Params[0] = DstDecl);
3872 args.push_back(Params[1] = SrcDecl);
3873 FD->setParams(Params);
3880 llvm::Function *Fn = llvm::Function::Create(
3881 LTy, llvm::GlobalValue::InternalLinkage,
"__copy_helper_atomic_property_",
3899 ConstructorArgs.push_back(SRC);
3900 ConstructorArgs.append(std::next(CXXConstExpr->
arg_begin()),
3929 HelperFn = llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
3946 llvm::Value *Val =
Block;
3951 Val =
Result.getScalarVal();
3953 Ty, AutoreleaseSelector,
3955 Val =
Result.getScalarVal();
3960 switch (TT.getOS()) {
3961 case llvm::Triple::Darwin:
3962 case llvm::Triple::MacOSX:
3963 return llvm::MachO::PLATFORM_MACOS;
3964 case llvm::Triple::IOS:
3965 return llvm::MachO::PLATFORM_IOS;
3966 case llvm::Triple::TvOS:
3967 return llvm::MachO::PLATFORM_TVOS;
3968 case llvm::Triple::WatchOS:
3969 return llvm::MachO::PLATFORM_WATCHOS;
3970 case llvm::Triple::DriverKit:
3971 return llvm::MachO::PLATFORM_DRIVERKIT;
3978 const VersionTuple &Version) {
3985 auto EmitArgs = [&](
const VersionTuple &Version,
const llvm::Triple &TT) {
3986 std::optional<unsigned> Min = Version.getMinor(),
3987 SMin = Version.getSubminor();
3990 Args.push_back(llvm::ConstantInt::get(CGM.
Int32Ty, Version.getMajor()));
3991 Args.push_back(llvm::ConstantInt::get(CGM.
Int32Ty, Min.value_or(0)));
3992 Args.push_back(llvm::ConstantInt::get(CGM.
Int32Ty, SMin.value_or(0)));
3995 assert(!Version.empty() &&
"unexpected empty version");
3999 llvm::FunctionType *FTy = llvm::FunctionType::get(
4000 CGM.
Int32Ty, {CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty},
4006 llvm::Value *Check =
4008 return CGF.
Builder.CreateICmpNE(Check,
4009 llvm::Constant::getNullValue(CGM.
Int32Ty));
4019 llvm::FunctionType *FTy =
4025 std::optional<unsigned> Min = Version.getMinor(),
4026 SMin = Version.getSubminor();
4027 llvm::Value *Args[] = {
4028 llvm::ConstantInt::get(
CGM.
Int32Ty, Version.getMajor()),
4029 llvm::ConstantInt::get(
CGM.
Int32Ty, Min.value_or(0)),
4030 llvm::ConstantInt::get(
CGM.
Int32Ty, SMin.value_or(0))};
4032 llvm::Value *CallRes =
4035 return Builder.CreateICmpNE(CallRes, llvm::Constant::getNullValue(
Int32Ty));
4039 const llvm::Triple &TT,
const VersionTuple &
TargetVersion) {
4040 VersionTuple FoundationDroppedInVersion;
4041 switch (TT.getOS()) {
4042 case llvm::Triple::IOS:
4043 case llvm::Triple::TvOS:
4044 FoundationDroppedInVersion = VersionTuple(13);
4046 case llvm::Triple::WatchOS:
4047 FoundationDroppedInVersion = VersionTuple(6);
4049 case llvm::Triple::Darwin:
4050 case llvm::Triple::MacOSX:
4051 FoundationDroppedInVersion = VersionTuple(10, 15);
4053 case llvm::Triple::DriverKit:
4057 llvm_unreachable(
"Unexpected OS");
4062void CodeGenModule::emitAtAvailableLinkGuard() {
4078 llvm::Metadata *Args[2] = {llvm::MDString::get(Context,
"-framework"),
4079 llvm::MDString::get(Context,
"CoreFoundation")};
4080 LinkerOptionsMetadata.push_back(llvm::MDNode::get(Context, Args));
4083 llvm::FunctionType *FTy =
4085 llvm::FunctionCallee CFFunc =
4088 llvm::FunctionType *CheckFTy = llvm::FunctionType::get(
VoidTy, {},
false);
4090 CheckFTy,
"__clang_at_available_requires_core_foundation_framework",
4091 llvm::AttributeList(),
true);
4092 llvm::Function *CFLinkCheckFunc =
4093 cast<llvm::Function>(CFLinkCheckFuncRef.getCallee()->stripPointerCasts());
4094 if (CFLinkCheckFunc->empty()) {
4095 CFLinkCheckFunc->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
4096 CFLinkCheckFunc->setVisibility(llvm::GlobalValue::HiddenVisibility);
4098 CGF.Builder.SetInsertPoint(CGF.createBasicBlock(
"", CFLinkCheckFunc));
4099 CGF.EmitNounwindRuntimeCall(CFFunc,
4100 llvm::Constant::getNullValue(
VoidPtrTy));
4101 CGF.Builder.CreateUnreachable();
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
CodeGenFunction::ComplexPairTy ComplexPairTy
static llvm::Value * emitARCUnsafeClaimCallResult(CodeGenFunction &CGF, const Expr *e)
Given that the given expression is some sort of call (which does not return retained),...
static bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl)
static bool shouldRetainObjCLifetime(Qualifiers::ObjCLifetime lifetime)
static bool shouldEmitSeparateBlockRetain(const Expr *e)
Determine whether it might be important to emit a separate objc_retain_block on the result of the giv...
static std::optional< llvm::Value * > tryEmitSpecializedAllocInit(CodeGenFunction &CGF, const ObjCMessageExpr *OME)
Instead of '[[MyClass alloc] init]', try to generate 'objc_alloc_init(MyClass)'.
static llvm::Value * emitObjCValueOperation(CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType, llvm::FunctionCallee &fn, StringRef fnName)
Perform an operation having the signature i8* (i8*) where a null input causes a no-op and returns nul...
llvm::function_ref< llvm::Value *(CodeGenFunction &CGF, llvm::Value *value)> ValueTransform
static llvm::Value * emitARCUnsafeUnretainedScalarExpr(CodeGenFunction &CGF, const Expr *e)
static llvm::Value * emitARCLoadOperation(CodeGenFunction &CGF, Address addr, llvm::Function *&fn, llvm::Intrinsic::ID IntID)
Perform an operation having the following signature: i8* (i8**)
static llvm::Constant * getNullForVariable(Address addr)
Given the address of a variable of pointer type, find the correct null to store into it.
static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF)
static const Expr * findWeakLValue(const Expr *E)
Given an expression of ObjC pointer type, check whether it was immediately loaded from an ARC __weak ...
llvm::PointerIntPair< llvm::Value *, 1, bool > TryEmitResult
static bool hasUnalignedAtomics(llvm::Triple::ArchType arch)
Determine whether the given architecture supports unaligned atomic accesses.
static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src, llvm::Function *&fn, llvm::Intrinsic::ID IntID)
Perform an operation having the following signature: void (i8**, i8**)
static void AppendFirstImpliedRuntimeProtocols(const ObjCProtocolDecl *PD, llvm::UniqueVector< const ObjCProtocolDecl * > &PDs)
static TryEmitResult tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e)
static llvm::Value * emitOptimizedARCReturnCall(llvm::Value *value, bool IsRetainRV, CodeGenFunction &CGF)
static llvm::Value * emitCmdValueForGetterSetterBody(CodeGenFunction &CGF, ObjCMethodDecl *MD)
static llvm::Function * getARCIntrinsic(llvm::Intrinsic::ID IntID, CodeGenModule &CGM)
static bool isFoundationNeededForDarwinAvailabilityCheck(const llvm::Triple &TT, const VersionTuple &TargetVersion)
static bool shouldExtendReceiverForInnerPointerMessage(const ObjCMessageExpr *message)
Decide whether to extend the lifetime of the receiver of a returns-inner-pointer message.
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: i8* (i8**, i8*)
static unsigned getBaseMachOPlatformID(const llvm::Triple &TT)
static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF, LValue lvalue, QualType type)
static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, llvm::Value *RTF)
static std::optional< llvm::Value * > tryGenerateSpecializedMessageSend(CodeGenFunction &CGF, QualType ResultType, llvm::Value *Receiver, const CallArgList &Args, Selector Sel, const ObjCMethodDecl *method, bool isClassMessage)
The ObjC runtime may provide entrypoints that are likely to be faster than an ordinary message send o...
static CharUnits getMaxAtomicAccessSize(CodeGenModule &CGM, llvm::Triple::ArchType arch)
Return the maximum size that permits atomic accesses for the given architecture.
static llvm::Value * emitARCRetainCallResult(CodeGenFunction &CGF, const Expr *e)
Given that the given expression is some sort of call (which does not return retained),...
static void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF, llvm::Value *returnAddr, ObjCIvarDecl *ivar, llvm::Constant *AtomicHelperFn)
emitCPPObjectAtomicGetterCall - Call the runtime function to copy the ivar into the resturn slot.
static llvm::Value * emitIsPlatformVersionAtLeast(CodeGenFunction &CGF, const VersionTuple &Version)
static void destroyARCStrongWithStore(CodeGenFunction &CGF, Address addr, QualType type)
Like CodeGenFunction::destroyARCStrong, but do it with a call.
static llvm::Value * emitARCRetainLoadOfScalar(CodeGenFunction &CGF, LValue lvalue, QualType type)
static void emitCXXDestructMethod(CodeGenFunction &CGF, ObjCImplementationDecl *impl)
static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar, bool isAtomic, bool hasStrong)
emitStructGetterCall - Call the runtime function to load a property into the return value slot.
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 signature i8* (i8*) where a null input causes a no-op and returns nul...
static llvm::Value * emitARCOperationAfterCall(CodeGenFunction &CGF, llvm::Value *value, ValueTransform doAfterCall, ValueTransform doFallback)
Insert code immediately after a call.
static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, ObjCIvarDecl *ivar)
emitStructSetterCall - Call the runtime function to store the value from the first formal parameter i...
static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, ObjCIvarDecl *ivar, llvm::Constant *AtomicHelperFn)
emitCPPObjectAtomicSetterCall - Call the runtime function to store the value from the first formal pa...
static RValue AdjustObjCObjectType(CodeGenFunction &CGF, QualType ET, RValue Result)
Adjust the type of an Objective-C object that doesn't match up due to type erasure at various points,...
static bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID)
static bool UseOptimizedSetter(CodeGenModule &CGM)
static Decl::Kind getKind(const Decl *D)
Defines the Objective-C statement AST node classes.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
SelectorTable & Selectors
Qualifiers::GC getObjCGCAttrKind(QualType Ty) const
Return one of the GCNone, Weak or Strong Objective-C garbage collection attributes.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
TypeInfoChars getTypeInfoInChars(const Type *T) const
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
QualType getObjCIdType() const
Represents the Objective-CC id type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
A builtin binary operation expression such as "x + y" or "x <= y".
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
bool canAvoidCopyToHeap() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
const BlockDecl * getBlockDecl() const
Represents a call to a C++ constructor.
static CXXConstructExpr * Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc, CXXConstructorDecl *Ctor, bool Elidable, ArrayRef< Expr * > Args, bool HadMultipleCandidates, bool ListInitialization, bool StdInitListInitialization, bool ZeroInitialization, ConstructionKind ConstructKind, SourceRange ParenOrBraceRange)
Create a C++ construction expression.
bool isElidable() const
Whether this construction is elidable.
bool hadMultipleCandidates() const
Whether the referred constructor was resolved from an overloaded set having size greater than 1.
bool isStdInitListInitialization() const
Whether this constructor call was written as list-initialization, but was interpreted as forming a st...
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
ConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
A call to an overloaded operator written using operator syntax.
static CXXOperatorCallExpr * Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, ADLCallKind UsesADL=NotADL)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
llvm::Value * getPointer() const
llvm::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot forLValue(const LValue &LV, CodeGenFunction &CGF, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
Address CreateConstArrayGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = [n x T]* ... produce name = getelementptr inbounds addr, i64 0, i64 index where i64 is a...
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Address CreateGEP(Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
All available information about a concrete callee.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the end of a new lexical block and pop the current block.
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.
CGFunctionInfo - Class to encapsulate the information about a function definition.
Implements runtime-specific code generation functions.
virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in getter.
virtual llvm::FunctionCallee GetPropertySetFunction()=0
Return the runtime function for setting properties.
virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in setter.
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtTryStmt &S)=0
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs, const ObjCInterfaceDecl *Class=nullptr, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation.
CodeGen::RValue GeneratePossiblySpecializedMessageSend(CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &Args, const ObjCInterfaceDecl *OID, const ObjCMethodDecl *Method, bool isClassMessage)
Generate an Objective-C message send operation.
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generate a function preamble for a method with the specified types.
virtual llvm::Value * GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *OPD)=0
Emit the code to return the named protocol as an object, as in a @protocol expression.
virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl, llvm::Value *Self, bool IsClassMessage, const CallArgList &CallArgs, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation to the super class initiated in a method for Class and...
virtual llvm::FunctionCallee EnumerationMutationFunction()=0
EnumerationMutationFunction - Return the function that's called by the compiler when a mutation is de...
virtual llvm::FunctionCallee GetGetStructFunction()=0
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
virtual llvm::Value * GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID)=0
GetClass - Return a reference to the class for the given interface decl.
virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, bool copy)=0
Return the runtime function for optimized setting properties.
virtual llvm::Value * GetSelector(CodeGenFunction &CGF, Selector Sel)=0
Get a selector for the specified name and type values.
virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generates prologue for direct Objective-C Methods.
virtual llvm::Value * EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
virtual llvm::FunctionCallee GetPropertyGetFunction()=0
Return the runtime function for getting properties.
virtual llvm::FunctionCallee GetSetStructFunction()=0
std::vector< const ObjCProtocolDecl * > GetRuntimeProtocolList(ObjCProtocolDecl::protocol_iterator begin, ObjCProtocolDecl::protocol_iterator end)
Walk the list of protocol references from a class, category or protocol to traverse the DAG formed fr...
virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S)=0
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
static AutoVarEmission invalid()
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, ObjCMethodDecl *MD, bool ctor)
void StartObjCMethod(const ObjCMethodDecl *MD, const ObjCContainerDecl *CD)
void EmitARCDestroyWeak(Address addr)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitARCMoveWeak(Address dst, Address src)
void generateObjCGetterBody(const ObjCImplementationDecl *classImpl, const ObjCPropertyImplDecl *propImpl, const ObjCMethodDecl *GetterMothodDecl, llvm::Constant *AtomicHelperFn)
llvm::Value * EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)
Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
llvm::Value * EmitObjCAutoreleasePoolPush()
llvm::Value * EmitARCRetainAutoreleaseNonBlock(llvm::Value *value)
void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr)
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
llvm::Value * EmitARCRetainAutoreleasedReturnValue(llvm::Value *value)
llvm::Value * EmitObjCAllocWithZone(llvm::Value *value, llvm::Type *returnType)
CleanupKind getARCCleanupKind()
Retrieves the default cleanup kind for an ARC cleanup.
bool shouldUseFusedARCCalls()
llvm::Value * EmitARCAutoreleaseReturnValue(llvm::Value *value)
void GenerateObjCMethod(const ObjCMethodDecl *OMD)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Value * EmitARCAutorelease(llvm::Value *value)
void EmitExtendGCLifetime(llvm::Value *object)
EmitExtendGCLifetime - Given a pointer to an Objective-C object, make sure it survives garbage collec...
void EmitARCNoopIntrinsicUse(ArrayRef< llvm::Value * > values)
llvm::Constant * GenerateObjCAtomicGetterCopyHelperFunction(const ObjCPropertyImplDecl *PID)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
void callCStructCopyConstructor(LValue Dst, LValue Src)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Value * EmitARCLoadWeakRetained(Address addr)
const LangOptions & getLangOpts() const
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
llvm::Value * EmitARCRetainAutorelease(QualType type, llvm::Value *value)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)
SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
llvm::Value * EmitObjCRetainNonBlock(llvm::Value *value, llvm::Type *returnType)
llvm::Value * EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType)
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
llvm::Value * EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored)
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::Type * ConvertTypeForMem(QualType T)
llvm::Value * EmitARCUnsafeUnretainedScalarExpr(const Expr *expr)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
void EmitAutoVarInit(const AutoVarEmission &emission)
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
llvm::Value * EmitARCRetainBlock(llvm::Value *value, bool mandatory)
QualType TypeOfSelfObject()
TypeOfSelfObject - Return type of object that this self represents.
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void EmitObjCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
llvm::Value * EmitARCLoadWeak(Address addr)
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
llvm::Value * EmitObjCAllocInit(llvm::Value *value, llvm::Type *resultType)
llvm::Value * EmitObjCCollectionLiteral(const Expr *E, const ObjCMethodDecl *MethodWithObjects)
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
llvm::BasicBlock * getInvokeDest()
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
llvm::Value * EmitARCRetainAutoreleaseReturnValue(llvm::Value *value)
void EmitARCCopyWeak(Address dst, Address src)
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
CGDebugInfo * getDebugInfo()
LValue EmitDeclRefLValue(const DeclRefExpr *E)
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr)
llvm::Value * EmitARCRetainAutoreleaseScalarExpr(const Expr *expr)
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * EmitARCRetain(QualType type, llvm::Value *value)
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
llvm::Value * EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
Address CreateMemTemp(QualType T, const Twine &Name="tmp", Address *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
llvm::Constant * GenerateObjCAtomicSetterCopyHelperFunction(const ObjCPropertyImplDecl *PID)
void emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr)
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
void callCStructMoveAssignmentOperator(LValue Dst, LValue Src)
void EmitAutoVarCleanups(const AutoVarEmission &emission)
static Destroyer destroyARCWeak
void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S)
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
CleanupKind getCleanupKind(QualType::DestructionKind kind)
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Value * EmitObjCMRRAutoreleasePoolPush()
llvm::Type * ConvertType(QualType T)
CodeGenTypes & getTypes() const
void EmitARCInitWeak(Address addr, llvm::Value *value)
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
void generateObjCSetterBody(const ObjCImplementationDecl *classImpl, const ObjCPropertyImplDecl *propImpl, llvm::Constant *AtomicHelperFn)
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
static Destroyer destroyARCStrongPrecise
void EmitARCIntrinsicUse(ArrayRef< llvm::Value * > values)
void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S)
void EmitReturnStmt(const ReturnStmt &S)
AggValueSlot::Overlap_t getOverlapForReturnValue()
Determine whether a return value slot may overlap some other object.
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
llvm::Value * EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr)
void GenerateObjCSetter(ObjCImplementationDecl *IMP, const ObjCPropertyImplDecl *PID)
GenerateObjCSetter - Synthesize an Objective-C property setter function for the given property.
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
void GenerateObjCGetter(ObjCImplementationDecl *IMP, const ObjCPropertyImplDecl *PID)
GenerateObjCGetter - Synthesize an Objective-C property getter function.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
static Destroyer destroyARCStrongImprecise
LValue EmitLValueForIvar(QualType ObjectTy, llvm::Value *Base, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)
llvm::Value * EmitObjCAlloc(llvm::Value *value, llvm::Type *returnType)
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs=std::nullopt)
EmitStmt - Emit the code for the statement.
void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
static Destroyer emitARCIntrinsicUse
void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)
void EmitObjCAtTryStmt(const ObjCAtTryStmt &S)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
This class organizes the cross-function state that is used while generating LLVM code.
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
llvm::Constant * getAtomicGetterHelperFnMap(QualType Ty)
const LangOptions & getLangOpts() const
QualType getObjCFastEnumerationStateType()
Retrieve the record type that describes the state of an Objective-C fast enumeration loop (for....
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::FunctionCallee IsOSVersionAtLeastFn
const llvm::DataLayout & getDataLayout() const
ObjCEntrypoints & getObjCEntrypoints() const
const llvm::Triple & getTriple() const
void setAtomicSetterHelperFnMap(QualType Ty, llvm::Constant *Fn)
llvm::Constant * getAtomicSetterHelperFnMap(QualType Ty)
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
ASTContext & getContext() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
void setAtomicGetterHelperFnMap(QualType Ty, llvm::Constant *Fn)
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
llvm::FunctionCallee IsPlatformVersionAtLeastFn
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character.
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.