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));
68 const Expr *SubExpr =
E->getSubExpr();
70 if (
E->isExpressibleAsConstantInitializer()) {
72 return ConstEmitter.tryEmitAbstract(
E,
E->
getType());
75 assert(BoxingMethod->
isClassMethod() &&
"BoxingMethod must be a class method");
83 llvm::Value *Receiver = Runtime.
GetClass(*
this, ClassDecl);
92 if (ValueType->isObjCBoxableRecordType()) {
97 llvm::Value *BitCast =
Builder.CreateBitCast(
118 Args, ClassDecl, BoxingMethod);
129 DLE = cast<ObjCDictionaryLiteral>(
E);
135 StringRef ConstantName = ALE ?
"__NSArray0__" :
"__NSDictionary0__";
137 llvm::Constant *Constant =
141 cast<llvm::LoadInst>(Ptr)->setMetadata(
142 llvm::LLVMContext::MD_invariant_load,
164 bool TrackNeededObjects =
169 for (uint64_t i = 0; i < NumElements; i++) {
178 if (TrackNeededObjects) {
179 NeededObjects.push_back(value);
195 if (TrackNeededObjects) {
196 NeededObjects.push_back(keyValue);
197 NeededObjects.push_back(valueValue);
224 assert(InterfacePointerType &&
"Unexpected InterfacePointerType - null");
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;
331 return (var->hasLocalStorage() &&
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;
469 llvm::DenseSet<const ObjCProtocolDecl *> NonRuntimePDs;
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)
494 llvm::DenseSet<const ObjCProtocolDecl *> AllImpliedProtocols;
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");
579 bool isDelegateInit =
E->isDelegateInitCall();
605 method->
hasAttr<NSConsumesSelfAttr>());
608 bool isSuperMessage =
false;
609 bool isClassMessage =
false;
613 llvm::Value *Receiver =
nullptr;
614 switch (
E->getReceiverKind()) {
616 ReceiverType =
E->getInstanceReceiver()->
getType();
620 E->getInstanceReceiver());
621 Receiver = ter.getPointer();
622 if (ter.getInt()) retainSelf =
false;
628 ReceiverType =
E->getClassReceiver();
630 assert(OID &&
"Invalid Objective-C class message send");
631 Receiver = Runtime.
GetClass(*
this, OID);
632 isClassMessage =
true;
637 ReceiverType =
E->getSuperType();
639 isSuperMessage =
true;
643 ReceiverType =
E->getSuperType();
645 isSuperMessage =
true;
646 isClassMessage =
true;
657 method->
hasAttr<ObjCReturnsInnerPointerAttr>() &&
664 EmitCallArgs(Args, method,
E->arguments(), AbstractCallee(method));
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) {
857 llvm::Triple::ArchType
arch) {
867 class PropertyImplStrategy {
879 SetPropertyAndExpressionGet,
889 StrategyKind
getKind()
const {
return StrategyKind(
Kind); }
891 bool hasStrongMember()
const {
return HasStrong; }
892 bool isAtomic()
const {
return IsAtomic; }
893 bool isCopy()
const {
return IsCopy; }
895 CharUnits getIvarSize()
const {
return IvarSize; }
896 CharUnits getIvarAlignment()
const {
return IvarAlignment; }
902 LLVM_PREFERRED_TYPE(StrategyKind)
904 LLVM_PREFERRED_TYPE(
bool)
905 unsigned IsAtomic : 1;
906 LLVM_PREFERRED_TYPE(
bool)
908 LLVM_PREFERRED_TYPE(
bool)
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 =
1107 llvm::FunctionCallee copyCppAtomicObjectFn =
1128 return llvm::PoisonValue::get(selType);
1138 llvm::Constant *AtomicHelperFn) {
1143 if (!AtomicHelperFn) {
1151 ivar, 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);
1214 case PropertyImplStrategy::GetSetProperty: {
1215 llvm::FunctionCallee getPropertyFn =
1217 if (!getPropertyFn) {
1228 llvm::Value *ivarOffset =
1240 llvm::CallBase *CallInstruction;
1244 if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(CallInstruction))
1245 call->setTailCall();
1254 EmitReturnOfRValue(RV, propType);
1262 case PropertyImplStrategy::CopyStruct:
1264 strategy.hasStrongMember());
1267 case PropertyImplStrategy::Expression:
1268 case PropertyImplStrategy::SetPropertyAndExpressionGet: {
1307 value =
Builder.CreateBitCast(
1315 llvm_unreachable(
"bad evaluation kind");
1319 llvm_unreachable(
"bad @property implementation strategy!");
1331 llvm::Value *ivarAddr =
1370 llvm::Constant *AtomicHelperFn) {
1376 llvm::Value *ivarAddr =
1392 llvm::FunctionCallee fn =
1403 if (!setter)
return true;
1413 if (
CallExpr *call = dyn_cast<CallExpr>(setter)) {
1415 = dyn_cast_or_null<FunctionDecl>(call->getCalleeDecl()))
1416 if (callee->isTrivial())
1421 assert(isa<ExprWithCleanups>(setter));
1434 llvm::Constant *AtomicHelperFn) {
1440 if (!AtomicHelperFn) {
1459 if (!AtomicHelperFn)
1469 PropertyImplStrategy strategy(
CGM, propImpl);
1470 switch (strategy.getKind()) {
1471 case PropertyImplStrategy::Native: {
1473 if (strategy.getIvarSize().isZero())
1484 llvm::Type *castType = llvm::Type::getIntNTy(
1495 store->setAtomic(llvm::AtomicOrdering::Unordered);
1499 case PropertyImplStrategy::GetSetProperty:
1500 case PropertyImplStrategy::SetPropertyAndExpressionGet: {
1502 llvm::FunctionCallee setOptimizedPropertyFn =
nullptr;
1503 llvm::FunctionCallee setPropertyFn =
nullptr;
1506 setOptimizedPropertyFn =
1508 strategy.isAtomic(), strategy.isCopy());
1509 if (!setOptimizedPropertyFn) {
1516 if (!setPropertyFn) {
1527 llvm::Value *ivarOffset =
1536 if (setOptimizedPropertyFn) {
1559 case PropertyImplStrategy::CopyStruct:
1563 case PropertyImplStrategy::Expression:
1576 &selfLoad,
true,
true);
1590 if (ivarRef.getType()->isObjCObjectPointerType()) {
1591 if (argLoad.getType()->isObjCObjectPointerType())
1593 else if (argLoad.getType()->isBlockPointerType())
1594 argCK = CK_BlockPointerToObjCPointerCast;
1596 argCK = CK_CPointerToObjCPointerCast;
1597 }
else if (ivarRef.getType()->isBlockPointerType()) {
1598 if (argLoad.getType()->isBlockPointerType())
1601 argCK = CK_AnyPointerToBlockPointerCast;
1602 }
else if (ivarRef.getType()->isPointerType()) {
1604 }
else if (argLoad.getType()->isAtomicType() &&
1605 !ivarRef.getType()->isAtomicType()) {
1606 argCK = CK_AtomicToNonAtomic;
1607 }
else if (!argLoad.getType()->isAtomicType() &&
1608 ivarRef.getType()->isAtomicType()) {
1609 argCK = CK_NonAtomicToAtomic;
1613 Expr *finalArg = &argLoad;
1614 if (!
getContext().hasSameUnqualifiedType(ivarRef.getType(),
1616 finalArg = &argCast;
1619 getContext(), &ivarRef, finalArg, BO_Assign, ivarRef.getType(),
1630 llvm::Constant *AtomicHelperFn =
1633 assert(OMD &&
"Invalid call to generate setter (empty method)");
1646 CodeGenFunction::Destroyer *destroyer;
1647 bool useEHCleanupForArray;
1649 DestroyIvar(llvm::Value *addr,
const ObjCIvarDecl *ivar,
1650 CodeGenFunction::Destroyer *destroyer,
1651 bool useEHCleanupForArray)
1652 : addr(addr), ivar(ivar), destroyer(destroyer),
1653 useEHCleanupForArray(useEHCleanupForArray) {}
1659 flags.isForNormalCleanup() && useEHCleanupForArray);
1674 CodeGenFunction::RunCleanupsScope scope(CGF);
1685 if (!dtorKind)
continue;
1701 CGF.
EHStack.pushCleanup<DestroyIvar>(cleanupKind, self, ivar, destroyer,
1705 assert(scope.requiresCleanups() &&
"nothing to do in .cxx_destruct?");
1719 for (
const auto *IvarInit : IMP->
inits()) {
1733 llvm::Value *SelfAsId =
1761 llvm::FunctionCallee EnumerationMutationFnPtr =
1763 if (!EnumerationMutationFnPtr) {
1774 RunCleanupsScope ForScope(*
this);
1778 if (
const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement()))
1789 static const unsigned NumItems = 16;
1800 getContext().getObjCIdType(), llvm::APInt(32, NumItems),
nullptr,
1805 llvm::Value *Collection;
1834 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumItems);
1841 FastEnumSel, Collection, Args);
1844 llvm::Value *initialBufferLimit = CountRV.
getScalarVal();
1849 llvm::Value *zero = llvm::Constant::getNullValue(NSUIntegerTy);
1856 Builder.CreateICmpEQ(initialBufferLimit, zero,
"iszero"), EmptyBB,
1866 Address StateMutationsPtrPtr =
1868 llvm::Value *StateMutationsPtr
1872 llvm::Value *initialMutations =
1882 llvm::PHINode *index =
Builder.CreatePHI(NSUIntegerTy, 3,
"forcoll.index");
1883 index->addIncoming(zero, LoopInitBB);
1886 llvm::PHINode *count =
Builder.CreatePHI(NSUIntegerTy, 3,
"forcoll.count");
1887 count->addIncoming(initialBufferLimit, LoopInitBB);
1895 llvm::Value *currentMutations
1900 llvm::BasicBlock *WasNotMutatedBB =
createBasicBlock(
"forcoll.notmutated");
1902 Builder.CreateCondBr(
Builder.CreateICmpEQ(currentMutations, initialMutations),
1903 WasNotMutatedBB, WasMutatedBB);
1909 Builder.CreateBitCast(Collection, ObjCIdType);
1922 RunCleanupsScope elementVariableScope(*
this);
1923 bool elementIsVariable;
1926 if (
const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
1930 const VarDecl *
D = cast<VarDecl>(SD->getSingleDecl());
1934 elementType =
D->getType();
1935 elementIsVariable =
true;
1937 if (
D->isARCPseudoStrong())
1940 elementLValue =
LValue();
1941 elementType = cast<Expr>(S.getElement())->getType();
1942 elementIsVariable =
false;
1944 llvm::Type *convertedElementType =
ConvertType(elementType);
1951 llvm::Value *EnumStateItems =
1956 ObjCIdType, EnumStateItems, index,
"currentitem.ptr");
1957 llvm::Value *CurrentItem =
1971 SanitizerScope SanScope(
this);
1973 assert(InterfaceTy->
getDecl() &&
"No decl for ObjC interface type");
1979 llvm::Value *IsClass =
1982 IsKindOfClassSel, CurrentItem,
1985 llvm::Constant *StaticData[] = {
1988 EmitCheck({{IsClass, SanitizerKind::ObjCCast}},
1989 SanitizerHandler::InvalidObjCCast,
1995 CurrentItem =
Builder.CreateBitCast(CurrentItem, convertedElementType,
2000 if (!elementIsVariable) {
2001 elementLValue =
EmitLValue(cast<Expr>(S.getElement()));
2010 if (elementIsVariable)
2014 BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
2016 RunCleanupsScope
Scope(*
this);
2019 BreakContinueStack.pop_back();
2022 elementVariableScope.ForceCleanup();
2030 llvm::Value *indexPlusOne =
2031 Builder.CreateNUWAdd(index, llvm::ConstantInt::get(NSUIntegerTy, 1));
2038 Builder.CreateICmpULT(indexPlusOne, count), LoopBodyBB, FetchMoreBB,
2041 index->addIncoming(indexPlusOne, AfterBody.getBlock());
2042 count->addIncoming(count, AfterBody.getBlock());
2050 FastEnumSel, Collection, Args);
2056 index->addIncoming(zero,
Builder.GetInsertBlock());
2057 count->addIncoming(refetchCount,
Builder.GetInsertBlock());
2060 EmptyBB, LoopBodyBB);
2065 if (!elementIsVariable) {
2068 llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
2069 elementLValue =
EmitLValue(cast<Expr>(S.getElement()));
2076 ForScope.ForceCleanup();
2095 CallObjCRelease(llvm::Value *
object) : object(object) {}
2096 llvm::Value *object;
2108 llvm::Value *
object) {
2116 llvm::Value *value) {
2142 if (
auto *F = dyn_cast<llvm::Function>(RTF)) {
2148 F->setLinkage(llvm::Function::ExternalWeakLinkage);
2154 llvm::FunctionCallee RTF) {
2170 llvm::Function *&fn, llvm::Intrinsic::ID IntID,
2171 llvm::CallInst::TailCallKind tailKind = llvm::CallInst::TCK_None) {
2172 if (isa<llvm::ConstantPointerNull>(value))
2179 llvm::Type *origType = returnType ? returnType : value->getType();
2184 call->setTailCallKind(tailKind);
2187 return CGF.
Builder.CreateBitCast(call, origType);
2193 llvm::Function *&fn,
2194 llvm::Intrinsic::ID IntID) {
2205 llvm::Function *&fn,
2206 llvm::Intrinsic::ID IntID,
2213 llvm::Type *origType = value->getType();
2215 llvm::Value *args[] = {
2220 if (ignored)
return nullptr;
2222 return CGF.
Builder.CreateBitCast(result, origType);
2228 llvm::Function *&fn,
2229 llvm::Intrinsic::ID IntID) {
2235 llvm::Value *args[] = {
2246 llvm::Type *returnType,
2247 llvm::FunctionCallee &fn,
2249 if (isa<llvm::ConstantPointerNull>(value))
2253 llvm::FunctionType *fnType =
2258 if (llvm::Function *f = dyn_cast<llvm::Function>(fn.getCallee()))
2259 if (fnName ==
"objc_retain")
2260 f->addFnAttr(llvm::Attribute::NonLazyBind);
2264 llvm::Type *origType = returnType ? returnType : value->getType();
2272 if (fnName ==
"objc_autorelease")
2273 if (
auto *
Call = dyn_cast<llvm::CallInst>(Inst))
2274 Call->setTailCall();
2277 return CGF.
Builder.CreateBitCast(Inst, origType);
2284 if (
type->isBlockPointerType())
2295 llvm::Intrinsic::objc_retain);
2309 llvm::Intrinsic::objc_retainBlock);
2315 if (!mandatory && isa<llvm::Instruction>(result)) {
2316 llvm::CallInst *call
2317 = cast<llvm::CallInst>(result->stripPointerCasts());
2318 assert(call->getCalledOperand() ==
2321 call->setMetadata(
"clang.arc.copy_on_escape",
2322 llvm::MDNode::get(
Builder.getContext(), std::nullopt));
2331 llvm::InlineAsm *&marker
2339 if (assembly.empty()) {
2344 llvm::FunctionType *
type =
2345 llvm::FunctionType::get(CGF.
VoidTy,
false);
2347 marker = llvm::InlineAsm::get(
type, assembly,
"",
true);
2353 const char *retainRVMarkerKey = llvm::objcarc::getRVMarkerModuleFlagStr();
2354 if (!CGF.
CGM.
getModule().getModuleFlag(retainRVMarkerKey)) {
2357 retainRVMarkerKey, str);
2364 CGF.
Builder.CreateCall(marker, std::nullopt,
2378 llvm::Function *&EP = IsRetainRV
2381 llvm::Intrinsic::ID IID =
2382 IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue
2383 : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;
2386 llvm::Triple::ArchType Arch = CGF.
CGM.
getTriple().getArch();
2391 (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::x86_64)) {
2392 llvm::Value *bundleArgs[] = {EP};
2393 llvm::OperandBundleDef OB(
"clang.arc.attachedcall", bundleArgs);
2394 auto *oldCall = cast<llvm::CallBase>(value);
2395 llvm::CallBase *newCall = llvm::CallBase::addOperandBundle(
2396 oldCall, llvm::LLVMContext::OB_clang_arc_attachedcall, OB,
2397 oldCall->getIterator());
2398 newCall->copyMetadata(*oldCall);
2399 oldCall->replaceAllUsesWith(newCall);
2400 oldCall->eraseFromParent();
2407 llvm::CallInst::TailCallKind tailKind =
2408 isNoTail ? llvm::CallInst::TCK_NoTail : llvm::CallInst::TCK_None;
2438 if (isa<llvm::ConstantPointerNull>(value))
return;
2451 call->setMetadata(
"clang.imprecise_release",
2452 llvm::MDNode::get(
Builder.getContext(), std::nullopt));
2488 llvm::Value *args[] = {
2493 if (ignored)
return nullptr;
2501 llvm::Value *newValue,
2504 bool isBlock =
type->isBlockPointerType();
2538 llvm::Intrinsic::objc_autorelease);
2547 llvm::Intrinsic::objc_autoreleaseReturnValue,
2548 llvm::CallInst::TCK_Tail);
2557 llvm::Intrinsic::objc_retainAutoreleaseReturnValue,
2558 llvm::CallInst::TCK_Tail);
2567 llvm::Value *value) {
2568 if (!
type->isBlockPointerType())
2571 if (isa<llvm::ConstantPointerNull>(value))
return value;
2573 llvm::Type *origType = value->getType();
2577 return Builder.CreateBitCast(value, origType);
2586 llvm::Intrinsic::objc_retainAutorelease);
2594 llvm::Intrinsic::objc_loadWeak);
2601 llvm::Intrinsic::objc_loadWeakRetained);
2611 llvm::Intrinsic::objc_storeWeak, ignored);
2623 if (isa<llvm::ConstantPointerNull>(value) &&
2631 llvm::Intrinsic::objc_initWeak,
true);
2650 llvm::Intrinsic::objc_moveWeak);
2659 llvm::Intrinsic::objc_copyWeak);
2694 llvm::FunctionCallee &fn =
2697 llvm::FunctionType *fnType =
2729 AllocSel, Receiver, Args);
2738 InitSel, Receiver, Args);
2745 llvm::Type *resultType) {
2754 llvm::Type *resultType) {
2757 "objc_allocWithZone");
2761 llvm::Type *resultType) {
2804 llvm::Type *returnType) {
2806 *
this, value, returnType,
2808 "objc_autorelease");
2814 llvm::Type *returnType) {
2816 *
this, value, returnType,
2824 if (isa<llvm::ConstantPointerNull>(value))
return;
2826 llvm::FunctionCallee &fn =
2829 llvm::FunctionType *fnType =
2834 if (llvm::Function *f = dyn_cast<llvm::Function>(fn.getCallee()))
2835 f->addFnAttr(llvm::Attribute::NonLazyBind);
2845 call->setMetadata(
"clang.imprecise_release",
2846 llvm::MDNode::get(
Builder.getContext(), std::nullopt));
2854 CallObjCAutoreleasePoolObject(llvm::Value *token) :
Token(token) {}
2863 CallObjCMRRAutoreleasePoolObject(llvm::Value *token) :
Token(token) {}
2890 llvm_unreachable(
"impossible lifetime!");
2896 llvm::Value *result;
2916 !
type.isConstQualified() &&
2935 !
type.isVolatileQualified() &&
2937 isa<BinaryOperator>(e) &&
2938 cast<BinaryOperator>(e)->getOpcode() == BO_Assign)
2944 if (
const auto *decl_expr = dyn_cast<DeclRefExpr>(e)) {
2955 llvm::Value *value)>
2966 CGBuilderTy::InsertPoint ip = CGF.
Builder.saveIP();
2967 auto *callBase = dyn_cast<llvm::CallBase>(value);
2969 if (callBase && llvm::objcarc::hasAttachedCallOpBundle(callBase)) {
2971 value = doFallback(CGF, value);
2972 }
else if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(value)) {
2974 CGF.
Builder.SetInsertPoint(call->getParent(),
2975 ++llvm::BasicBlock::iterator(call));
2976 value = doAfterCall(CGF, value);
2977 }
else if (llvm::InvokeInst *invoke = dyn_cast<llvm::InvokeInst>(value)) {
2979 llvm::BasicBlock *BB = invoke->getNormalDest();
2980 CGF.
Builder.SetInsertPoint(BB, BB->begin());
2981 value = doAfterCall(CGF, value);
2985 }
else if (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(value)) {
2988 CGF.
Builder.SetInsertPoint(bitcast->getParent(), bitcast->getIterator());
2989 llvm::Value *operand = bitcast->getOperand(0);
2991 bitcast->setOperand(0, operand);
2994 auto *phi = dyn_cast<llvm::PHINode>(value);
2995 if (phi && phi->getNumIncomingValues() == 2 &&
2996 isa<llvm::ConstantPointerNull>(phi->getIncomingValue(1)) &&
2997 isa<llvm::CallBase>(phi->getIncomingValue(0))) {
3000 llvm::Value *inVal = phi->getIncomingValue(0);
3002 phi->setIncomingValue(0, inVal);
3008 value = doFallback(CGF, value);
3045 bool allowUnsafeClaim) {
3046 if (allowUnsafeClaim &&
3064 if (isa<BlockExpr>(e))
3068 switch (
cast->getCastKind()) {
3070 case CK_LValueToRValue:
3071 case CK_ARCReclaimReturnedObject:
3072 case CK_ARCConsumeObject:
3073 case CK_ARCProduceObject:
3082 case CK_AnyPointerToBlockPointerCast:
3094template <
typename Impl,
typename Result>
class ARCExprEmitter {
3097 Impl &asImpl() {
return *
static_cast<Impl*
>(
this); }
3102 Result visit(
const Expr *e);
3103 Result visitCastExpr(
const CastExpr *e);
3105 Result visitBlockExpr(
const BlockExpr *e);
3129template <
typename Impl,
typename Result>
3135 const Expr *resultExpr =
E->getResultExpr();
3140 i =
E->semantics_begin(), e =
E->semantics_end(); i != e; ++i) {
3141 const Expr *semantic = *i;
3145 if (
const OpaqueValueExpr *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
3146 typedef CodeGenFunction::OpaqueValueMappingData OVMA;
3151 if (ov == resultExpr) {
3152 assert(!OVMA::shouldBindAsLValue(ov));
3153 result = asImpl().visit(ov->getSourceExpr());
3154 opaqueData = OVMA::bind(CGF, ov,
3159 opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
3161 opaques.push_back(opaqueData);
3165 }
else if (semantic == resultExpr) {
3166 result = asImpl().visit(semantic);
3170 CGF.EmitIgnoredExpr(semantic);
3175 for (
unsigned i = 0, e = opaques.size(); i != e; ++i)
3176 opaques[i].unbind(CGF);
3181template <
typename Impl,
typename Result>
3182Result ARCExprEmitter<Impl, Result>::visitBlockExpr(
const BlockExpr *e) {
3184 return asImpl().visitExpr(e);
3187template <
typename Impl,
typename Result>
3188Result ARCExprEmitter<Impl,Result>::visitCastExpr(
const CastExpr *e) {
3196 case CK_CPointerToObjCPointerCast:
3197 case CK_BlockPointerToObjCPointerCast:
3198 case CK_AnyPointerToBlockPointerCast:
3200 llvm::Type *resultType = CGF.ConvertType(e->
getType());
3203 return asImpl().emitBitCast(result, resultType);
3207 case CK_LValueToRValue:
3208 return asImpl().visitLValueToRValue(e->
getSubExpr());
3209 case CK_ARCConsumeObject:
3210 return asImpl().visitConsumeObject(e->
getSubExpr());
3211 case CK_ARCExtendBlockObject:
3212 return asImpl().visitExtendBlockObject(e->
getSubExpr());
3213 case CK_ARCReclaimReturnedObject:
3214 return asImpl().visitReclaimReturnedObject(e->
getSubExpr());
3218 return asImpl().visitExpr(e);
3222template <
typename Impl,
typename Result>
3224ARCExprEmitter<Impl,Result>::visitBinaryOperator(
const BinaryOperator *e) {
3227 CGF.EmitIgnoredExpr(e->
getLHS());
3228 CGF.EnsureInsertPoint();
3229 return asImpl().visit(e->
getRHS());
3232 return asImpl().visitBinAssign(e);
3235 return asImpl().visitExpr(e);
3239template <
typename Impl,
typename Result>
3243 return asImpl().visitBinAssignUnsafeUnretained(e);
3246 return asImpl().visitBinAssignWeak(e);
3249 return asImpl().visitBinAssignAutoreleasing(e);
3252 return asImpl().visitBinAssignStrong(e);
3255 return asImpl().visitExpr(e);
3257 llvm_unreachable(
"bad ObjC ownership qualifier");
3262template <
typename Impl,
typename Result>
3263Result ARCExprEmitter<Impl,Result>::
3272 CGF.EmitStoreThroughLValue(
RValue::get(asImpl().getValueOfResult(result)),
3278template <
typename Impl,
typename Result>
3280ARCExprEmitter<Impl,Result>::visitBinAssignAutoreleasing(
const BinaryOperator *e) {
3281 return asImpl().visitExpr(e);
3284template <
typename Impl,
typename Result>
3286ARCExprEmitter<Impl,Result>::visitBinAssignWeak(
const BinaryOperator *e) {
3287 return asImpl().visitExpr(e);
3290template <
typename Impl,
typename Result>
3292ARCExprEmitter<Impl,Result>::visitBinAssignStrong(
const BinaryOperator *e) {
3293 return asImpl().visitExpr(e);
3297template <
typename Impl,
typename Result>
3298Result ARCExprEmitter<Impl,Result>::visit(
const Expr *e) {
3303 assert(!isa<ExprWithCleanups>(e));
3309 if (
const CastExpr *ce = dyn_cast<CastExpr>(e)) {
3310 return asImpl().visitCastExpr(ce);
3313 }
else if (
auto op = dyn_cast<BinaryOperator>(e)) {
3314 return asImpl().visitBinaryOperator(op);
3322 }
else if (isa<CallExpr>(e) ||
3323 (isa<ObjCMessageExpr>(e) &&
3324 !cast<ObjCMessageExpr>(e)->isDelegateInitCall())) {
3325 return asImpl().visitCall(e);
3328 }
else if (
const PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) {
3329 return asImpl().visitPseudoObjectExpr(pseudo);
3330 }
else if (
auto *be = dyn_cast<BlockExpr>(e))
3331 return asImpl().visitBlockExpr(be);
3333 return asImpl().visitExpr(e);
3339struct ARCRetainExprEmitter :
3340 public ARCExprEmitter<ARCRetainExprEmitter, TryEmitResult> {
3345 return result.getPointer();
3349 llvm::Value *value = result.getPointer();
3350 value = CGF.Builder.CreateBitCast(value, resultType);
3351 result.setPointer(value);
3362 llvm::Value *result = CGF.EmitScalarExpr(e);
3370 if (CGF.CGM.getCodeGenOpts().ObjCAvoidHeapifyLocalBlocks &&
3372 result.setInt(
true);
3380 llvm::Value *result;
3385 result = CGF.EmitScalarExpr(e);
3392 if (subresult.getInt()) {
3397 result = subresult.getPointer();
3401 result = CGF.EmitARCRetainBlock(result,
true);
3423 llvm::Value *result = CGF.EmitScalarExpr(e);
3431 return ARCRetainExprEmitter(CGF).visit(e);
3438 llvm::Value *value = result.getPointer();
3439 if (!result.getInt())
3451 RunCleanupsScope scope(*
this);
3456 llvm::Value *value = result.getPointer();
3457 if (!result.getInt())
3466 RunCleanupsScope scope(*
this);
3471 llvm::Value *value = result.getPointer();
3472 if (result.getInt())
3480 llvm::Value *result;
3488 result = subresult.getPointer();
3489 doRetain = !subresult.getInt();
3516struct ARCUnsafeUnretainedExprEmitter :
3517 public ARCExprEmitter<ARCUnsafeUnretainedExprEmitter, llvm::Value*> {
3519 ARCUnsafeUnretainedExprEmitter(
CodeGenFunction &CGF) : ARCExprEmitter(CGF) {}
3521 llvm::Value *getValueOfResult(llvm::Value *value) {
3525 llvm::Value *emitBitCast(llvm::Value *value, llvm::Type *resultType) {
3526 return CGF.Builder.CreateBitCast(value, resultType);
3529 llvm::Value *visitLValueToRValue(
const Expr *e) {
3530 return CGF.EmitScalarExpr(e);
3535 llvm::Value *visitConsumeObject(
const Expr *e) {
3536 llvm::Value *value = CGF.EmitScalarExpr(e);
3537 return CGF.EmitObjCConsumeObject(e->
getType(), value);
3542 llvm::Value *visitExtendBlockObject(
const Expr *e) {
3543 return CGF.EmitARCExtendBlockObject(e);
3547 llvm::Value *visitReclaimReturnedObject(
const Expr *e) {
3548 return CGF.EmitARCReclaimReturnedObject(e,
true);
3553 llvm::Value *visitCall(
const Expr *e) {
3554 return CGF.EmitScalarExpr(e);
3558 llvm::Value *visitExpr(
const Expr *e) {
3559 return CGF.EmitScalarExpr(e);
3566 return ARCUnsafeUnretainedExprEmitter(CGF).visit(e);
3576 RunCleanupsScope scope(*
this);
3583std::pair<LValue,llvm::Value*>
3599 return std::pair<LValue,llvm::Value*>(std::move(lvalue), value);
3602std::pair<LValue,llvm::Value*>
3607 llvm::Value *value = result.getPointer();
3609 bool hasImmediateRetain = result.getInt();
3616 hasImmediateRetain =
true;
3622 if (hasImmediateRetain) {
3630 return std::pair<LValue,llvm::Value*>(lvalue, value);
3633std::pair<LValue,llvm::Value*>
3640 return std::pair<LValue,llvm::Value*>(lvalue, value);
3653 RunCleanupsScope
Scope(*
this);
3662 for (
const auto *I : S.body())
3673 llvm::FunctionType *extenderType
3675 llvm::InlineAsm *extender = llvm::InlineAsm::get(extenderType,
3700 CharUnits Alignment =
C.getTypeAlignInChars(Ty);
3711 llvm::Constant *HelperFn =
nullptr;
3725 SrcTy =
C.getPointerType(SrcTy);
3728 ArgTys.push_back(DestTy);
3729 ArgTys.push_back(SrcTy);
3730 QualType FunctionTy =
C.getFunctionType(ReturnTy, ArgTys, {});
3734 FunctionTy,
nullptr,
SC_Static,
false,
false,
false);
3742 args.push_back(Params[0] = DstDecl);
3747 args.push_back(Params[1] = SrcDecl);
3748 FD->setParams(Params);
3755 llvm::Function *
Fn =
3756 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
3757 "__assign_helper_atomic_property_",
3774 Expr *Args[2] = {DST, SRC};
3798 CharUnits Alignment =
C.getTypeAlignInChars(Ty);
3809 llvm::Constant *HelperFn =
nullptr;
3823 SrcTy =
C.getPointerType(SrcTy);
3826 ArgTys.push_back(DestTy);
3827 ArgTys.push_back(SrcTy);
3828 QualType FunctionTy =
C.getFunctionType(ReturnTy, ArgTys, {});
3832 FunctionTy,
nullptr,
SC_Static,
false,
false,
false);
3840 args.push_back(Params[0] = DstDecl);
3845 args.push_back(Params[1] = SrcDecl);
3846 FD->setParams(Params);
3853 llvm::Function *
Fn = llvm::Function::Create(
3854 LTy, llvm::GlobalValue::InternalLinkage,
"__copy_helper_atomic_property_",
3872 ConstructorArgs.push_back(SRC);
3873 ConstructorArgs.append(std::next(CXXConstExpr->
arg_begin()),
3919 llvm::Value *Val =
Block;
3924 Val =
Result.getScalarVal();
3926 Ty, AutoreleaseSelector,
3928 Val =
Result.getScalarVal();
3933 switch (TT.getOS()) {
3934 case llvm::Triple::Darwin:
3935 case llvm::Triple::MacOSX:
3936 return llvm::MachO::PLATFORM_MACOS;
3937 case llvm::Triple::IOS:
3938 return llvm::MachO::PLATFORM_IOS;
3939 case llvm::Triple::TvOS:
3940 return llvm::MachO::PLATFORM_TVOS;
3941 case llvm::Triple::WatchOS:
3942 return llvm::MachO::PLATFORM_WATCHOS;
3943 case llvm::Triple::XROS:
3944 return llvm::MachO::PLATFORM_XROS;
3945 case llvm::Triple::DriverKit:
3946 return llvm::MachO::PLATFORM_DRIVERKIT;
3948 return llvm::MachO::PLATFORM_UNKNOWN;
3953 const VersionTuple &Version) {
3960 auto EmitArgs = [&](
const VersionTuple &Version,
const llvm::Triple &TT) {
3961 std::optional<unsigned>
Min = Version.getMinor(),
3962 SMin = Version.getSubminor();
3965 Args.push_back(llvm::ConstantInt::get(CGM.
Int32Ty, Version.getMajor()));
3966 Args.push_back(llvm::ConstantInt::get(CGM.
Int32Ty,
Min.value_or(0)));
3967 Args.push_back(llvm::ConstantInt::get(CGM.
Int32Ty, SMin.value_or(0)));
3970 assert(!Version.empty() &&
"unexpected empty version");
3974 llvm::FunctionType *FTy = llvm::FunctionType::get(
3975 CGM.
Int32Ty, {CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty},
3981 llvm::Value *Check =
3983 return CGF.
Builder.CreateICmpNE(Check,
3984 llvm::Constant::getNullValue(CGM.
Int32Ty));
3994 llvm::FunctionType *FTy =
4000 std::optional<unsigned>
Min = Version.getMinor(),
4001 SMin = Version.getSubminor();
4002 llvm::Value *Args[] = {
4003 llvm::ConstantInt::get(
CGM.
Int32Ty, Version.getMajor()),
4005 llvm::ConstantInt::get(
CGM.
Int32Ty, SMin.value_or(0))};
4007 llvm::Value *CallRes =
4010 return Builder.CreateICmpNE(CallRes, llvm::Constant::getNullValue(
Int32Ty));
4014 const llvm::Triple &TT,
const VersionTuple &
TargetVersion) {
4015 VersionTuple FoundationDroppedInVersion;
4016 switch (TT.getOS()) {
4017 case llvm::Triple::IOS:
4018 case llvm::Triple::TvOS:
4019 FoundationDroppedInVersion = VersionTuple(13);
4021 case llvm::Triple::WatchOS:
4022 FoundationDroppedInVersion = VersionTuple(6);
4024 case llvm::Triple::Darwin:
4025 case llvm::Triple::MacOSX:
4026 FoundationDroppedInVersion = VersionTuple(10, 15);
4028 case llvm::Triple::XROS:
4031 case llvm::Triple::DriverKit:
4035 llvm_unreachable(
"Unexpected OS");
4040void CodeGenModule::emitAtAvailableLinkGuard() {
4044 if (!
Target.getTriple().isOSDarwin())
4056 llvm::Metadata *Args[2] = {llvm::MDString::get(Context,
"-framework"),
4057 llvm::MDString::get(Context,
"CoreFoundation")};
4058 LinkerOptionsMetadata.push_back(llvm::MDNode::get(Context, Args));
4061 llvm::FunctionType *FTy =
4063 llvm::FunctionCallee CFFunc =
4066 llvm::FunctionType *CheckFTy = llvm::FunctionType::get(
VoidTy, {},
false);
4068 CheckFTy,
"__clang_at_available_requires_core_foundation_framework",
4069 llvm::AttributeList(),
true);
4070 llvm::Function *CFLinkCheckFunc =
4071 cast<llvm::Function>(CFLinkCheckFuncRef.getCallee()->stripPointerCasts());
4072 if (CFLinkCheckFunc->empty()) {
4073 CFLinkCheckFunc->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
4074 CFLinkCheckFunc->setVisibility(llvm::GlobalValue::HiddenVisibility);
4076 CGF.Builder.SetInsertPoint(CGF.createBasicBlock(
"", CFLinkCheckFunc));
4077 CGF.EmitNounwindRuntimeCall(CFFunc,
4078 llvm::Constant::getNullValue(
VoidPtrTy));
4079 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)
enum clang::sema::@1655::IndirectLocalPathEntry::EntryKind Kind
static Decl::Kind getKind(const Decl *D)
llvm::MachO::Target Target
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.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
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>.
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.
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.
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, CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange)
Create a C++ construction expression.
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.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
CXXConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
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.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
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::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot forLValue(const LValue &LV, 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 CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const 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)
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
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)
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.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
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...
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)
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.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
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.