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);
225 assert(InterfacePointerType &&
"Unexpected InterfacePointerType - null");
229 llvm::Value *Receiver = Runtime.
GetClass(*
this, Class);
234 Receiver, Args, Class, MethodWithObjects);
240 if (TrackNeededObjects) {
281 if (ExpLLVMTy ==
Result.getScalarVal()->getType())
301 if (
auto opaque = dyn_cast<OpaqueValueExpr>(receiver)) {
302 if (opaque->getSourceExpr())
307 if (!ice || ice->
getCastKind() != CK_LValueToRValue)
return true;
311 if (
auto opaque = dyn_cast<OpaqueValueExpr>(receiver)) {
312 if (opaque->getSourceExpr())
321 if (isa<MemberExpr>(receiver) || isa<ObjCIvarRefExpr>(receiver))
326 if (!declRef)
return true;
328 if (!var)
return true;
333 !var->
hasAttr<ObjCPreciseLifetimeAttr>());
346 llvm_unreachable(
"invalid receiver kind");
354 if (
auto CE = dyn_cast<CastExpr>(E)) {
355 if (CE->getCastKind() == CK_LValueToRValue) {
357 return CE->getSubExpr();
381 bool isClassMessage) {
383 if (!CGM.getCodeGenOpts().ObjCConvertMessagesToRuntimeCalls)
386 auto &Runtime = CGM.getLangOpts().ObjCRuntime;
389 if (isClassMessage &&
390 Runtime.shouldUseRuntimeFunctionsForAlloc() &&
399 Args.size() == 1 && Args.front().getType()->isPointerType() &&
401 const llvm::Value* arg = Args.front().getKnownRValue().getScalarVal();
402 if (isa<llvm::ConstantPointerNull>(arg))
413 Runtime.shouldUseARCFunctionsForRetainRelease())
420 Runtime.shouldUseARCFunctionsForRetainRelease())
427 Runtime.shouldUseARCFunctionsForRetainRelease()) {
443 bool isClassMessage) {
444 if (std::optional<llvm::Value *> SpecializedResult =
446 Sel, Method, isClassMessage)) {
455 llvm::UniqueVector<const ObjCProtocolDecl *> &PDs) {
462 for (
const auto *ParentPD : PD->
protocols())
466std::vector<const ObjCProtocolDecl *>
469 std::vector<const ObjCProtocolDecl *> RuntimePds;
472 for (; begin != end; ++begin) {
473 const auto *It = *begin;
474 const auto *Can = It->getCanonicalDecl();
475 if (Can->isNonRuntimeProtocol())
476 NonRuntimePDs.insert(Can);
478 RuntimePds.push_back(Can);
482 if (NonRuntimePDs.empty())
489 llvm::UniqueVector<const ObjCProtocolDecl *> FirstImpliedProtos;
490 for (
const auto *PD : NonRuntimePDs)
496 for (
const auto *PD : RuntimePds) {
497 const auto *Can = PD->getCanonicalDecl();
498 AllImpliedProtocols.insert(Can);
499 Can->getImpliedProtocols(AllImpliedProtocols);
505 for (
const auto *PD : FirstImpliedProtos) {
506 PD->getImpliedProtocols(AllImpliedProtocols);
513 for (
const auto *PD : FirstImpliedProtos) {
514 if (!AllImpliedProtocols.contains(PD)) {
515 RuntimePds.push_back(PD);
525static std::optional<llvm::Value *>
528 if (!Runtime.shouldUseRuntimeFunctionForCombinedAllocInit())
544 Selector SubSel = SubOME->getSelector();
546 if (!SubOME->getType()->isObjCObjectPointerType() ||
550 llvm::Value *Receiver =
nullptr;
551 switch (SubOME->getReceiverKind()) {
553 if (!SubOME->getInstanceReceiver()->getType()->isObjCClassType())
559 QualType ReceiverType = SubOME->getClassReceiver();
562 assert(ID &&
"null interface should be impossible here");
606 method->
hasAttr<NSConsumesSelfAttr>());
609 bool isSuperMessage =
false;
610 bool isClassMessage =
false;
614 llvm::Value *Receiver =
nullptr;
622 Receiver = ter.getPointer();
623 if (ter.getInt()) retainSelf =
false;
631 assert(OID &&
"Invalid Objective-C class message send");
632 Receiver = Runtime.
GetClass(*
this, OID);
633 isClassMessage =
true;
640 isSuperMessage =
true;
646 isSuperMessage =
true;
647 isClassMessage =
true;
658 method->
hasAttr<ObjCReturnsInnerPointerAttr>() &&
674 if (isDelegateInit) {
676 "delegate init calls should only be marked in ARC");
685 if (isSuperMessage) {
688 bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->
getDeclContext());
700 *
this, Return, ResultType, E->
getSelector(), Receiver, Args, OID,
701 method, isClassMessage);
706 if (isDelegateInit) {
714 newSelf =
Builder.CreateBitCast(newSelf, selfTy);
731 bool isCategory = isa<ObjCCategoryImplDecl>(impl);
758 if (OMD->
hasAttr<NoDebugAttr>())
765 Fn->setVisibility(llvm::Function::HiddenVisibility);
798 if (ident->
isStr(
"dealloc"))
811 assert(isa<CompoundStmt>(OMD->
getBody()));
820 bool isAtomic,
bool hasStrong) {
861 llvm::Triple::ArchType
arch) {
871 class PropertyImplStrategy {
883 SetPropertyAndExpressionGet,
893 StrategyKind
getKind()
const {
return StrategyKind(Kind); }
895 bool hasStrongMember()
const {
return HasStrong; }
896 bool isAtomic()
const {
return IsAtomic; }
897 bool isCopy()
const {
return IsCopy; }
899 CharUnits getIvarSize()
const {
return IvarSize; }
900 CharUnits getIvarAlignment()
const {
return IvarAlignment; }
907 unsigned IsAtomic : 1;
909 unsigned HasStrong : 1;
917PropertyImplStrategy::PropertyImplStrategy(
CodeGenModule &CGM,
930 IvarSize = TInfo.
Width;
931 IvarAlignment = TInfo.Align;
937 Kind = IsAtomic ? GetSetProperty : SetPropertyAndExpressionGet;
950 }
else if (CGM.
getLangOpts().ObjCAutoRefCount && !IsAtomic) {
960 Kind = SetPropertyAndExpressionGet;
966 }
else if (!IsAtomic) {
967 Kind = SetPropertyAndExpressionGet;
972 Kind = GetSetProperty;
1003 HasStrong =
recordType->getDecl()->hasObjectMember();
1018 if (!IvarSize.isPowerOfTwo()) {
1023 llvm::Triple::ArchType
arch =
1051 llvm::Constant *AtomicHelperFn =
1054 assert(OMD &&
"Invalid call to generate getter (empty method)");
1064 if (!getter)
return true;
1076 if (
const CXXConstructExpr *construct = dyn_cast<CXXConstructExpr>(getter))
1077 return (construct->getConstructor()->isTrivial());
1081 assert(isa<ExprWithCleanups>(getter));
1088 llvm::Value *returnAddr,
1090 llvm::Constant *AtomicHelperFn) {
1099 llvm::Value *ivarAddr =
1108 llvm::FunctionCallee copyCppAtomicObjectFn =
1129 return llvm::PoisonValue::get(selType);
1139 llvm::Constant *AtomicHelperFn) {
1144 if (!AtomicHelperFn) {
1159 if (!AtomicHelperFn) {
1168 ivar, AtomicHelperFn);
1178 PropertyImplStrategy strategy(
CGM, propImpl);
1179 switch (strategy.getKind()) {
1180 case PropertyImplStrategy::Native: {
1182 if (strategy.getIvarSize().isZero())
1190 llvm::Type *bitcastType = llvm::Type::getIntNTy(
getLLVMContext(), ivarSize);
1196 load->setAtomic(llvm::AtomicOrdering::Unordered);
1203 llvm::Value *ivarVal = load;
1204 if (ivarSize > retTySize) {
1205 bitcastType = llvm::Type::getIntNTy(
getLLVMContext(), retTySize);
1206 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 *castType = llvm::Type::getIntNTy(
1499 store->setAtomic(llvm::AtomicOrdering::Unordered);
1503 case PropertyImplStrategy::GetSetProperty:
1504 case PropertyImplStrategy::SetPropertyAndExpressionGet: {
1506 llvm::FunctionCallee setOptimizedPropertyFn =
nullptr;
1507 llvm::FunctionCallee setPropertyFn =
nullptr;
1510 setOptimizedPropertyFn =
1512 strategy.isAtomic(), strategy.isCopy());
1513 if (!setOptimizedPropertyFn) {
1520 if (!setPropertyFn) {
1531 llvm::Value *ivarOffset =
1540 if (setOptimizedPropertyFn) {
1563 case PropertyImplStrategy::CopyStruct:
1567 case PropertyImplStrategy::Expression:
1580 &selfLoad,
true,
true);
1594 if (ivarRef.getType()->isObjCObjectPointerType()) {
1595 if (argLoad.getType()->isObjCObjectPointerType())
1597 else if (argLoad.getType()->isBlockPointerType())
1598 argCK = CK_BlockPointerToObjCPointerCast;
1600 argCK = CK_CPointerToObjCPointerCast;
1601 }
else if (ivarRef.getType()->isBlockPointerType()) {
1602 if (argLoad.getType()->isBlockPointerType())
1605 argCK = CK_AnyPointerToBlockPointerCast;
1606 }
else if (ivarRef.getType()->isPointerType()) {
1608 }
else if (argLoad.getType()->isAtomicType() &&
1609 !ivarRef.getType()->isAtomicType()) {
1610 argCK = CK_AtomicToNonAtomic;
1611 }
else if (!argLoad.getType()->isAtomicType() &&
1612 ivarRef.getType()->isAtomicType()) {
1613 argCK = CK_NonAtomicToAtomic;
1617 Expr *finalArg = &argLoad;
1618 if (!
getContext().hasSameUnqualifiedType(ivarRef.getType(),
1620 finalArg = &argCast;
1623 getContext(), &ivarRef, finalArg, BO_Assign, ivarRef.getType(),
1634 llvm::Constant *AtomicHelperFn =
1637 assert(OMD &&
"Invalid call to generate setter (empty method)");
1650 CodeGenFunction::Destroyer *destroyer;
1651 bool useEHCleanupForArray;
1653 DestroyIvar(llvm::Value *addr,
const ObjCIvarDecl *ivar,
1654 CodeGenFunction::Destroyer *destroyer,
1655 bool useEHCleanupForArray)
1656 : addr(addr), ivar(ivar), destroyer(destroyer),
1657 useEHCleanupForArray(useEHCleanupForArray) {}
1663 flags.isForNormalCleanup() && useEHCleanupForArray);
1678 CodeGenFunction::RunCleanupsScope scope(CGF);
1689 if (!dtorKind)
continue;
1705 CGF.
EHStack.pushCleanup<DestroyIvar>(cleanupKind, self, ivar, destroyer,
1709 assert(scope.requiresCleanups() &&
"nothing to do in .cxx_destruct?");
1723 for (
const auto *IvarInit : IMP->
inits()) {
1737 llvm::Value *SelfAsId =
1765 llvm::FunctionCallee EnumerationMutationFnPtr =
1767 if (!EnumerationMutationFnPtr) {
1778 RunCleanupsScope ForScope(*
this);
1782 if (
const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement()))
1793 static const unsigned NumItems = 16;
1806 llvm::APInt(32, NumItems),
nullptr,
1811 llvm::Value *Collection;
1842 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumItems);
1849 FastEnumSel, Collection, Args);
1852 llvm::Value *initialBufferLimit = CountRV.
getScalarVal();
1857 llvm::Value *zero = llvm::Constant::getNullValue(NSUIntegerTy);
1864 Builder.CreateICmpEQ(initialBufferLimit, zero,
"iszero"), EmptyBB,
1874 Address StateMutationsPtrPtr =
1876 llvm::Value *StateMutationsPtr
1880 llvm::Value *initialMutations =
1890 llvm::PHINode *index =
Builder.CreatePHI(NSUIntegerTy, 3,
"forcoll.index");
1891 index->addIncoming(zero, LoopInitBB);
1894 llvm::PHINode *count =
Builder.CreatePHI(NSUIntegerTy, 3,
"forcoll.count");
1895 count->addIncoming(initialBufferLimit, LoopInitBB);
1903 llvm::Value *currentMutations
1908 llvm::BasicBlock *WasNotMutatedBB =
createBasicBlock(
"forcoll.notmutated");
1910 Builder.CreateCondBr(
Builder.CreateICmpEQ(currentMutations, initialMutations),
1911 WasNotMutatedBB, WasMutatedBB);
1917 Builder.CreateBitCast(Collection, ObjCIdType);
1930 RunCleanupsScope elementVariableScope(*
this);
1931 bool elementIsVariable;
1934 if (
const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
1938 const VarDecl *D = cast<VarDecl>(SD->getSingleDecl());
1943 elementIsVariable =
true;
1948 elementLValue =
LValue();
1949 elementType = cast<Expr>(S.getElement())->getType();
1950 elementIsVariable =
false;
1952 llvm::Type *convertedElementType =
ConvertType(elementType);
1959 llvm::Value *EnumStateItems =
1964 ObjCIdType, EnumStateItems, index,
"currentitem.ptr");
1965 llvm::Value *CurrentItem =
1979 SanitizerScope SanScope(
this);
1981 assert(InterfaceTy->
getDecl() &&
"No decl for ObjC interface type");
1987 llvm::Value *IsClass =
1990 IsKindOfClassSel, CurrentItem,
1993 llvm::Constant *StaticData[] = {
1996 EmitCheck({{IsClass, SanitizerKind::ObjCCast}},
1997 SanitizerHandler::InvalidObjCCast,
2003 CurrentItem =
Builder.CreateBitCast(CurrentItem, convertedElementType,
2008 if (!elementIsVariable) {
2009 elementLValue =
EmitLValue(cast<Expr>(S.getElement()));
2018 if (elementIsVariable)
2022 BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
2024 RunCleanupsScope
Scope(*
this);
2027 BreakContinueStack.pop_back();
2030 elementVariableScope.ForceCleanup();
2038 llvm::Value *indexPlusOne =
2039 Builder.CreateAdd(index, llvm::ConstantInt::get(NSUIntegerTy, 1));
2046 Builder.CreateICmpULT(indexPlusOne, count), LoopBodyBB, FetchMoreBB,
2049 index->addIncoming(indexPlusOne, AfterBody.getBlock());
2050 count->addIncoming(count, AfterBody.getBlock());
2058 FastEnumSel, Collection, Args);
2064 index->addIncoming(zero,
Builder.GetInsertBlock());
2065 count->addIncoming(refetchCount,
Builder.GetInsertBlock());
2068 EmptyBB, LoopBodyBB);
2073 if (!elementIsVariable) {
2076 llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
2077 elementLValue =
EmitLValue(cast<Expr>(S.getElement()));
2084 ForScope.ForceCleanup();
2103 CallObjCRelease(llvm::Value *
object) :
object(
object) {}
2116 llvm::Value *
object) {
2124 llvm::Value *value) {
2150 if (
auto *F = dyn_cast<llvm::Function>(RTF)) {
2156 F->setLinkage(llvm::Function::ExternalWeakLinkage);
2162 llvm::FunctionCallee RTF) {
2178 llvm::Function *&fn, llvm::Intrinsic::ID IntID,
2179 llvm::CallInst::TailCallKind tailKind = llvm::CallInst::TCK_None) {
2180 if (isa<llvm::ConstantPointerNull>(value))
2187 llvm::Type *origType = returnType ? returnType : value->getType();
2192 call->setTailCallKind(tailKind);
2195 return CGF.
Builder.CreateBitCast(call, origType);
2201 llvm::Function *&fn,
2202 llvm::Intrinsic::ID IntID) {
2213 llvm::Function *&fn,
2214 llvm::Intrinsic::ID IntID,
2221 llvm::Type *origType = value->getType();
2223 llvm::Value *args[] = {
2229 if (ignored)
return nullptr;
2231 return CGF.
Builder.CreateBitCast(result, origType);
2237 llvm::Function *&fn,
2238 llvm::Intrinsic::ID IntID) {
2244 llvm::Value *args[] = {
2256 llvm::Type *returnType,
2257 llvm::FunctionCallee &fn,
2259 if (isa<llvm::ConstantPointerNull>(value))
2263 llvm::FunctionType *fnType =
2268 if (llvm::Function *f = dyn_cast<llvm::Function>(fn.getCallee()))
2269 if (fnName ==
"objc_retain")
2270 f->addFnAttr(llvm::Attribute::NonLazyBind);
2274 llvm::Type *origType = returnType ? returnType : value->getType();
2282 if (fnName ==
"objc_autorelease")
2283 if (
auto *Call = dyn_cast<llvm::CallInst>(Inst))
2284 Call->setTailCall();
2287 return CGF.
Builder.CreateBitCast(Inst, origType);
2294 if (
type->isBlockPointerType())
2305 llvm::Intrinsic::objc_retain);
2319 llvm::Intrinsic::objc_retainBlock);
2325 if (!mandatory && isa<llvm::Instruction>(result)) {
2326 llvm::CallInst *call
2327 = cast<llvm::CallInst>(result->stripPointerCasts());
2328 assert(call->getCalledOperand() ==
2331 call->setMetadata(
"clang.arc.copy_on_escape",
2332 llvm::MDNode::get(
Builder.getContext(), std::nullopt));
2341 llvm::InlineAsm *&marker
2349 if (assembly.empty()) {
2354 llvm::FunctionType *
type =
2355 llvm::FunctionType::get(CGF.
VoidTy,
false);
2357 marker = llvm::InlineAsm::get(
type, assembly,
"",
true);
2363 const char *retainRVMarkerKey = llvm::objcarc::getRVMarkerModuleFlagStr();
2364 if (!CGF.
CGM.
getModule().getModuleFlag(retainRVMarkerKey)) {
2367 retainRVMarkerKey, str);
2374 CGF.
Builder.CreateCall(marker, std::nullopt,
2388 llvm::Function *&EP = IsRetainRV
2391 llvm::Intrinsic::ID IID =
2392 IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue
2393 : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;
2396 llvm::Triple::ArchType Arch = CGF.
CGM.
getTriple().getArch();
2401 (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::x86_64)) {
2402 llvm::Value *bundleArgs[] = {EP};
2403 llvm::OperandBundleDef OB(
"clang.arc.attachedcall", bundleArgs);
2404 auto *oldCall = cast<llvm::CallBase>(value);
2405 llvm::CallBase *newCall = llvm::CallBase::addOperandBundle(
2406 oldCall, llvm::LLVMContext::OB_clang_arc_attachedcall, OB, oldCall);
2407 newCall->copyMetadata(*oldCall);
2408 oldCall->replaceAllUsesWith(newCall);
2409 oldCall->eraseFromParent();
2416 llvm::CallInst::TailCallKind tailKind =
2417 isNoTail ? llvm::CallInst::TCK_NoTail : llvm::CallInst::TCK_None;
2447 if (isa<llvm::ConstantPointerNull>(value))
return;
2460 call->setMetadata(
"clang.imprecise_release",
2461 llvm::MDNode::get(
Builder.getContext(), std::nullopt));
2497 llvm::Value *args[] = {
2503 if (ignored)
return nullptr;
2511 llvm::Value *newValue,
2514 bool isBlock =
type->isBlockPointerType();
2548 llvm::Intrinsic::objc_autorelease);
2557 llvm::Intrinsic::objc_autoreleaseReturnValue,
2558 llvm::CallInst::TCK_Tail);
2567 llvm::Intrinsic::objc_retainAutoreleaseReturnValue,
2568 llvm::CallInst::TCK_Tail);
2577 llvm::Value *value) {
2578 if (!
type->isBlockPointerType())
2581 if (isa<llvm::ConstantPointerNull>(value))
return value;
2583 llvm::Type *origType = value->getType();
2587 return Builder.CreateBitCast(value, origType);
2596 llvm::Intrinsic::objc_retainAutorelease);
2604 llvm::Intrinsic::objc_loadWeak);
2611 llvm::Intrinsic::objc_loadWeakRetained);
2621 llvm::Intrinsic::objc_storeWeak, ignored);
2633 if (isa<llvm::ConstantPointerNull>(value) &&
2641 llvm::Intrinsic::objc_initWeak,
true);
2660 llvm::Intrinsic::objc_moveWeak);
2669 llvm::Intrinsic::objc_copyWeak);
2704 llvm::FunctionCallee &fn =
2707 llvm::FunctionType *fnType =
2739 AllocSel, Receiver, Args);
2748 InitSel, Receiver, Args);
2755 llvm::Type *resultType) {
2764 llvm::Type *resultType) {
2767 "objc_allocWithZone");
2771 llvm::Type *resultType) {
2814 llvm::Type *returnType) {
2816 *
this, value, returnType,
2818 "objc_autorelease");
2824 llvm::Type *returnType) {
2826 *
this, value, returnType,
2834 if (isa<llvm::ConstantPointerNull>(value))
return;
2836 llvm::FunctionCallee &fn =
2839 llvm::FunctionType *fnType =
2844 if (llvm::Function *f = dyn_cast<llvm::Function>(fn.getCallee()))
2845 f->addFnAttr(llvm::Attribute::NonLazyBind);
2855 call->setMetadata(
"clang.imprecise_release",
2856 llvm::MDNode::get(
Builder.getContext(), std::nullopt));
2864 CallObjCAutoreleasePoolObject(llvm::Value *token) :
Token(token) {}
2873 CallObjCMRRAutoreleasePoolObject(llvm::Value *token) :
Token(token) {}
2900 llvm_unreachable(
"impossible lifetime!");
2906 llvm::Value *result;
2926 !
type.isConstQualified() &&
2945 !
type.isVolatileQualified() &&
2947 isa<BinaryOperator>(e) &&
2948 cast<BinaryOperator>(e)->getOpcode() == BO_Assign)
2954 if (
const auto *decl_expr = dyn_cast<DeclRefExpr>(e)) {
2965 llvm::Value *value)>
2976 CGBuilderTy::InsertPoint ip = CGF.
Builder.saveIP();
2977 auto *callBase = dyn_cast<llvm::CallBase>(value);
2979 if (callBase && llvm::objcarc::hasAttachedCallOpBundle(callBase)) {
2981 value = doFallback(CGF, value);
2982 }
else if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(value)) {
2984 CGF.
Builder.SetInsertPoint(call->getParent(),
2985 ++llvm::BasicBlock::iterator(call));
2986 value = doAfterCall(CGF, value);
2987 }
else if (llvm::InvokeInst *invoke = dyn_cast<llvm::InvokeInst>(value)) {
2989 llvm::BasicBlock *BB = invoke->getNormalDest();
2990 CGF.
Builder.SetInsertPoint(BB, BB->begin());
2991 value = doAfterCall(CGF, value);
2995 }
else if (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(value)) {
2998 CGF.
Builder.SetInsertPoint(bitcast->getParent(), bitcast->getIterator());
2999 llvm::Value *operand = bitcast->getOperand(0);
3001 bitcast->setOperand(0, operand);
3004 auto *phi = dyn_cast<llvm::PHINode>(value);
3005 if (phi && phi->getNumIncomingValues() == 2 &&
3006 isa<llvm::ConstantPointerNull>(phi->getIncomingValue(1)) &&
3007 isa<llvm::CallBase>(phi->getIncomingValue(0))) {
3010 llvm::Value *inVal = phi->getIncomingValue(0);
3012 phi->setIncomingValue(0, inVal);
3018 value = doFallback(CGF, value);
3055 bool allowUnsafeClaim) {
3056 if (allowUnsafeClaim &&
3074 if (isa<BlockExpr>(e))
3078 switch (
cast->getCastKind()) {
3080 case CK_LValueToRValue:
3081 case CK_ARCReclaimReturnedObject:
3082 case CK_ARCConsumeObject:
3083 case CK_ARCProduceObject:
3092 case CK_AnyPointerToBlockPointerCast:
3104template <
typename Impl,
typename Result>
class ARCExprEmitter {
3107 Impl &asImpl() {
return *
static_cast<Impl*
>(
this); }
3112 Result visit(
const Expr *e);
3113 Result visitCastExpr(
const CastExpr *e);
3115 Result visitBlockExpr(
const BlockExpr *e);
3139template <
typename Impl,
typename Result>
3141ARCExprEmitter<Impl,Result>::visitPseudoObjectExpr(
const PseudoObjectExpr *E) {
3151 const Expr *semantic = *i;
3155 if (
const OpaqueValueExpr *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
3156 typedef CodeGenFunction::OpaqueValueMappingData OVMA;
3161 if (ov == resultExpr) {
3162 assert(!OVMA::shouldBindAsLValue(ov));
3163 result = asImpl().visit(ov->getSourceExpr());
3164 opaqueData = OVMA::bind(CGF, ov,
3169 opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
3171 opaques.push_back(opaqueData);
3175 }
else if (semantic == resultExpr) {
3176 result = asImpl().visit(semantic);
3180 CGF.EmitIgnoredExpr(semantic);
3185 for (
unsigned i = 0, e = opaques.size(); i != e; ++i)
3186 opaques[i].unbind(CGF);
3191template <
typename Impl,
typename Result>
3192Result ARCExprEmitter<Impl, Result>::visitBlockExpr(
const BlockExpr *e) {
3194 return asImpl().visitExpr(e);
3197template <
typename Impl,
typename Result>
3198Result ARCExprEmitter<Impl,Result>::visitCastExpr(
const CastExpr *e) {
3206 case CK_CPointerToObjCPointerCast:
3207 case CK_BlockPointerToObjCPointerCast:
3208 case CK_AnyPointerToBlockPointerCast:
3210 llvm::Type *resultType = CGF.ConvertType(e->
getType());
3213 return asImpl().emitBitCast(result, resultType);
3217 case CK_LValueToRValue:
3218 return asImpl().visitLValueToRValue(e->
getSubExpr());
3219 case CK_ARCConsumeObject:
3220 return asImpl().visitConsumeObject(e->
getSubExpr());
3221 case CK_ARCExtendBlockObject:
3222 return asImpl().visitExtendBlockObject(e->
getSubExpr());
3223 case CK_ARCReclaimReturnedObject:
3224 return asImpl().visitReclaimReturnedObject(e->
getSubExpr());
3228 return asImpl().visitExpr(e);
3232template <
typename Impl,
typename Result>
3234ARCExprEmitter<Impl,Result>::visitBinaryOperator(
const BinaryOperator *e) {
3237 CGF.EmitIgnoredExpr(e->
getLHS());
3238 CGF.EnsureInsertPoint();
3239 return asImpl().visit(e->
getRHS());
3242 return asImpl().visitBinAssign(e);
3245 return asImpl().visitExpr(e);
3249template <
typename Impl,
typename Result>
3253 return asImpl().visitBinAssignUnsafeUnretained(e);
3256 return asImpl().visitBinAssignWeak(e);
3259 return asImpl().visitBinAssignAutoreleasing(e);
3262 return asImpl().visitBinAssignStrong(e);
3265 return asImpl().visitExpr(e);
3267 llvm_unreachable(
"bad ObjC ownership qualifier");
3272template <
typename Impl,
typename Result>
3273Result ARCExprEmitter<Impl,Result>::
3282 CGF.EmitStoreThroughLValue(
RValue::get(asImpl().getValueOfResult(result)),
3288template <
typename Impl,
typename Result>
3290ARCExprEmitter<Impl,Result>::visitBinAssignAutoreleasing(
const BinaryOperator *e) {
3291 return asImpl().visitExpr(e);
3294template <
typename Impl,
typename Result>
3296ARCExprEmitter<Impl,Result>::visitBinAssignWeak(
const BinaryOperator *e) {
3297 return asImpl().visitExpr(e);
3300template <
typename Impl,
typename Result>
3302ARCExprEmitter<Impl,Result>::visitBinAssignStrong(
const BinaryOperator *e) {
3303 return asImpl().visitExpr(e);
3307template <
typename Impl,
typename Result>
3308Result ARCExprEmitter<Impl,Result>::visit(
const Expr *e) {
3313 assert(!isa<ExprWithCleanups>(e));
3319 if (
const CastExpr *ce = dyn_cast<CastExpr>(e)) {
3320 return asImpl().visitCastExpr(ce);
3323 }
else if (
auto op = dyn_cast<BinaryOperator>(e)) {
3324 return asImpl().visitBinaryOperator(op);
3332 }
else if (isa<CallExpr>(e) ||
3333 (isa<ObjCMessageExpr>(e) &&
3334 !cast<ObjCMessageExpr>(e)->isDelegateInitCall())) {
3335 return asImpl().visitCall(e);
3338 }
else if (
const PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) {
3339 return asImpl().visitPseudoObjectExpr(pseudo);
3340 }
else if (
auto *be = dyn_cast<BlockExpr>(e))
3341 return asImpl().visitBlockExpr(be);
3343 return asImpl().visitExpr(e);
3349struct ARCRetainExprEmitter :
3350 public ARCExprEmitter<ARCRetainExprEmitter, TryEmitResult> {
3355 return result.getPointer();
3359 llvm::Value *value = result.getPointer();
3360 value = CGF.Builder.CreateBitCast(value, resultType);
3361 result.setPointer(value);
3372 llvm::Value *result = CGF.EmitScalarExpr(e);
3380 if (CGF.CGM.getCodeGenOpts().ObjCAvoidHeapifyLocalBlocks &&
3382 result.setInt(
true);
3390 llvm::Value *result;
3395 result = CGF.EmitScalarExpr(e);
3402 if (subresult.getInt()) {
3407 result = subresult.getPointer();
3411 result = CGF.EmitARCRetainBlock(result,
true);
3433 llvm::Value *result = CGF.EmitScalarExpr(e);
3441 return ARCRetainExprEmitter(CGF).visit(e);
3448 llvm::Value *value = result.getPointer();
3449 if (!result.getInt())
3461 RunCleanupsScope scope(*
this);
3466 llvm::Value *value = result.getPointer();
3467 if (!result.getInt())
3476 RunCleanupsScope scope(*
this);
3481 llvm::Value *value = result.getPointer();
3482 if (result.getInt())
3490 llvm::Value *result;
3498 result = subresult.getPointer();
3499 doRetain = !subresult.getInt();
3526struct ARCUnsafeUnretainedExprEmitter :
3527 public ARCExprEmitter<ARCUnsafeUnretainedExprEmitter, llvm::Value*> {
3529 ARCUnsafeUnretainedExprEmitter(
CodeGenFunction &CGF) : ARCExprEmitter(CGF) {}
3531 llvm::Value *getValueOfResult(llvm::Value *value) {
3535 llvm::Value *emitBitCast(llvm::Value *value, llvm::Type *resultType) {
3536 return CGF.Builder.CreateBitCast(value, resultType);
3539 llvm::Value *visitLValueToRValue(
const Expr *e) {
3540 return CGF.EmitScalarExpr(e);
3545 llvm::Value *visitConsumeObject(
const Expr *e) {
3546 llvm::Value *value = CGF.EmitScalarExpr(e);
3547 return CGF.EmitObjCConsumeObject(e->
getType(), value);
3552 llvm::Value *visitExtendBlockObject(
const Expr *e) {
3553 return CGF.EmitARCExtendBlockObject(e);
3557 llvm::Value *visitReclaimReturnedObject(
const Expr *e) {
3558 return CGF.EmitARCReclaimReturnedObject(e,
true);
3563 llvm::Value *visitCall(
const Expr *e) {
3564 return CGF.EmitScalarExpr(e);
3568 llvm::Value *visitExpr(
const Expr *e) {
3569 return CGF.EmitScalarExpr(e);
3576 return ARCUnsafeUnretainedExprEmitter(CGF).visit(e);
3586 RunCleanupsScope scope(*
this);
3593std::pair<LValue,llvm::Value*>
3609 return std::pair<LValue,llvm::Value*>(std::move(lvalue), value);
3612std::pair<LValue,llvm::Value*>
3617 llvm::Value *value = result.getPointer();
3619 bool hasImmediateRetain = result.getInt();
3626 hasImmediateRetain =
true;
3632 if (hasImmediateRetain) {
3640 return std::pair<LValue,llvm::Value*>(lvalue, value);
3643std::pair<LValue,llvm::Value*>
3650 return std::pair<LValue,llvm::Value*>(lvalue, value);
3663 RunCleanupsScope
Scope(*
this);
3672 for (
const auto *I : S.body())
3683 llvm::FunctionType *extenderType
3685 llvm::InlineAsm *extender = llvm::InlineAsm::get(extenderType,
3711 CharUnits Alignment =
C.getTypeAlignInChars(Ty);
3714 return llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
3722 llvm::Constant *HelperFn =
nullptr;
3736 SrcTy =
C.getPointerType(SrcTy);
3739 ArgTys.push_back(DestTy);
3740 ArgTys.push_back(SrcTy);
3741 QualType FunctionTy =
C.getFunctionType(ReturnTy, ArgTys, {});
3745 FunctionTy,
nullptr,
SC_Static,
false,
false,
false);
3753 args.push_back(Params[0] = DstDecl);
3758 args.push_back(Params[1] = SrcDecl);
3759 FD->setParams(Params);
3766 llvm::Function *Fn =
3767 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
3768 "__assign_helper_atomic_property_",
3785 Expr *Args[2] = {DST, SRC};
3794 HelperFn = llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
3809 CharUnits Alignment =
C.getTypeAlignInChars(Ty);
3812 return llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
3820 llvm::Constant *HelperFn =
nullptr;
3834 SrcTy =
C.getPointerType(SrcTy);
3837 ArgTys.push_back(DestTy);
3838 ArgTys.push_back(SrcTy);
3839 QualType FunctionTy =
C.getFunctionType(ReturnTy, ArgTys, {});
3843 FunctionTy,
nullptr,
SC_Static,
false,
false,
false);
3851 args.push_back(Params[0] = DstDecl);
3856 args.push_back(Params[1] = SrcDecl);
3857 FD->setParams(Params);
3864 llvm::Function *Fn = llvm::Function::Create(
3865 LTy, llvm::GlobalValue::InternalLinkage,
"__copy_helper_atomic_property_",
3883 ConstructorArgs.push_back(SRC);
3884 ConstructorArgs.append(std::next(CXXConstExpr->
arg_begin()),
3913 HelperFn = llvm::ConstantExpr::getBitCast(Fn,
VoidPtrTy);
3930 llvm::Value *Val =
Block;
3935 Val =
Result.getScalarVal();
3937 Ty, AutoreleaseSelector,
3939 Val =
Result.getScalarVal();
3944 switch (TT.getOS()) {
3945 case llvm::Triple::Darwin:
3946 case llvm::Triple::MacOSX:
3947 return llvm::MachO::PLATFORM_MACOS;
3948 case llvm::Triple::IOS:
3949 return llvm::MachO::PLATFORM_IOS;
3950 case llvm::Triple::TvOS:
3951 return llvm::MachO::PLATFORM_TVOS;
3952 case llvm::Triple::WatchOS:
3953 return llvm::MachO::PLATFORM_WATCHOS;
3954 case llvm::Triple::DriverKit:
3955 return llvm::MachO::PLATFORM_DRIVERKIT;
3962 const VersionTuple &Version) {
3969 auto EmitArgs = [&](
const VersionTuple &Version,
const llvm::Triple &TT) {
3970 std::optional<unsigned> Min = Version.getMinor(),
3971 SMin = Version.getSubminor();
3974 Args.push_back(llvm::ConstantInt::get(CGM.
Int32Ty, Version.getMajor()));
3975 Args.push_back(llvm::ConstantInt::get(CGM.
Int32Ty, Min.value_or(0)));
3976 Args.push_back(llvm::ConstantInt::get(CGM.
Int32Ty, SMin.value_or(0)));
3979 assert(!Version.empty() &&
"unexpected empty version");
3983 llvm::FunctionType *FTy = llvm::FunctionType::get(
3984 CGM.
Int32Ty, {CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty},
3990 llvm::Value *Check =
3992 return CGF.
Builder.CreateICmpNE(Check,
3993 llvm::Constant::getNullValue(CGM.
Int32Ty));
4003 llvm::FunctionType *FTy =
4009 std::optional<unsigned> Min = Version.getMinor(),
4010 SMin = Version.getSubminor();
4011 llvm::Value *Args[] = {
4012 llvm::ConstantInt::get(
CGM.
Int32Ty, Version.getMajor()),
4013 llvm::ConstantInt::get(
CGM.
Int32Ty, Min.value_or(0)),
4014 llvm::ConstantInt::get(
CGM.
Int32Ty, SMin.value_or(0))};
4016 llvm::Value *CallRes =
4019 return Builder.CreateICmpNE(CallRes, llvm::Constant::getNullValue(
Int32Ty));
4023 const llvm::Triple &TT,
const VersionTuple &
TargetVersion) {
4024 VersionTuple FoundationDroppedInVersion;
4025 switch (TT.getOS()) {
4026 case llvm::Triple::IOS:
4027 case llvm::Triple::TvOS:
4028 FoundationDroppedInVersion = VersionTuple(13);
4030 case llvm::Triple::WatchOS:
4031 FoundationDroppedInVersion = VersionTuple(6);
4033 case llvm::Triple::Darwin:
4034 case llvm::Triple::MacOSX:
4035 FoundationDroppedInVersion = VersionTuple(10, 15);
4037 case llvm::Triple::DriverKit:
4041 llvm_unreachable(
"Unexpected OS");
4046void CodeGenModule::emitAtAvailableLinkGuard() {
4062 llvm::Metadata *Args[2] = {llvm::MDString::get(Context,
"-framework"),
4063 llvm::MDString::get(Context,
"CoreFoundation")};
4064 LinkerOptionsMetadata.push_back(llvm::MDNode::get(Context, Args));
4067 llvm::FunctionType *FTy =
4069 llvm::FunctionCallee CFFunc =
4072 llvm::FunctionType *CheckFTy = llvm::FunctionType::get(
VoidTy, {},
false);
4074 CheckFTy,
"__clang_at_available_requires_core_foundation_framework",
4075 llvm::AttributeList(),
true);
4076 llvm::Function *CFLinkCheckFunc =
4077 cast<llvm::Function>(CFLinkCheckFuncRef.getCallee()->stripPointerCasts());
4078 if (CFLinkCheckFunc->empty()) {
4079 CFLinkCheckFunc->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
4080 CFLinkCheckFunc->setVisibility(llvm::GlobalValue::HiddenVisibility);
4082 CGF.Builder.SetInsertPoint(CGF.createBasicBlock(
"", CFLinkCheckFunc));
4083 CGF.EmitNounwindRuntimeCall(CFFunc,
4084 llvm::Constant::getNullValue(
VoidPtrTy));
4085 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.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
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 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.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
llvm::Constant * getPointer() const
Information for lazily generating a cleanup.
FunctionArgList - Type for representing both the decl and type of parameters to a function.