ARCRuntimeEntryPoints.h [plain text]
#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H
#define LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H
#include "ObjCARC.h"
namespace llvm {
namespace objcarc {
enum class ARCRuntimeEntryPointKind {
AutoreleaseRV,
Release,
Retain,
RetainBlock,
Autorelease,
StoreStrong,
RetainRV,
RetainAutorelease,
RetainAutoreleaseRV,
};
class ARCRuntimeEntryPoints {
public:
ARCRuntimeEntryPoints() : TheModule(nullptr),
AutoreleaseRV(nullptr),
Release(nullptr),
Retain(nullptr),
RetainBlock(nullptr),
Autorelease(nullptr),
StoreStrong(nullptr),
RetainRV(nullptr),
RetainAutorelease(nullptr),
RetainAutoreleaseRV(nullptr) { }
void init(Module *M) {
TheModule = M;
AutoreleaseRV = nullptr;
Release = nullptr;
Retain = nullptr;
RetainBlock = nullptr;
Autorelease = nullptr;
StoreStrong = nullptr;
RetainRV = nullptr;
RetainAutorelease = nullptr;
RetainAutoreleaseRV = nullptr;
}
Constant *get(ARCRuntimeEntryPointKind kind) {
assert(TheModule != nullptr && "Not initialized.");
switch (kind) {
case ARCRuntimeEntryPointKind::AutoreleaseRV:
return getI8XRetI8XEntryPoint(AutoreleaseRV,
"objc_autoreleaseReturnValue", true);
case ARCRuntimeEntryPointKind::Release:
return getVoidRetI8XEntryPoint(Release, "objc_release");
case ARCRuntimeEntryPointKind::Retain:
return getI8XRetI8XEntryPoint(Retain, "objc_retain", true);
case ARCRuntimeEntryPointKind::RetainBlock:
return getI8XRetI8XEntryPoint(RetainBlock, "objc_retainBlock", false);
case ARCRuntimeEntryPointKind::Autorelease:
return getI8XRetI8XEntryPoint(Autorelease, "objc_autorelease", true);
case ARCRuntimeEntryPointKind::StoreStrong:
return getI8XRetI8XXI8XEntryPoint(StoreStrong, "objc_storeStrong");
case ARCRuntimeEntryPointKind::RetainRV:
return getI8XRetI8XEntryPoint(RetainRV,
"objc_retainAutoreleasedReturnValue", true);
case ARCRuntimeEntryPointKind::RetainAutorelease:
return getI8XRetI8XEntryPoint(RetainAutorelease, "objc_retainAutorelease",
true);
case ARCRuntimeEntryPointKind::RetainAutoreleaseRV:
return getI8XRetI8XEntryPoint(RetainAutoreleaseRV,
"objc_retainAutoreleaseReturnValue", true);
}
llvm_unreachable("Switch should be a covered switch.");
}
private:
Module *TheModule;
Constant *AutoreleaseRV;
Constant *Release;
Constant *Retain;
Constant *RetainBlock;
Constant *Autorelease;
Constant *StoreStrong;
Constant *RetainRV;
Constant *RetainAutorelease;
Constant *RetainAutoreleaseRV;
Constant *getVoidRetI8XEntryPoint(Constant *&Decl,
const char *Name) {
if (Decl)
return Decl;
LLVMContext &C = TheModule->getContext();
Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
AttributeSet Attr =
AttributeSet().addAttribute(C, AttributeSet::FunctionIndex,
Attribute::NoUnwind);
FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
false);
return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
}
Constant *getI8XRetI8XEntryPoint(Constant *& Decl,
const char *Name,
bool NoUnwind = false) {
if (Decl)
return Decl;
LLVMContext &C = TheModule->getContext();
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
Type *Params[] = { I8X };
FunctionType *Fty = FunctionType::get(I8X, Params, false);
AttributeSet Attr = AttributeSet();
if (NoUnwind)
Attr = Attr.addAttribute(C, AttributeSet::FunctionIndex,
Attribute::NoUnwind);
return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
}
Constant *getI8XRetI8XXI8XEntryPoint(Constant *&Decl,
const char *Name) {
if (Decl)
return Decl;
LLVMContext &C = TheModule->getContext();
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
Type *I8XX = PointerType::getUnqual(I8X);
Type *Params[] = { I8XX, I8X };
AttributeSet Attr =
AttributeSet().addAttribute(C, AttributeSet::FunctionIndex,
Attribute::NoUnwind);
Attr = Attr.addAttribute(C, 1, Attribute::NoCapture);
FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
false);
return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
}
};
} }
#endif