1//===- ObjCARCUtil.h - ObjC ARC Utility Functions ---------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8/// \file 9/// This file defines ARC utility functions which are used by various parts of 10/// the compiler. 11/// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_ANALYSIS_OBJCARCUTIL_H 15#define LLVM_ANALYSIS_OBJCARCUTIL_H 16 17#include "llvm/Analysis/ObjCARCInstKind.h" 18#include "llvm/IR/Function.h" 19#include "llvm/IR/InstrTypes.h" 20#include "llvm/IR/LLVMContext.h" 21 22namespace llvm { 23namespace objcarc { 24 25inline const char *getRVMarkerModuleFlagStr() { 26 return "clang.arc.retainAutoreleasedReturnValueMarker"; 27} 28 29inline bool hasAttachedCallOpBundle(const CallBase *CB) { 30 // Ignore the bundle if the return type is void. Global optimization passes 31 // can turn the called function's return type to void. That should happen only 32 // if the call doesn't return and the call to @llvm.objc.clang.arc.noop.use 33 // no longer consumes the function return or is deleted. In that case, it's 34 // not necessary to emit the marker instruction or calls to the ARC runtime 35 // functions. 36 return !CB->getFunctionType()->getReturnType()->isVoidTy() && 37 CB->getOperandBundle(LLVMContext::OB_clang_arc_attachedcall) 38 .has_value(); 39} 40 41/// This function returns operand bundle clang_arc_attachedcall's argument, 42/// which is the address of the ARC runtime function. 43inline std::optional<Function *> getAttachedARCFunction(const CallBase *CB) { 44 auto B = CB->getOperandBundle(LLVMContext::OB_clang_arc_attachedcall); 45 if (!B) 46 return std::nullopt; 47 48 return cast<Function>(B->Inputs[0]); 49} 50 51/// Check whether the function is retainRV/unsafeClaimRV. 52inline bool isRetainOrClaimRV(ARCInstKind Kind) { 53 return Kind == ARCInstKind::RetainRV || Kind == ARCInstKind::UnsafeClaimRV; 54} 55 56/// This function returns the ARCInstKind of the function attached to operand 57/// bundle clang_arc_attachedcall. It returns std::nullopt if the call doesn't 58/// have the operand bundle or the operand is null. Otherwise it returns either 59/// RetainRV or UnsafeClaimRV. 60inline ARCInstKind getAttachedARCFunctionKind(const CallBase *CB) { 61 std::optional<Function *> Fn = getAttachedARCFunction(CB); 62 if (!Fn) 63 return ARCInstKind::None; 64 auto FnClass = GetFunctionClass(*Fn); 65 assert(isRetainOrClaimRV(FnClass) && "unexpected ARC runtime function"); 66 return FnClass; 67} 68 69} // end namespace objcarc 70} // end namespace llvm 71 72#endif 73