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::@1653::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.
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.
LValue - This represents an lvalue references.
CharUnits getAlignment() const
llvm::Value * getPointer(CodeGenFunction &CGF) const
const Qualifiers & getQuals() const
Address getAddress() const
ARCPreciseLifetime_t isARCPreciseLifetime() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
virtual StringRef getARCRetainAutoreleasedReturnValueMarker() const
Retrieve the address of a function to call immediately before calling objc_retainAutoreleasedReturnVa...
virtual bool markARCOptimizedReturnCallsAsNoTail() const
Determine whether a call to objc_retainAutoreleasedReturnValue or objc_unsafeClaimAutoreleasedReturnV...
CompoundStmt - This represents a group of statements like { stmt stmt }.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
SourceLocation getLocation() const
DeclContext * getDeclContext()
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, Expr *TrailingRequiresClause=nullptr)
GlobalDecl - represents a global declaration.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
clang::ObjCRuntime ObjCRuntime
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Expr * getElement(unsigned Index)
getElement - Return the Element at the specified index.
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
Represents Objective-C's @autoreleasepool Statement.
const Stmt * getSubStmt() const
ObjCBoxedExpr - used for generalized expression boxing.
ObjCContainerDecl - Represents a container for method declarations.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
Represents Objective-C's collection statement.
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
ObjCInterfaceDecl * getSuperClass() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCIvarDecl * getNextIvar()
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Selector getSelector() const
@ SuperInstance
The receiver is the instance of the superclass object.
@ Instance
The receiver is an object instance.
@ SuperClass
The receiver is a superclass.
@ Class
The receiver is a class.
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
param_const_iterator param_end() const
param_const_iterator param_begin() const
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
SourceLocation getEndLoc() const LLVM_READONLY
const ParmVarDecl *const * param_const_iterator
SourceLocation getBeginLoc() const LLVM_READONLY
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
bool isInstanceMethod() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID)
createImplicitParams - Used to lazily create the self and cmd implicit parameters.
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
bool isAtomic() const
isAtomic - Return true if the property is atomic.
SetterKind getSetterKind() const
getSetterKind - Return the method used for doing assignment in the property setter.
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
ObjCIvarDecl * getPropertyIvarDecl() const
Expr * getSetterCXXAssignment() const
ObjCPropertyDecl * getPropertyDecl() const
Expr * getGetterCXXConstructor() const
ObjCMethodDecl * getSetterMethodDecl() const
ObjCMethodDecl * getGetterMethodDecl() const
Represents an Objective-C protocol declaration.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
ObjCProtocolList::iterator protocol_iterator
ObjCProtocolDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C protocol.
protocol_range protocols() const
ObjCProtocolExpr used for protocol expression in Objective-C.
The basic abstraction for the target Objective-C runtime.
bool hasEmptyCollections() const
Are the empty collection symbols available?
bool hasAtomicCopyHelper() const
bool hasARCUnsafeClaimAutoreleasedReturnValue() const
Is objc_unsafeClaimAutoreleasedReturnValue available?
bool hasNativeARC() const
Does this runtime natively provide the ARC entrypoints?
bool hasOptimizedSetter() const
Does this runtime supports optimized setter entrypoints?
ObjCSelectorExpr used for @selector in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
const Expr *const * const_semantics_iterator
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
@ DK_objc_strong_lifetime
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const
Check if this is a non-trivial type that would cause a C struct transitively containing this type to ...
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool hasNonTrivialObjCLifetime() const
@ PCK_Struct
The type is a struct containing a field whose type is neither PCK_Trivial nor PCK_VolatileTrivial.
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
ObjCLifetime getObjCLifetime() const
void setObjCLifetime(ObjCLifetime type)
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
Scope - A scope is a transient data structure that is used while parsing the program.
Selector getNullarySelector(const IdentifierInfo *ID)
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
bool isKeywordSelector() const
ObjCMethodFamily getMethodFamily() const
Derive the conventional family of this method.
bool isUnarySelector() const
unsigned getNumArgs() const
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Token - This structure provides full information about a lexed token.
bool isBlockPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjCObjectPointerType() const
bool isObjCClassType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
bool isObjCRetainableType() const
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::Function * getNonTrivialCStructCopyConstructor(CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, bool IsVolatile, QualType QT)
Returns the copy constructor for a C struct with non-trivially copyable fields, generating it if nece...
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
llvm::Function * getNonTrivialCStructMoveAssignmentOperator(CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, bool IsVolatile, QualType QT)
Return the move assignment operator for a C struct with non-trivially copyable fields,...
ARCPreciseLifetime_t
Does an ARC strong l-value have precise lifetime?
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< RecordType > recordType
Matches record types (e.g.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool Cast(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ OK_Ordinary
An ordinary object is located at an address in memory.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
llvm::PointerType * VoidPtrTy
llvm::PointerType * Int8PtrPtrTy
unsigned char PointerSizeInBytes
llvm::IntegerType * Int32Ty
unsigned char PointerAlignInBytes
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
llvm::Function * objc_retainAutoreleasedReturnValue
id objc_retainAutoreleasedReturnValue(id);
llvm::Function * objc_retainAutoreleaseReturnValue
id objc_retainAutoreleaseReturnValue(id);
llvm::FunctionCallee objc_alloc
void objc_alloc(id);
llvm::Function * objc_retain
id objc_retain(id);
llvm::FunctionCallee objc_alloc_init
void objc_alloc_init(id);
llvm::Function * objc_autorelease
id objc_autorelease(id);
llvm::Function * objc_moveWeak
void objc_moveWeak(id *dest, id *src);
llvm::FunctionCallee objc_autoreleasePoolPopInvoke
void objc_autoreleasePoolPop(void*); Note this method is used when we are using exception handling
llvm::InlineAsm * retainAutoreleasedReturnValueMarker
A void(void) inline asm to use to mark that the return value of a call will be immediately retain.
llvm::Function * clang_arc_use
void clang.arc.use(...);
llvm::Function * objc_initWeak
id objc_initWeak(id*, id);
llvm::FunctionCallee objc_retainRuntimeFunction
id objc_retain(id); Note this is the runtime method not the intrinsic.
llvm::Function * objc_copyWeak
void objc_copyWeak(id *dest, id *src);
llvm::Function * objc_destroyWeak
void objc_destroyWeak(id*);
llvm::Function * objc_retainAutorelease
id objc_retainAutorelease(id);
llvm::Function * objc_autoreleasePoolPush
void *objc_autoreleasePoolPush(void);
llvm::Function * objc_retainBlock
id objc_retainBlock(id);
llvm::Function * objc_storeStrong
void objc_storeStrong(id*, id);
llvm::Function * objc_loadWeak
id objc_loadWeak(id*);
llvm::Function * clang_arc_noop_use
void clang.arc.noop.use(...);
llvm::Function * objc_loadWeakRetained
id objc_loadWeakRetained(id*);
llvm::Function * objc_release
void objc_release(id);
llvm::FunctionCallee objc_autoreleaseRuntimeFunction
id objc_autorelease(id); Note this is the runtime method not the intrinsic.
llvm::Function * objc_autoreleaseReturnValue
id objc_autoreleaseReturnValue(id);
llvm::FunctionCallee objc_releaseRuntimeFunction
void objc_release(id); Note this is the runtime method not the intrinsic.
llvm::FunctionCallee objc_allocWithZone
void objc_allocWithZone(id);
llvm::FunctionCallee objc_autoreleasePoolPop
void objc_autoreleasePoolPop(void*);
llvm::Function * objc_storeWeak
id objc_storeWeak(id*, id);
llvm::Function * objc_unsafeClaimAutoreleasedReturnValue
id objc_unsafeClaimAutoreleasedReturnValue(id);
Expr * Value
The value of the dictionary element.
Expr * Key
The key for the dictionary element.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.