#ifndef CLANG_CODEGEN_OBCJRUNTIME_H
#define CLANG_CODEGEN_OBCJRUNTIME_H
#include "clang/Basic/IdentifierTable.h" // Selector
#include "clang/AST/DeclObjC.h"
#include "CGBuilder.h"
#include "CGCall.h"
#include "CGValue.h"
namespace llvm {
class Constant;
class Function;
class Module;
class StructLayout;
class StructType;
class Type;
class Value;
}
namespace clang {
namespace CodeGen {
class CodeGenFunction;
}
class FieldDecl;
class ObjCAtTryStmt;
class ObjCAtThrowStmt;
class ObjCAtSynchronizedStmt;
class ObjCContainerDecl;
class ObjCCategoryImplDecl;
class ObjCImplementationDecl;
class ObjCInterfaceDecl;
class ObjCMessageExpr;
class ObjCMethodDecl;
class ObjCProtocolDecl;
class Selector;
class ObjCIvarDecl;
class ObjCStringLiteral;
class BlockDeclRefExpr;
namespace CodeGen {
class CodeGenModule;
class CGBlockInfo;
class CGObjCRuntime {
protected:
CodeGen::CodeGenModule &CGM;
CGObjCRuntime(CodeGen::CodeGenModule &CGM) : CGM(CGM) {}
uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
const ObjCInterfaceDecl *OID,
const ObjCIvarDecl *Ivar);
uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
const ObjCImplementationDecl *OID,
const ObjCIvarDecl *Ivar);
LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
const ObjCInterfaceDecl *OID,
llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
unsigned CVRQualifiers,
llvm::Value *Offset);
void EmitTryCatchStmt(CodeGenFunction &CGF,
const ObjCAtTryStmt &S,
llvm::Constant *beginCatchFn,
llvm::Constant *endCatchFn,
llvm::Constant *exceptionRethrowFn);
void EmitAtSynchronizedStmt(CodeGenFunction &CGF,
const ObjCAtSynchronizedStmt &S,
llvm::Function *syncEnterFn,
llvm::Function *syncExitFn);
public:
virtual ~CGObjCRuntime();
virtual llvm::Function *ModuleInitFunction() = 0;
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
Selector Sel, bool lval=false) = 0;
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
const ObjCMethodDecl *Method) = 0;
virtual llvm::Constant *GetEHType(QualType T) = 0;
virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0;
virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0;
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) = 0;
virtual CodeGen::RValue
GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
ReturnValueSlot ReturnSlot,
QualType ResultType,
Selector Sel,
llvm::Value *Receiver,
const CallArgList &CallArgs,
const ObjCInterfaceDecl *Class = 0,
const ObjCMethodDecl *Method = 0) = 0;
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 = 0) = 0;
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
const ObjCProtocolDecl *OPD) = 0;
virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0;
virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
const ObjCContainerDecl *CD) = 0;
virtual llvm::Constant *GetPropertyGetFunction() = 0;
virtual llvm::Constant *GetPropertySetFunction() = 0;
virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
bool copy) = 0;
virtual llvm::Constant *GetGetStructFunction() = 0;
virtual llvm::Constant *GetSetStructFunction() = 0;
virtual llvm::Constant *GetCppAtomicObjectFunction() = 0;
virtual llvm::Value *GetClass(CGBuilderTy &Builder,
const ObjCInterfaceDecl *OID) = 0;
virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
llvm_unreachable("autoreleasepool unsupported in this ABI");
}
virtual llvm::Constant *EnumerationMutationFunction() = 0;
virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtSynchronizedStmt &S) = 0;
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtTryStmt &S) = 0;
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtThrowStmt &S) = 0;
virtual llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
llvm::Value *AddrWeakObj) = 0;
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dest) = 0;
virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dest,
bool threadlocal=false) = 0;
virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dest,
llvm::Value *ivarOffset) = 0;
virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dest) = 0;
virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
QualType ObjectTy,
llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
unsigned CVRQualifiers) = 0;
virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
const ObjCInterfaceDecl *Interface,
const ObjCIvarDecl *Ivar) = 0;
virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
llvm::Value *DestPtr,
llvm::Value *SrcPtr,
llvm::Value *Size) = 0;
virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
const CodeGen::CGBlockInfo &blockInfo) = 0;
virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) = 0;
struct MessageSendInfo {
const CGFunctionInfo &CallInfo;
llvm::PointerType *MessengerType;
MessageSendInfo(const CGFunctionInfo &callInfo,
llvm::PointerType *messengerType)
: CallInfo(callInfo), MessengerType(messengerType) {}
};
MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method,
QualType resultType,
CallArgList &callArgs);
};
CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM);
CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM);
}
}
#endif