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_IR_OBJCARCUTIL_H
15 #define LLVM_IR_OBJCARCUTIL_H
16 
17 #include "llvm/IR/InstrTypes.h"
18 #include "llvm/IR/LLVMContext.h"
19 
20 namespace llvm {
21 namespace objcarc {
22 
getRVMarkerModuleFlagStr()23 inline const char *getRVMarkerModuleFlagStr() {
24   return "clang.arc.retainAutoreleasedReturnValueMarker";
25 }
26 
27 enum AttachedCallOperandBundle : unsigned { RVOB_Retain, RVOB_Claim };
28 
29 inline AttachedCallOperandBundle
getAttachedCallOperandBundleEnum(bool IsRetain)30 getAttachedCallOperandBundleEnum(bool IsRetain) {
31   return IsRetain ? RVOB_Retain : RVOB_Claim;
32 }
33 
hasAttachedCallOpBundle(const CallBase * CB)34 inline bool hasAttachedCallOpBundle(const CallBase *CB) {
35   // Ignore the bundle if the return type is void. Global optimization passes
36   // can turn the called function's return type to void. That should happen only
37   // if the call doesn't return and the call to @llvm.objc.clang.arc.noop.use
38   // no longer consumes the function return or is deleted. In that case, it's
39   // not necessary to emit the marker instruction or calls to the ARC runtime
40   // functions.
41   return !CB->getFunctionType()->getReturnType()->isVoidTy() &&
42          CB->getOperandBundle(LLVMContext::OB_clang_arc_attachedcall)
43              .hasValue();
44 }
45 
hasAttachedCallOpBundle(const CallBase * CB,bool IsRetain)46 inline bool hasAttachedCallOpBundle(const CallBase *CB, bool IsRetain) {
47   assert(hasAttachedCallOpBundle(CB) &&
48          "call doesn't have operand bundle clang_arc_attachedcall");
49   auto B = CB->getOperandBundle(LLVMContext::OB_clang_arc_attachedcall);
50   if (!B.hasValue())
51     return false;
52   return cast<ConstantInt>(B->Inputs[0])->getZExtValue() ==
53          getAttachedCallOperandBundleEnum(IsRetain);
54 }
55 
56 } // end namespace objcarc
57 } // end namespace llvm
58 
59 #endif
60