summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGObjCMac.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-05-02 19:39:53 +0000
committerdim <dim@FreeBSD.org>2011-05-02 19:39:53 +0000
commit110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab (patch)
tree64a10f4c4154739d4a8191d7e1b52ce497f4ebd6 /lib/CodeGen/CGObjCMac.cpp
parenta0fb00f9837bd0d2e5948f16f6a6b82a7a628f51 (diff)
downloadFreeBSD-src-110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab.zip
FreeBSD-src-110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab.tar.gz
Vendor import of clang trunk r130700:
http://llvm.org/svn/llvm-project/cfe/trunk@130700
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r--lib/CodeGen/CGObjCMac.cpp364
1 files changed, 62 insertions, 302 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 8dbd85f..2b1cfe3 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This provides Objective-C code generation targetting the Apple runtime.
+// This provides Objective-C code generation targeting the Apple runtime.
//
//===----------------------------------------------------------------------===//
@@ -42,9 +42,6 @@
using namespace clang;
using namespace CodeGen;
-// Common CGObjCRuntime functions, these don't belong here, but they
-// don't belong in CGObjCRuntime either so we will live with it for
-// now.
static void EmitNullReturnInitialization(CodeGenFunction &CGF,
ReturnValueSlot &returnSlot,
@@ -55,112 +52,6 @@ static void EmitNullReturnInitialization(CodeGenFunction &CGF,
CGF.EmitNullInitialization(returnSlot.getValue(), resultType);
}
-static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
- const ObjCInterfaceDecl *OID,
- const ObjCImplementationDecl *ID,
- const ObjCIvarDecl *Ivar) {
- const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
-
- // FIXME: We should eliminate the need to have ObjCImplementationDecl passed
- // in here; it should never be necessary because that should be the lexical
- // decl context for the ivar.
-
- // If we know have an implementation (and the ivar is in it) then
- // look up in the implementation layout.
- const ASTRecordLayout *RL;
- if (ID && ID->getClassInterface() == Container)
- RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
- else
- RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);
-
- // Compute field index.
- //
- // FIXME: The index here is closely tied to how ASTContext::getObjCLayout is
- // implemented. This should be fixed to get the information from the layout
- // directly.
- unsigned Index = 0;
- llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
- CGM.getContext().ShallowCollectObjCIvars(Container, Ivars);
- for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
- if (Ivar == Ivars[k])
- break;
- ++Index;
- }
- assert(Index != Ivars.size() && "Ivar is not inside container!");
- assert(Index < RL->getFieldCount() && "Ivar is not inside record layout!");
-
- return RL->getFieldOffset(Index);
-}
-
-uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
- const ObjCInterfaceDecl *OID,
- const ObjCIvarDecl *Ivar) {
- return LookupFieldBitOffset(CGM, OID, 0, Ivar) / 8;
-}
-
-uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
- const ObjCImplementationDecl *OID,
- const ObjCIvarDecl *Ivar) {
- return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) / 8;
-}
-
-LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
- const ObjCInterfaceDecl *OID,
- llvm::Value *BaseValue,
- const ObjCIvarDecl *Ivar,
- unsigned CVRQualifiers,
- llvm::Value *Offset) {
- // Compute (type*) ( (char *) BaseValue + Offset)
- const llvm::Type *I8Ptr = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
- QualType IvarTy = Ivar->getType();
- const llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
- llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, I8Ptr);
- V = CGF.Builder.CreateGEP(V, Offset, "add.ptr");
- V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy));
-
- if (!Ivar->isBitField()) {
- LValue LV = CGF.MakeAddrLValue(V, IvarTy);
- LV.getQuals().addCVRQualifiers(CVRQualifiers);
- return LV;
- }
-
- // We need to compute an access strategy for this bit-field. We are given the
- // offset to the first byte in the bit-field, the sub-byte offset is taken
- // from the original layout. We reuse the normal bit-field access strategy by
- // treating this as an access to a struct where the bit-field is in byte 0,
- // and adjust the containing type size as appropriate.
- //
- // FIXME: Note that currently we make a very conservative estimate of the
- // alignment of the bit-field, because (a) it is not clear what guarantees the
- // runtime makes us, and (b) we don't have a way to specify that the struct is
- // at an alignment plus offset.
- //
- // Note, there is a subtle invariant here: we can only call this routine on
- // non-synthesized ivars but we may be called for synthesized ivars. However,
- // a synthesized ivar can never be a bit-field, so this is safe.
- const ASTRecordLayout &RL =
- CGF.CGM.getContext().getASTObjCInterfaceLayout(OID);
- uint64_t TypeSizeInBits = CGF.CGM.getContext().toBits(RL.getSize());
- uint64_t FieldBitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar);
- uint64_t BitOffset = FieldBitOffset % 8;
- uint64_t ContainingTypeAlign = 8;
- uint64_t ContainingTypeSize = TypeSizeInBits - (FieldBitOffset - BitOffset);
- uint64_t BitFieldSize =
- Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue();
-
- // Allocate a new CGBitFieldInfo object to describe this access.
- //
- // FIXME: This is incredibly wasteful, these should be uniqued or part of some
- // layout object. However, this is blocked on other cleanups to the
- // Objective-C code, so for now we just live with allocating a bunch of these
- // objects.
- CGBitFieldInfo *Info = new (CGF.CGM.getContext()) CGBitFieldInfo(
- CGBitFieldInfo::MakeInfo(CGF.CGM.getTypes(), Ivar, BitOffset, BitFieldSize,
- ContainingTypeSize, ContainingTypeAlign));
-
- return LValue::MakeBitfield(V, *Info,
- IvarTy.getCVRQualifiers() | CVRQualifiers);
-}
///
@@ -328,7 +219,7 @@ public:
CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
Params.push_back(IdType);
Params.push_back(SelType);
- Params.push_back(Ctx.LongTy);
+ Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
Params.push_back(Ctx.BoolTy);
const llvm::FunctionType *FTy =
Types.GetFunctionType(Types.getFunctionInfo(IdType, Params,
@@ -346,7 +237,7 @@ public:
CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
Params.push_back(IdType);
Params.push_back(SelType);
- Params.push_back(Ctx.LongTy);
+ Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
Params.push_back(IdType);
Params.push_back(Ctx.BoolTy);
Params.push_back(Ctx.BoolTy);
@@ -1294,7 +1185,8 @@ private:
llvm::Value *Receiver,
QualType Arg0Ty,
bool IsSuper,
- const CallArgList &CallArgs);
+ const CallArgList &CallArgs,
+ const ObjCMethodDecl *Method);
/// GetClassGlobal - Return the global variable for the Objective-C
/// class of the given name.
@@ -1555,7 +1447,7 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
// Create and init a super structure; this is a (receiver, class)
// pair we will pass to objc_msgSendSuper.
llvm::Value *ObjCSuper =
- CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
+ CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
llvm::Value *ReceiverAsObject =
CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
CGF.Builder.CreateStore(ReceiverAsObject,
@@ -1630,9 +1522,8 @@ CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF,
CallArgList ActualArgs;
if (!IsSuper)
Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp");
- ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty));
- ActualArgs.push_back(std::make_pair(RValue::get(Sel),
- CGF.getContext().getObjCSelType()));
+ ActualArgs.add(RValue::get(Arg0), Arg0Ty);
+ ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
CodeGenTypes &Types = CGM.getTypes();
@@ -2177,6 +2068,8 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
4, true);
DefinedCategories.push_back(GV);
DefinedCategoryNames.insert(ExtName.str());
+ // method definition entries must be clear for next implementation.
+ MethodDefinitions.clear();
}
// FIXME: Get from somewhere?
@@ -2304,6 +2197,8 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
else
GV = CreateMetadataVar(Name, Init, Section, 4, true);
DefinedClasses.push_back(GV);
+ // method definition entries must be clear for next implementation.
+ MethodDefinitions.clear();
}
llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
@@ -3596,7 +3491,9 @@ llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
llvm::ConstantArray::get(VMContext,
Ident->getNameStart()),
- "__TEXT,__cstring,cstring_literals",
+ ((ObjCABI == 2) ?
+ "__TEXT,__objc_classname,cstring_literals" :
+ "__TEXT,__cstring,cstring_literals"),
1, true);
return getConstantGEP(VMContext, Entry, 0, 0);
@@ -3668,7 +3565,7 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
// Note that 'i' here is actually the field index inside RD of Field,
// although this dependency is hidden.
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
- FieldOffset = RL.getFieldOffset(i) / 8;
+ FieldOffset = RL.getFieldOffset(i) / ByteSizeInBits;
} else
FieldOffset = ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field));
@@ -3920,7 +3817,9 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string& BitMap) {
llvm::GlobalVariable * Entry =
CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
llvm::ConstantArray::get(VMContext, BitMap.c_str()),
- "__TEXT,__cstring,cstring_literals",
+ ((ObjCABI == 2) ?
+ "__TEXT,__objc_classname,cstring_literals" :
+ "__TEXT,__cstring,cstring_literals"),
1, true);
return getConstantGEP(VMContext, Entry, 0, 0);
}
@@ -3999,7 +3898,9 @@ llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
if (!Entry)
Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_",
llvm::ConstantArray::get(VMContext, Sel.getAsString()),
- "__TEXT,__cstring,cstring_literals",
+ ((ObjCABI == 2) ?
+ "__TEXT,__objc_methname,cstring_literals" :
+ "__TEXT,__cstring,cstring_literals"),
1, true);
return getConstantGEP(VMContext, Entry, 0, 0);
@@ -4019,7 +3920,9 @@ llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
if (!Entry)
Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
llvm::ConstantArray::get(VMContext, TypeStr),
- "__TEXT,__cstring,cstring_literals",
+ ((ObjCABI == 2) ?
+ "__TEXT,__objc_methtype,cstring_literals" :
+ "__TEXT,__cstring,cstring_literals"),
1, true);
return getConstantGEP(VMContext, Entry, 0, 0);
@@ -4035,7 +3938,9 @@ llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D) {
if (!Entry)
Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
llvm::ConstantArray::get(VMContext, TypeStr),
- "__TEXT,__cstring,cstring_literals",
+ ((ObjCABI == 2) ?
+ "__TEXT,__objc_methtype,cstring_literals" :
+ "__TEXT,__cstring,cstring_literals"),
1, true);
return getConstantGEP(VMContext, Entry, 0, 0);
@@ -4173,11 +4078,11 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
// }
RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
Ctx.getTranslationUnitDecl(),
- SourceLocation(),
+ SourceLocation(), SourceLocation(),
&Ctx.Idents.get("_objc_super"));
- RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+ RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
Ctx.getObjCIdType(), 0, 0, false));
- RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+ RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
Ctx.getObjCClassType(), 0, 0, false));
RD->completeDefinition();
@@ -4636,11 +4541,11 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
// First the clang type for struct _message_ref_t
RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
Ctx.getTranslationUnitDecl(),
- SourceLocation(),
+ SourceLocation(), SourceLocation(),
&Ctx.Idents.get("_message_ref_t"));
- RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+ RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
Ctx.VoidPtrTy, 0, 0, false));
- RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+ RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
Ctx.getObjCSelType(), 0, 0, false));
RD->completeDefinition();
@@ -4966,7 +4871,7 @@ void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
if (!RL.getFieldCount())
InstanceStart = InstanceSize;
else
- InstanceStart = RL.getFieldOffset(0) / 8;
+ InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
}
void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
@@ -5017,14 +4922,14 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
Root = Super;
IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString());
- if (Root->hasAttr<WeakImportAttr>())
+ if (Root->isWeakImported())
IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
// work on super class metadata symbol.
std::string SuperClassName =
ObjCMetaClassName +
ID->getClassInterface()->getSuperClass()->getNameAsString();
SuperClassGV = GetClassGlobal(SuperClassName);
- if (ID->getClassInterface()->getSuperClass()->hasAttr<WeakImportAttr>())
+ if (ID->getClassInterface()->getSuperClass()->isWeakImported())
SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
}
llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
@@ -5054,7 +4959,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
std::string RootClassName =
ID->getClassInterface()->getSuperClass()->getNameAsString();
SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName);
- if (ID->getClassInterface()->getSuperClass()->hasAttr<WeakImportAttr>())
+ if (ID->getClassInterface()->getSuperClass()->isWeakImported())
SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
}
GetClassSizeInfo(ID, InstanceStart, InstanceSize);
@@ -5076,6 +4981,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
// Force the definition of the EHType if necessary.
if (flags & CLS_EXCEPTION)
GetInterfaceEHType(ID->getClassInterface(), true);
+ // Make sure method definition entries are all clear for next implementation.
+ MethodDefinitions.clear();
}
/// GenerateProtocolRef - This routine is called to generate code for
@@ -5136,7 +5043,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Values[0] = GetClassName(OCD->getIdentifier());
// meta-class entry symbol
llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName);
- if (Interface->hasAttr<WeakImportAttr>())
+ if (Interface->isWeakImported())
ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
Values[1] = ClassGV;
@@ -5204,6 +5111,8 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
// Determine if this category is also "non-lazy".
if (ImplementationIsNonLazy(OCD))
DefinedNonLazyCategories.push_back(GCATV);
+ // method definition entries must be clear for next implementation.
+ MethodDefinitions.clear();
}
/// GetMethodConstant - Return a struct objc_method constant for the
@@ -5622,7 +5531,8 @@ CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend(
llvm::Value *Receiver,
QualType Arg0Ty,
bool IsSuper,
- const CallArgList &CallArgs) {
+ const CallArgList &CallArgs,
+ const ObjCMethodDecl *Method) {
// FIXME. Even though IsSuper is passes. This function doese not handle calls
// to 'super' receivers.
CodeGenTypes &Types = CGM.getTypes();
@@ -5685,15 +5595,15 @@ CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend(
llvm::Value *Arg1 = CGF.Builder.CreateBitCast(GV, ObjCTypes.MessageRefPtrTy);
CallArgList ActualArgs;
- ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty));
- ActualArgs.push_back(std::make_pair(RValue::get(Arg1),
- ObjCTypes.MessageRefCPtrTy));
+ ActualArgs.add(RValue::get(Arg0), Arg0Ty);
+ ActualArgs.add(RValue::get(Arg1), ObjCTypes.MessageRefCPtrTy);
ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
const CGFunctionInfo &FnInfo1 = Types.getFunctionInfo(ResultType, ActualArgs,
FunctionType::ExtInfo());
llvm::Value *Callee = CGF.Builder.CreateStructGEP(Arg1, 0);
Callee = CGF.Builder.CreateLoad(Callee);
- const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo1, true);
+ const llvm::FunctionType *FTy =
+ Types.GetFunctionType(FnInfo1, Method ? Method->isVariadic() : false);
Callee = CGF.Builder.CreateBitCast(Callee,
llvm::PointerType::getUnqual(FTy));
return CGF.EmitCall(FnInfo1, Callee, Return, ActualArgs);
@@ -5716,7 +5626,7 @@ CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
false, CallArgs, Method, ObjCTypes)
: EmitMessageSend(CGF, Return, ResultType, Sel,
Receiver, CGF.getContext().getObjCIdType(),
- false, CallArgs);
+ false, CallArgs, Method);
}
llvm::GlobalVariable *
@@ -5807,7 +5717,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder,
/// decl.
llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
const ObjCInterfaceDecl *ID) {
- if (ID->hasAttr<WeakImportAttr>()) {
+ if (ID->isWeakImported()) {
std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
@@ -5834,7 +5744,7 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
// Create and init a super structure; this is a (receiver, class)
// pair we will pass to objc_msgSendSuper.
llvm::Value *ObjCSuper =
- CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
+ CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
llvm::Value *ReceiverAsObject =
CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
@@ -5870,7 +5780,7 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
true, CallArgs, Method, ObjCTypes)
: EmitMessageSend(CGF, Return, ResultType, Sel,
ObjCSuper, ObjCTypes.SuperPtrCTy,
- true, CallArgs);
+ true, CallArgs, Method);
}
llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
@@ -6008,65 +5918,12 @@ void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
return;
}
-namespace {
- struct CallSyncExit : EHScopeStack::Cleanup {
- llvm::Value *SyncExitFn;
- llvm::Value *SyncArg;
- CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
- : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
-
- void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
- CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
- }
- };
-}
-
void
CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtSynchronizedStmt &S) {
- // Evaluate the lock operand. This should dominate the cleanup.
- llvm::Value *SyncArg = CGF.EmitScalarExpr(S.getSynchExpr());
-
- // Acquire the lock.
- SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
- CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg)
- ->setDoesNotThrow();
-
- // Register an all-paths cleanup to release the lock.
- CGF.EHStack.pushCleanup<CallSyncExit>(NormalAndEHCleanup,
- ObjCTypes.getSyncExitFn(),
- SyncArg);
-
- // Emit the body of the statement.
- CGF.EmitStmt(S.getSynchBody());
-
- // Pop the lock-release cleanup.
- CGF.PopCleanupBlock();
-}
-
-namespace {
- struct CatchHandler {
- const VarDecl *Variable;
- const Stmt *Body;
- llvm::BasicBlock *Block;
- llvm::Value *TypeInfo;
- };
-
- struct CallObjCEndCatch : EHScopeStack::Cleanup {
- CallObjCEndCatch(bool MightThrow, llvm::Value *Fn) :
- MightThrow(MightThrow), Fn(Fn) {}
- bool MightThrow;
- llvm::Value *Fn;
-
- void Emit(CodeGenFunction &CGF, bool IsForEH) {
- if (!MightThrow) {
- CGF.Builder.CreateCall(Fn)->setDoesNotThrow();
- return;
- }
-
- CGF.EmitCallOrInvoke(Fn, 0, 0);
- }
- };
+ EmitAtSynchronizedStmt(CGF, S,
+ cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
+ cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
}
llvm::Constant *
@@ -6096,104 +5953,10 @@ CGObjCNonFragileABIMac::GetEHType(QualType T) {
void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtTryStmt &S) {
- // Jump destination for falling out of catch bodies.
- CodeGenFunction::JumpDest Cont;
- if (S.getNumCatchStmts())
- Cont = CGF.getJumpDestInCurrentScope("eh.cont");
-
- CodeGenFunction::FinallyInfo FinallyInfo;
- if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt())
- FinallyInfo = CGF.EnterFinallyBlock(Finally->getFinallyBody(),
- ObjCTypes.getObjCBeginCatchFn(),
- ObjCTypes.getObjCEndCatchFn(),
- ObjCTypes.getExceptionRethrowFn());
-
- llvm::SmallVector<CatchHandler, 8> Handlers;
-
- // Enter the catch, if there is one.
- if (S.getNumCatchStmts()) {
- for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) {
- const ObjCAtCatchStmt *CatchStmt = S.getCatchStmt(I);
- const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
-
- Handlers.push_back(CatchHandler());
- CatchHandler &Handler = Handlers.back();
- Handler.Variable = CatchDecl;
- Handler.Body = CatchStmt->getCatchBody();
- Handler.Block = CGF.createBasicBlock("catch");
-
- // @catch(...) always matches.
- if (!CatchDecl) {
- Handler.TypeInfo = 0; // catch-all
- // Don't consider any other catches.
- break;
- }
-
- Handler.TypeInfo = GetEHType(CatchDecl->getType());
- }
-
- EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
- for (unsigned I = 0, E = Handlers.size(); I != E; ++I)
- Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block);
- }
-
- // Emit the try body.
- CGF.EmitStmt(S.getTryBody());
-
- // Leave the try.
- if (S.getNumCatchStmts())
- CGF.EHStack.popCatch();
-
- // Remember where we were.
- CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
-
- // Emit the handlers.
- for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
- CatchHandler &Handler = Handlers[I];
-
- CGF.EmitBlock(Handler.Block);
- llvm::Value *RawExn = CGF.Builder.CreateLoad(CGF.getExceptionSlot());
-
- // Enter the catch.
- llvm::CallInst *Exn =
- CGF.Builder.CreateCall(ObjCTypes.getObjCBeginCatchFn(), RawExn,
- "exn.adjusted");
- Exn->setDoesNotThrow();
-
- // Add a cleanup to leave the catch.
- bool EndCatchMightThrow = (Handler.Variable == 0);
- CGF.EHStack.pushCleanup<CallObjCEndCatch>(NormalAndEHCleanup,
- EndCatchMightThrow,
- ObjCTypes.getObjCEndCatchFn());
-
- // Bind the catch parameter if it exists.
- if (const VarDecl *CatchParam = Handler.Variable) {
- const llvm::Type *CatchType = CGF.ConvertType(CatchParam->getType());
- llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType);
-
- CGF.EmitAutoVarDecl(*CatchParam);
- CGF.Builder.CreateStore(CastExn, CGF.GetAddrOfLocalVar(CatchParam));
- }
-
- CGF.ObjCEHValueStack.push_back(Exn);
- CGF.EmitStmt(Handler.Body);
- CGF.ObjCEHValueStack.pop_back();
-
- // Leave the earlier cleanup.
- CGF.PopCleanupBlock();
-
- CGF.EmitBranchThroughCleanup(Cont);
- }
-
- // Go back to the try-statement fallthrough.
- CGF.Builder.restoreIP(SavedIP);
-
- // Pop out of the normal cleanup on the finally.
- if (S.getFinallyStmt())
- CGF.ExitFinallyBlock(FinallyInfo);
-
- if (Cont.isValid())
- CGF.EmitBlock(Cont.getBlock());
+ EmitTryCatchStmt(CGF, S,
+ cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
+ cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
+ cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
}
/// EmitThrowStmt - Generate code for a throw statement.
@@ -6290,10 +6053,7 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
CodeGen::CGObjCRuntime *
CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
+ if (CGM.getLangOptions().ObjCNonFragileABI)
+ return new CGObjCNonFragileABIMac(CGM);
return new CGObjCMac(CGM);
}
-
-CodeGen::CGObjCRuntime *
-CodeGen::CreateMacNonFragileABIObjCRuntime(CodeGen::CodeGenModule &CGM) {
- return new CGObjCNonFragileABIMac(CGM);
-}
OpenPOWER on IntegriCloud