19735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall//==- CGObjCRuntime.cpp - Interface to Shared Objective-C Runtime Features ==//
29735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall//
39735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall//                     The LLVM Compiler Infrastructure
49735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall//
59735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall// This file is distributed under the University of Illinois Open Source
69735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall// License. See LICENSE.TXT for details.
79735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall//
89735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall//===----------------------------------------------------------------------===//
99735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall//
109735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall// This abstract class defines the interface for Objective-C runtime-specific
119735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall// code generation.  It provides some concrete helper methods for functionality
129735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall// shared between all (or most) of the Objective-C runtimes supported by clang.
139735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall//
149735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall//===----------------------------------------------------------------------===//
159735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
169735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall#include "CGObjCRuntime.h"
1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "CGCleanup.h"
189735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall#include "CGRecordLayout.h"
199735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall#include "CodeGenFunction.h"
2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "CodeGenModule.h"
219735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall#include "clang/AST/RecordLayout.h"
229735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall#include "clang/AST/StmtObjC.h"
238b54999a831bb195c08541ca995ef0505c96193fMark Lacey#include "clang/CodeGen/CGFunctionInfo.h"
24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/IR/CallSite.h"
259735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
269735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnallusing namespace clang;
279735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnallusing namespace CodeGen;
289735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
299735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnallstatic uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
309735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                     const ObjCInterfaceDecl *OID,
319735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                     const ObjCImplementationDecl *ID,
329735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                     const ObjCIvarDecl *Ivar) {
339735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
349735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
359735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // FIXME: We should eliminate the need to have ObjCImplementationDecl passed
369735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // in here; it should never be necessary because that should be the lexical
379735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // decl context for the ivar.
389735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
399735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // If we know have an implementation (and the ivar is in it) then
409735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // look up in the implementation layout.
419735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  const ASTRecordLayout *RL;
4260ef308e51c71b760d7f598c1b763ceb7b768148Douglas Gregor  if (ID && declaresSameEntity(ID->getClassInterface(), Container))
439735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
449735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  else
459735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);
469735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
479735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Compute field index.
489735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  //
499735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // FIXME: The index here is closely tied to how ASTContext::getObjCLayout is
509735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // implemented. This should be fixed to get the information from the layout
519735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // directly.
529735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  unsigned Index = 0;
53bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian
54db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  for (const ObjCIvarDecl *IVD = Container->all_declared_ivar_begin();
55bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian       IVD; IVD = IVD->getNextIvar()) {
56bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian    if (Ivar == IVD)
579735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      break;
589735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    ++Index;
599735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  }
609735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  assert(Index < RL->getFieldCount() && "Ivar is not inside record layout!");
619735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
629735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  return RL->getFieldOffset(Index);
639735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall}
649735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
65e5b4666d9b86ea30b90b599691e75d380f84ddd6Eli Friedmanuint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
66e5b4666d9b86ea30b90b599691e75d380f84ddd6Eli Friedman                                              const ObjCInterfaceDecl *OID,
67e5b4666d9b86ea30b90b599691e75d380f84ddd6Eli Friedman                                              const ObjCIvarDecl *Ivar) {
686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return LookupFieldBitOffset(CGM, OID, nullptr, Ivar) /
69e5b4666d9b86ea30b90b599691e75d380f84ddd6Eli Friedman    CGM.getContext().getCharWidth();
709735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall}
719735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
72e5b4666d9b86ea30b90b599691e75d380f84ddd6Eli Friedmanuint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
73e5b4666d9b86ea30b90b599691e75d380f84ddd6Eli Friedman                                              const ObjCImplementationDecl *OID,
74e5b4666d9b86ea30b90b599691e75d380f84ddd6Eli Friedman                                              const ObjCIvarDecl *Ivar) {
75e5b4666d9b86ea30b90b599691e75d380f84ddd6Eli Friedman  return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) /
76e5b4666d9b86ea30b90b599691e75d380f84ddd6Eli Friedman    CGM.getContext().getCharWidth();
779735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall}
789735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
797745786044f159cf9ddf4a8a0f7be8fe2bebfa80Eli Friedmanunsigned CGObjCRuntime::ComputeBitfieldBitOffset(
807745786044f159cf9ddf4a8a0f7be8fe2bebfa80Eli Friedman    CodeGen::CodeGenModule &CGM,
817745786044f159cf9ddf4a8a0f7be8fe2bebfa80Eli Friedman    const ObjCInterfaceDecl *ID,
827745786044f159cf9ddf4a8a0f7be8fe2bebfa80Eli Friedman    const ObjCIvarDecl *Ivar) {
837745786044f159cf9ddf4a8a0f7be8fe2bebfa80Eli Friedman  return LookupFieldBitOffset(CGM, ID, ID->getImplementation(), Ivar);
847745786044f159cf9ddf4a8a0f7be8fe2bebfa80Eli Friedman}
857745786044f159cf9ddf4a8a0f7be8fe2bebfa80Eli Friedman
869735ca6e01113aec6a825dd5b1cb1b98fb377d31David ChisnallLValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
879735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                               const ObjCInterfaceDecl *OID,
889735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                               llvm::Value *BaseValue,
899735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                               const ObjCIvarDecl *Ivar,
909735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                               unsigned CVRQualifiers,
919735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                               llvm::Value *Offset) {
929735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Compute (type*) ( (char *) BaseValue + Offset)
939735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  QualType IvarTy = Ivar->getType();
942acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
9572d2dab6058467036df73a5f668036a519043e5bChandler Carruth  llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, CGF.Int8PtrTy);
969735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  V = CGF.Builder.CreateInBoundsGEP(V, Offset, "add.ptr");
979735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
989735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  if (!Ivar->isBitField()) {
9972d2dab6058467036df73a5f668036a519043e5bChandler Carruth    V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy));
100d71f44266a598ab174f17435289526bbb57000e2Eli Friedman    LValue LV = CGF.MakeNaturalAlignAddrLValue(V, IvarTy);
1019735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    LV.getQuals().addCVRQualifiers(CVRQualifiers);
1029735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    return LV;
1039735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  }
1049735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
1059735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // We need to compute an access strategy for this bit-field. We are given the
1069735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // offset to the first byte in the bit-field, the sub-byte offset is taken
1079735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // from the original layout. We reuse the normal bit-field access strategy by
1089735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // treating this as an access to a struct where the bit-field is in byte 0,
1099735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // and adjust the containing type size as appropriate.
1109735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  //
1119735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // FIXME: Note that currently we make a very conservative estimate of the
1129735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // alignment of the bit-field, because (a) it is not clear what guarantees the
1139735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // runtime makes us, and (b) we don't have a way to specify that the struct is
1149735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // at an alignment plus offset.
1159735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  //
1169735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Note, there is a subtle invariant here: we can only call this routine on
1179735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // non-synthesized ivars but we may be called for synthesized ivars.  However,
1189735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // a synthesized ivar can never be a bit-field, so this is safe.
1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  uint64_t FieldBitOffset = LookupFieldBitOffset(CGF.CGM, OID, nullptr, Ivar);
12018052cd75ef2793c756d851af29d39d5b538fe50Ken Dyck  uint64_t BitOffset = FieldBitOffset % CGF.CGM.getContext().getCharWidth();
12164aa4b3ec7e62288e2e66c1935487ece995ca94bJohn McCall  uint64_t AlignmentBits = CGF.CGM.getTarget().getCharAlign();
122a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith  uint64_t BitFieldSize = Ivar->getBitWidthValue(CGF.getContext());
12372d2dab6058467036df73a5f668036a519043e5bChandler Carruth  CharUnits StorageSize =
12472d2dab6058467036df73a5f668036a519043e5bChandler Carruth    CGF.CGM.getContext().toCharUnitsFromBits(
12572d2dab6058467036df73a5f668036a519043e5bChandler Carruth      llvm::RoundUpToAlignment(BitOffset + BitFieldSize, AlignmentBits));
12672d2dab6058467036df73a5f668036a519043e5bChandler Carruth  CharUnits Alignment = CGF.CGM.getContext().toCharUnitsFromBits(AlignmentBits);
1279735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
1289735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Allocate a new CGBitFieldInfo object to describe this access.
1299735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  //
1309735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // FIXME: This is incredibly wasteful, these should be uniqued or part of some
1319735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // layout object. However, this is blocked on other cleanups to the
1329735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Objective-C code, so for now we just live with allocating a bunch of these
1339735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // objects.
1349735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  CGBitFieldInfo *Info = new (CGF.CGM.getContext()) CGBitFieldInfo(
1359735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    CGBitFieldInfo::MakeInfo(CGF.CGM.getTypes(), Ivar, BitOffset, BitFieldSize,
13672d2dab6058467036df73a5f668036a519043e5bChandler Carruth                             CGF.CGM.getContext().toBits(StorageSize),
13772d2dab6058467036df73a5f668036a519043e5bChandler Carruth                             Alignment.getQuantity()));
1389735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
13972d2dab6058467036df73a5f668036a519043e5bChandler Carruth  V = CGF.Builder.CreateBitCast(V,
14072d2dab6058467036df73a5f668036a519043e5bChandler Carruth                                llvm::Type::getIntNPtrTy(CGF.getLLVMContext(),
14172d2dab6058467036df73a5f668036a519043e5bChandler Carruth                                                         Info->StorageSize));
1429735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  return LValue::MakeBitfield(V, *Info,
143f4bcfa1b1850711d5eb092f2b0639331ef9f09f1Eli Friedman                              IvarTy.withCVRQualifiers(CVRQualifiers),
14472d2dab6058467036df73a5f668036a519043e5bChandler Carruth                              Alignment);
1459735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall}
1469735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
1479735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnallnamespace {
1489735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  struct CatchHandler {
1499735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    const VarDecl *Variable;
1509735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    const Stmt *Body;
1519735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    llvm::BasicBlock *Block;
152ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    llvm::Constant *TypeInfo;
1539735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  };
1549735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
1559735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  struct CallObjCEndCatch : EHScopeStack::Cleanup {
1569735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    CallObjCEndCatch(bool MightThrow, llvm::Value *Fn) :
1579735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      MightThrow(MightThrow), Fn(Fn) {}
1589735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    bool MightThrow;
1599735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    llvm::Value *Fn;
1609735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void Emit(CodeGenFunction &CGF, Flags flags) override {
1629735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      if (!MightThrow) {
1639735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall        CGF.Builder.CreateCall(Fn)->setDoesNotThrow();
1649735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall        return;
1659735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      }
1669735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
167bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall      CGF.EmitRuntimeCallOrInvoke(Fn);
1689735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    }
1699735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  };
1709735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall}
1719735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
1729735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
1739735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnallvoid CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF,
1749735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                     const ObjCAtTryStmt &S,
175789ecdebd04aebdb2d6b801ebe8e04a189ebc023David Chisnall                                     llvm::Constant *beginCatchFn,
176789ecdebd04aebdb2d6b801ebe8e04a189ebc023David Chisnall                                     llvm::Constant *endCatchFn,
177789ecdebd04aebdb2d6b801ebe8e04a189ebc023David Chisnall                                     llvm::Constant *exceptionRethrowFn) {
1789735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Jump destination for falling out of catch bodies.
1799735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  CodeGenFunction::JumpDest Cont;
1809735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  if (S.getNumCatchStmts())
1819735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    Cont = CGF.getJumpDestInCurrentScope("eh.cont");
1829735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
1839735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  CodeGenFunction::FinallyInfo FinallyInfo;
1849735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt())
185d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    FinallyInfo.enter(CGF, Finally->getFinallyBody(),
186d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall                      beginCatchFn, endCatchFn, exceptionRethrowFn);
1879735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
1885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<CatchHandler, 8> Handlers;
1899735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
1909735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Enter the catch, if there is one.
1919735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  if (S.getNumCatchStmts()) {
1929735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) {
1939735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      const ObjCAtCatchStmt *CatchStmt = S.getCatchStmt(I);
1949735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
1959735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
1969735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      Handlers.push_back(CatchHandler());
1979735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      CatchHandler &Handler = Handlers.back();
1989735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      Handler.Variable = CatchDecl;
1999735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      Handler.Body = CatchStmt->getCatchBody();
2009735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      Handler.Block = CGF.createBasicBlock("catch");
2019735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2029735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      // @catch(...) always matches.
2039735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      if (!CatchDecl) {
2046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        Handler.TypeInfo = nullptr; // catch-all
2059735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall        // Don't consider any other catches.
2069735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall        break;
2079735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      }
2089735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2099735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      Handler.TypeInfo = GetEHType(CatchDecl->getType());
2109735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    }
2119735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2129735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
2139735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    for (unsigned I = 0, E = Handlers.size(); I != E; ++I)
2149735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block);
2159735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  }
2169735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2179735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Emit the try body.
2189735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  CGF.EmitStmt(S.getTryBody());
2199735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2209735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Leave the try.
2219735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  if (S.getNumCatchStmts())
222777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    CGF.popCatchScope();
2239735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2249735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Remember where we were.
2259735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
2269735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2279735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Emit the handlers.
2289735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
2299735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    CatchHandler &Handler = Handlers[I];
2309735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2319735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    CGF.EmitBlock(Handler.Block);
232ae270598d5c7a9a283d4b3ddce53b151c6e2b182Bill Wendling    llvm::Value *RawExn = CGF.getExceptionFromSlot();
2339735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2349735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    // Enter the catch.
2359735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    llvm::Value *Exn = RawExn;
2369735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    if (beginCatchFn) {
2379735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      Exn = CGF.Builder.CreateCall(beginCatchFn, RawExn, "exn.adjusted");
2389735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      cast<llvm::CallInst>(Exn)->setDoesNotThrow();
2399735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    }
2409735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
241b9c8c42c392d0fe7079b968bbd5ed2bd4bd2f8d2Eric Christopher    CodeGenFunction::LexicalScope cleanups(CGF, Handler.Body->getSourceRange());
242fe3e3bd63d73c1a370b0b0447b8744d495fa6626John McCall
2439735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    if (endCatchFn) {
2449735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      // Add a cleanup to leave the catch.
2456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      bool EndCatchMightThrow = (Handler.Variable == nullptr);
2469735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2479735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      CGF.EHStack.pushCleanup<CallObjCEndCatch>(NormalAndEHCleanup,
2489735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                                EndCatchMightThrow,
2499735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                                endCatchFn);
2509735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    }
2519735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2529735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    // Bind the catch parameter if it exists.
2539735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    if (const VarDecl *CatchParam = Handler.Variable) {
2542acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner      llvm::Type *CatchType = CGF.ConvertType(CatchParam->getType());
2559735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType);
2569735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2579735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      CGF.EmitAutoVarDecl(*CatchParam);
258b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall
259b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall      llvm::Value *CatchParamAddr = CGF.GetAddrOfLocalVar(CatchParam);
260b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall
261b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall      switch (CatchParam->getType().getQualifiers().getObjCLifetime()) {
262b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall      case Qualifiers::OCL_Strong:
263b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall        CastExn = CGF.EmitARCRetainNonBlock(CastExn);
264b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall        // fallthrough
265b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall
266b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall      case Qualifiers::OCL_None:
267b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall      case Qualifiers::OCL_ExplicitNone:
268b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall      case Qualifiers::OCL_Autoreleasing:
269b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall        CGF.Builder.CreateStore(CastExn, CatchParamAddr);
270b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall        break;
271b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall
272b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall      case Qualifiers::OCL_Weak:
273b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall        CGF.EmitARCInitWeak(CatchParamAddr, CastExn);
274b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall        break;
275b29b12d494babf061201ffbcbcacddd21abec50eJohn McCall      }
2769735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    }
2779735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2789735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    CGF.ObjCEHValueStack.push_back(Exn);
2799735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    CGF.EmitStmt(Handler.Body);
2809735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    CGF.ObjCEHValueStack.pop_back();
2819735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
282fe3e3bd63d73c1a370b0b0447b8744d495fa6626John McCall    // Leave any cleanups associated with the catch.
283fe3e3bd63d73c1a370b0b0447b8744d495fa6626John McCall    cleanups.ForceCleanup();
2849735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2859735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    CGF.EmitBranchThroughCleanup(Cont);
2869735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  }
2879735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2889735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Go back to the try-statement fallthrough.
2899735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  CGF.Builder.restoreIP(SavedIP);
2909735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
291d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall  // Pop out of the finally.
2929735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  if (S.getFinallyStmt())
293d768e9d29abe1ac1ccc3ed63f2dce835d9bab342John McCall    FinallyInfo.exit(CGF);
2949735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2959735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  if (Cont.isValid())
2969735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    CGF.EmitBlock(Cont.getBlock());
2979735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall}
2989735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
2999735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnallnamespace {
3009735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  struct CallSyncExit : EHScopeStack::Cleanup {
3019735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    llvm::Value *SyncExitFn;
3029735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    llvm::Value *SyncArg;
3039735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
3049735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
3059735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void Emit(CodeGenFunction &CGF, Flags flags) override {
3079735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall      CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
3089735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall    }
3099735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  };
3109735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall}
3119735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
3129735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnallvoid CGObjCRuntime::EmitAtSynchronizedStmt(CodeGenFunction &CGF,
3139735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                           const ObjCAtSynchronizedStmt &S,
3149735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                           llvm::Function *syncEnterFn,
3159735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall                                           llvm::Function *syncExitFn) {
31607524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  CodeGenFunction::RunCleanupsScope cleanups(CGF);
31707524039dce5c820f111a1b3f772b4261f004b4aJohn McCall
31807524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  // Evaluate the lock operand.  This is guaranteed to dominate the
31907524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  // ARC release and lock-release cleanups.
32007524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  const Expr *lockExpr = S.getSynchExpr();
32107524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  llvm::Value *lock;
3224e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (CGF.getLangOpts().ObjCAutoRefCount) {
32307524039dce5c820f111a1b3f772b4261f004b4aJohn McCall    lock = CGF.EmitARCRetainScalarExpr(lockExpr);
32407524039dce5c820f111a1b3f772b4261f004b4aJohn McCall    lock = CGF.EmitObjCConsumeObject(lockExpr->getType(), lock);
32507524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  } else {
32607524039dce5c820f111a1b3f772b4261f004b4aJohn McCall    lock = CGF.EmitScalarExpr(lockExpr);
32707524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  }
32807524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  lock = CGF.Builder.CreateBitCast(lock, CGF.VoidPtrTy);
3299735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
3309735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Acquire the lock.
33107524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  CGF.Builder.CreateCall(syncEnterFn, lock)->setDoesNotThrow();
3329735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
3339735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Register an all-paths cleanup to release the lock.
33407524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  CGF.EHStack.pushCleanup<CallSyncExit>(NormalAndEHCleanup, syncExitFn, lock);
3359735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall
3369735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  // Emit the body of the statement.
3379735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall  CGF.EmitStmt(S.getSynchBody());
3389735ca6e01113aec6a825dd5b1cb1b98fb377d31David Chisnall}
339de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
340de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall/// Compute the pointer-to-function type to which a message send
341de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall/// should be casted in order to correctly call the given method
342de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall/// with the given arguments.
343de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall///
344de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall/// \param method - may be null
345de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall/// \param resultType - the result type to use if there's no method
346c7810fed64bff037915ba48f39f34614bc54517fJames Dennett/// \param callArgs - the actual arguments, including implicit ones
347de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallCGObjCRuntime::MessageSendInfo
348de5d3c717684f3821b8db58037bc7140acf134aaJohn McCallCGObjCRuntime::getMessageSendInfo(const ObjCMethodDecl *method,
349de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall                                  QualType resultType,
350de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall                                  CallArgList &callArgs) {
351de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  // If there's a method, use information from that.
352de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  if (method) {
353de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    const CGFunctionInfo &signature =
354de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall      CGM.getTypes().arrangeObjCMessageSendSignature(method, callArgs[0].Ty);
355de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
356de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    llvm::PointerType *signatureType =
357de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall      CGM.getTypes().GetFunctionType(signature)->getPointerTo();
358de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
359de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    // If that's not variadic, there's no need to recompute the ABI
360de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    // arrangement.
361de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    if (!signature.isVariadic())
362de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall      return MessageSendInfo(signature, signatureType);
363de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
364de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    // Otherwise, there is.
365de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    FunctionType::ExtInfo einfo = signature.getExtInfo();
366de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    const CGFunctionInfo &argsInfo =
3670f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall      CGM.getTypes().arrangeFreeFunctionCall(resultType, callArgs, einfo,
3680f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                             signature.getRequiredArgs());
369de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
370de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    return MessageSendInfo(argsInfo, signatureType);
371de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  }
372de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
373de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  // There's no method;  just use a default CC.
374de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  const CGFunctionInfo &argsInfo =
3750f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall    CGM.getTypes().arrangeFreeFunctionCall(resultType, callArgs,
3760f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                           FunctionType::ExtInfo(),
3770f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall                                           RequiredArgs::All);
378de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall
379de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  // Derive the signature to call from that.
380de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  llvm::PointerType *signatureType =
381de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall    CGM.getTypes().GetFunctionType(argsInfo)->getPointerTo();
382de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall  return MessageSendInfo(argsInfo, signatureType);
383de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall}
384