diff options
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
| -rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 1419 | 
1 files changed, 807 insertions, 612 deletions
| diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index a45446a7065a3..5f3ebbd757652 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -659,9 +659,6 @@ public:    // MessageRefCPtrTy - clang type for struct _message_ref_t*    QualType MessageRefCPtrTy; -  // MessengerTy - Type of the messenger (shown as IMP above) -  llvm::FunctionType *MessengerTy; -    // SuperMessageRefTy - LLVM for:    // struct _super_message_ref_t {    //   SUPER_IMP messenger; @@ -735,20 +732,6 @@ public:  class CGObjCCommonMac : public CodeGen::CGObjCRuntime {  public: -  // FIXME - accessibility -  class GC_IVAR { -  public: -    unsigned ivar_bytepos; -    unsigned ivar_size; -    GC_IVAR(unsigned bytepos = 0, unsigned size = 0) -      : ivar_bytepos(bytepos), ivar_size(size) {} - -    // Allow sorting based on byte pos. -    bool operator<(const GC_IVAR &b) const { -      return ivar_bytepos < b.ivar_bytepos; -    } -  }; -    class SKIP_SCAN {    public:      unsigned skip; @@ -830,10 +813,6 @@ protected:    // FIXME! May not be needing this after all.    unsigned ObjCABI; -  // gc ivar layout bitmap calculation helper caches. -  SmallVector<GC_IVAR, 16> SkipIvars; -  SmallVector<GC_IVAR, 16> IvarsInfo; -      // arc/mrr layout of captured block literal variables.    SmallVector<RUN_SKIP, 16> RunSkipBlockVars; @@ -854,7 +833,7 @@ protected:    llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;    /// DefinedCategoryNames - list of category names in form Class_Category. -  llvm::SetVector<std::string> DefinedCategoryNames; +  llvm::SmallSetVector<std::string, 16> DefinedCategoryNames;    /// MethodVarTypes - uniqued method type signatures. We have to use    /// a StringMap here because have no other unique reference. @@ -934,20 +913,28 @@ protected:    /// BuildIvarLayout - Builds ivar layout bitmap for the class    /// implementation for the __strong or __weak case.    /// +  /// \param hasMRCWeakIvars - Whether we are compiling in MRC and there +  ///   are any weak ivars defined directly in the class.  Meaningless unless +  ///   building a weak layout.  Does not guarantee that the layout will +  ///   actually have any entries, because the ivar might be under-aligned.    llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI, -                                  bool ForStrongLayout); -   -  llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap); +                                  CharUnits beginOffset, +                                  CharUnits endOffset, +                                  bool forStrongLayout, +                                  bool hasMRCWeakIvars); -  void BuildAggrIvarRecordLayout(const RecordType *RT, -                                 unsigned int BytePos, bool ForStrongLayout, -                                 bool &HasUnion); -  void BuildAggrIvarLayout(const ObjCImplementationDecl *OI, -                           const llvm::StructLayout *Layout, -                           const RecordDecl *RD, -                           ArrayRef<const FieldDecl*> RecFields, -                           unsigned int BytePos, bool ForStrongLayout, -                           bool &HasUnion); +  llvm::Constant *BuildStrongIvarLayout(const ObjCImplementationDecl *OI, +                                        CharUnits beginOffset, +                                        CharUnits endOffset) { +    return BuildIvarLayout(OI, beginOffset, endOffset, true, false); +  } + +  llvm::Constant *BuildWeakIvarLayout(const ObjCImplementationDecl *OI, +                                      CharUnits beginOffset, +                                      CharUnits endOffset, +                                      bool hasMRCWeakIvars) { +    return BuildIvarLayout(OI, beginOffset, endOffset, false, hasMRCWeakIvars); +  }    Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT, bool ByrefLayout); @@ -970,7 +957,6 @@ protected:    llvm::Constant *getBitmapBlockLayout(bool ComputeByrefLayout); -    /// GetIvarLayoutName - Returns a unique constant for the given    /// ivar layout bitmap.    llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident, @@ -1002,6 +988,7 @@ protected:    /// defined. The return value has type ProtocolPtrTy.    llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); +public:    /// CreateMetadataVar - Create a global variable with internal    /// linkage for use by the Objective-C runtime.    /// @@ -1017,9 +1004,10 @@ protected:    /// \param AddToUsed - Whether the variable should be added to    /// "llvm.used".    llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *Init, -                                          StringRef Section, unsigned Align, +                                          StringRef Section, CharUnits Align,                                            bool AddToUsed); +protected:    CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,                                    ReturnValueSlot Return,                                    QualType ResultType, @@ -1029,6 +1017,7 @@ protected:                                    bool IsSuper,                                    const CallArgList &CallArgs,                                    const ObjCMethodDecl *OMD, +                                  const ObjCInterfaceDecl *ClassReceiver,                                    const ObjCCommonTypesHelper &ObjCTypes);    /// EmitImageInfo - Emit the image info marker used to encode some module @@ -1039,7 +1028,11 @@ public:    CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :      CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { } -  llvm::Constant *GenerateConstantString(const StringLiteral *SL) override; +  bool isNonFragileABI() const { +    return ObjCABI == 2; +  } + +  ConstantAddress GenerateConstantString(const StringLiteral *SL) override;    llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,                                   const ObjCContainerDecl *CD=nullptr) override; @@ -1084,7 +1077,9 @@ private:    /// EmitClassExtension - Generate the class extension structure used    /// to store the weak ivar layout and properties. The return value    /// has type ClassExtensionPtrTy. -  llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID); +  llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID, +                                     CharUnits instanceSize, +                                     bool hasMRCWeakIvars);    /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,    /// for the given class. @@ -1172,8 +1167,8 @@ private:    /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,    /// for the given selector. -  llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel,  -                            bool lval=false); +  llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel); +  Address EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel);  public:    CGObjCMac(CodeGen::CodeGenModule &cgm); @@ -1199,8 +1194,8 @@ public:    llvm::Value *GetClass(CodeGenFunction &CGF,                          const ObjCInterfaceDecl *ID) override; -  llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel, -                           bool lval = false) override; +  llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override; +  Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override;    /// The NeXT/Apple runtimes do not support typed selectors; just emit an    /// untyped one. @@ -1236,19 +1231,19 @@ public:    void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,                       bool ClearInsertionPoint=true) override;    llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, -                                 llvm::Value *AddrWeakObj) override; +                                 Address AddrWeakObj) override;    void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, -                          llvm::Value *src, llvm::Value *dst) override; +                          llvm::Value *src, Address dst) override;    void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, -                            llvm::Value *src, llvm::Value *dest, +                            llvm::Value *src, Address dest,                              bool threadlocal = false) override;    void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, -                          llvm::Value *src, llvm::Value *dest, +                          llvm::Value *src, Address dest,                            llvm::Value *ivarOffset) override;    void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, -                                llvm::Value *src, llvm::Value *dest) override; +                                llvm::Value *src, Address dest) override;    void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, -                                llvm::Value *dest, llvm::Value *src, +                                Address dest, Address src,                                  llvm::Value *size) override;    LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy, @@ -1395,8 +1390,8 @@ private:    /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,    /// for the given selector. -  llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel,  -                            bool lval=false); +  llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel); +  Address EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel);    /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C    /// interface. The return value has type EHTypePtrTy. @@ -1474,9 +1469,10 @@ public:    llvm::Value *GetClass(CodeGenFunction &CGF,                          const ObjCInterfaceDecl *ID) override; -  llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel, -                           bool lvalue = false) override -    { return EmitSelector(CGF, Sel, lvalue); } +  llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override +    { return EmitSelector(CGF, Sel); } +  Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override +    { return EmitSelectorAddr(CGF, Sel); }    /// The NeXT/Apple runtimes do not support typed selectors; just emit an    /// untyped one. @@ -1531,19 +1527,19 @@ public:    void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,                       bool ClearInsertionPoint=true) override;    llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, -                                 llvm::Value *AddrWeakObj) override; +                                 Address AddrWeakObj) override;    void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, -                          llvm::Value *src, llvm::Value *dst) override; +                          llvm::Value *src, Address edst) override;    void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, -                            llvm::Value *src, llvm::Value *dest, +                            llvm::Value *src, Address dest,                              bool threadlocal = false) override;    void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, -                          llvm::Value *src, llvm::Value *dest, +                          llvm::Value *src, Address dest,                            llvm::Value *ivarOffset) override;    void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, -                                llvm::Value *src, llvm::Value *dest) override; +                                llvm::Value *src, Address dest) override;    void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, -                                llvm::Value *dest, llvm::Value *src, +                                Address dest, Address src,                                  llvm::Value *size) override;    LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,                                llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, @@ -1645,7 +1641,7 @@ struct NullReturnState {      // memory or (2) agg values in registers.      if (result.isAggregate()) {        assert(result.isAggregate() && "null init of non-aggregate result?"); -      CGF.EmitNullInitialization(result.getAggregateAddr(), resultType); +      CGF.EmitNullInitialization(result.getAggregateAddress(), resultType);        if (contBB) CGF.EmitBlock(contBB);        return result;      } @@ -1711,9 +1707,11 @@ llvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,  }  /// GetSelector - Return the pointer to the unique'd string for this selector. -llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel,  -                                    bool lval) { -  return EmitSelector(CGF, Sel, lval); +llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) { +  return EmitSelector(CGF, Sel); +} +Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) { +  return EmitSelectorAddr(CGF, Sel);  }  llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl                                      *Method) { @@ -1756,7 +1754,7 @@ llvm::Constant *CGObjCMac::GetEHType(QualType T) {     };  */ -llvm::Constant *CGObjCCommonMac::GenerateConstantString( +ConstantAddress CGObjCCommonMac::GenerateConstantString(    const StringLiteral *SL) {    return (CGM.getLangOpts().NoConstantCFStrings == 0 ?             CGM.GetAddrOfConstantCFString(SL) : @@ -1783,13 +1781,14 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,                                      const ObjCMethodDecl *Method) {    // Create and init a super structure; this is a (receiver, class)    // pair we will pass to objc_msgSendSuper. -  llvm::Value *ObjCSuper = -    CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super"); +  Address ObjCSuper = +    CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(), +                         "objc_super");    llvm::Value *ReceiverAsObject =      CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);    CGF.Builder.CreateStore(        ReceiverAsObject, -      CGF.Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 0)); +      CGF.Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero()));    // If this is a class message the metaclass is passed as the target.    llvm::Value *Target; @@ -1803,12 +1802,13 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,        // isa" is the first ivar in a class (which it must be).        Target = EmitClassRef(CGF, Class->getSuperClass());        Target = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, Target, 0); -      Target = CGF.Builder.CreateLoad(Target); +      Target = CGF.Builder.CreateAlignedLoad(Target, CGF.getPointerAlign());      } else {        llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);        llvm::Value *SuperPtr =            CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, MetaClassPtr, 1); -      llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr); +      llvm::Value *Super = +        CGF.Builder.CreateAlignedLoad(SuperPtr, CGF.getPointerAlign());        Target = Super;      }    } else if (isCategoryImpl) @@ -1816,19 +1816,19 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,    else {      llvm::Value *ClassPtr = EmitSuperClassRef(Class);      ClassPtr = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, ClassPtr, 1); -    Target = CGF.Builder.CreateLoad(ClassPtr); +    Target = CGF.Builder.CreateAlignedLoad(ClassPtr, CGF.getPointerAlign());    }    // FIXME: We shouldn't need to do this cast, rectify the ASTContext and    // ObjCTypes types.    llvm::Type *ClassTy =      CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());    Target = CGF.Builder.CreateBitCast(Target, ClassTy); -  CGF.Builder.CreateStore( -      Target, CGF.Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 1)); +  CGF.Builder.CreateStore(Target, +          CGF.Builder.CreateStructGEP(ObjCSuper, 1, CGF.getPointerSize()));    return EmitMessageSend(CGF, Return, ResultType,                           EmitSelector(CGF, Sel), -                         ObjCSuper, ObjCTypes.SuperPtrCTy, -                         true, CallArgs, Method, ObjCTypes); +                         ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy, +                         true, CallArgs, Method, Class, ObjCTypes);  }  /// Generate code for a message send expression. @@ -1843,7 +1843,16 @@ CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,    return EmitMessageSend(CGF, Return, ResultType,                           EmitSelector(CGF, Sel),                           Receiver, CGF.getContext().getObjCIdType(), -                         false, CallArgs, Method, ObjCTypes); +                         false, CallArgs, Method, Class, ObjCTypes); +} + +static bool isWeakLinkedClass(const ObjCInterfaceDecl *ID) { +  do { +    if (ID->isWeakImported()) +      return true; +  } while ((ID = ID->getSuperClass())); + +  return false;  }  CodeGen::RValue @@ -1856,6 +1865,7 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,                                   bool IsSuper,                                   const CallArgList &CallArgs,                                   const ObjCMethodDecl *Method, +                                 const ObjCInterfaceDecl *ClassReceiver,                                   const ObjCCommonTypesHelper &ObjCTypes) {    CallArgList ActualArgs;    if (!IsSuper) @@ -1872,11 +1882,38 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,                 CGM.getContext().getCanonicalType(ResultType) &&             "Result type mismatch!"); +  bool ReceiverCanBeNull = true; + +  // Super dispatch assumes that self is non-null; even the messenger +  // doesn't have a null check internally. +  if (IsSuper) { +    ReceiverCanBeNull = false; + +  // If this is a direct dispatch of a class method, check whether the class, +  // or anything in its hierarchy, was weak-linked. +  } else if (ClassReceiver && Method && Method->isClassMethod()) { +    ReceiverCanBeNull = isWeakLinkedClass(ClassReceiver); + +  // If we're emitting a method, and self is const (meaning just ARC, for now), +  // and the receiver is a load of self, then self is a valid object. +  } else if (auto CurMethod = +               dyn_cast_or_null<ObjCMethodDecl>(CGF.CurCodeDecl)) { +    auto Self = CurMethod->getSelfDecl(); +    if (Self->getType().isConstQualified()) { +      if (auto LI = dyn_cast<llvm::LoadInst>(Arg0->stripPointerCasts())) { +        llvm::Value *SelfAddr = CGF.GetAddrOfLocalVar(Self).getPointer(); +        if (SelfAddr == LI->getPointerOperand()) { +          ReceiverCanBeNull = false; +        } +      } +    } +  } +    NullReturnState nullReturn;    llvm::Constant *Fn = nullptr;    if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) { -    if (!IsSuper) nullReturn.init(CGF, Arg0); +    if (ReceiverCanBeNull) nullReturn.init(CGF, Arg0);      Fn = (ObjCABI == 2) ?  ObjCTypes.getSendStretFn2(IsSuper)        : ObjCTypes.getSendStretFn(IsSuper);    } else if (CGM.ReturnTypeUsesFPRet(ResultType)) { @@ -1888,76 +1925,182 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,    } else {      // arm64 uses objc_msgSend for stret methods and yet null receiver check      // must be made for it. -    if (!IsSuper && CGM.ReturnTypeUsesSRet(MSI.CallInfo)) +    if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(MSI.CallInfo))        nullReturn.init(CGF, Arg0);      Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)        : ObjCTypes.getSendFn(IsSuper);    } -   -  bool requiresnullCheck = false; -  if (CGM.getLangOpts().ObjCAutoRefCount && Method) + +  // Emit a null-check if there's a consumed argument other than the receiver. +  bool RequiresNullCheck = false; +  if (ReceiverCanBeNull && CGM.getLangOpts().ObjCAutoRefCount && Method) {      for (const auto *ParamDecl : Method->params()) {        if (ParamDecl->hasAttr<NSConsumedAttr>()) {          if (!nullReturn.NullBB)            nullReturn.init(CGF, Arg0); -        requiresnullCheck = true; +        RequiresNullCheck = true;          break;        }      } +  } +  llvm::Instruction *CallSite;    Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType); -  RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs); +  RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs, +                               CGCalleeInfo(), &CallSite); + +  // Mark the call as noreturn if the method is marked noreturn and the +  // receiver cannot be null. +  if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) { +    llvm::CallSite(CallSite).setDoesNotReturn(); +  } +    return nullReturn.complete(CGF, rvalue, ResultType, CallArgs, -                             requiresnullCheck ? Method : nullptr); +                             RequiresNullCheck ? Method : nullptr);  } -static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) { +static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, +                                           bool pointee = false) { +  // Note that GC qualification applies recursively to C pointer types +  // that aren't otherwise decorated.  This is weird, but it's probably +  // an intentional workaround to the unreliable placement of GC qualifiers.    if (FQT.isObjCGCStrong())      return Qualifiers::Strong; -   -  if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak) + +  if (FQT.isObjCGCWeak())      return Qualifiers::Weak; + +  if (auto ownership = FQT.getObjCLifetime()) { +    // Ownership does not apply recursively to C pointer types. +    if (pointee) return Qualifiers::GCNone; +    switch (ownership) { +    case Qualifiers::OCL_Weak: return Qualifiers::Weak; +    case Qualifiers::OCL_Strong: return Qualifiers::Strong; +    case Qualifiers::OCL_ExplicitNone: return Qualifiers::GCNone; +    case Qualifiers::OCL_Autoreleasing: llvm_unreachable("autoreleasing ivar?"); +    case Qualifiers::OCL_None: llvm_unreachable("known nonzero"); +    } +    llvm_unreachable("bad objc ownership"); +  } -  // check for __unsafe_unretained -  if (FQT.getObjCLifetime() == Qualifiers::OCL_ExplicitNone) -    return Qualifiers::GCNone; -   +  // Treat unqualified retainable pointers as strong.    if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())      return Qualifiers::Strong; -  if (const PointerType *PT = FQT->getAs<PointerType>()) -    return GetGCAttrTypeForType(Ctx, PT->getPointeeType()); +  // Walk into C pointer types, but only in GC. +  if (Ctx.getLangOpts().getGC() != LangOptions::NonGC) { +    if (const PointerType *PT = FQT->getAs<PointerType>()) +      return GetGCAttrTypeForType(Ctx, PT->getPointeeType(), /*pointee*/ true); +  }    return Qualifiers::GCNone;  } +namespace { +  struct IvarInfo { +    CharUnits Offset; +    uint64_t SizeInWords; +    IvarInfo(CharUnits offset, uint64_t sizeInWords) +      : Offset(offset), SizeInWords(sizeInWords) {} + +    // Allow sorting based on byte pos. +    bool operator<(const IvarInfo &other) const { +      return Offset < other.Offset; +    } +  }; + +  /// A helper class for building GC layout strings. +  class IvarLayoutBuilder { +    CodeGenModule &CGM; + +    /// The start of the layout.  Offsets will be relative to this value, +    /// and entries less than this value will be silently discarded. +    CharUnits InstanceBegin; + +    /// The end of the layout.  Offsets will never exceed this value. +    CharUnits InstanceEnd; + +    /// Whether we're generating the strong layout or the weak layout. +    bool ForStrongLayout; + +    /// Whether the offsets in IvarsInfo might be out-of-order. +    bool IsDisordered = false; + +    llvm::SmallVector<IvarInfo, 8> IvarsInfo; +  public: +    IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin, +                      CharUnits instanceEnd, bool forStrongLayout) +      : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd), +        ForStrongLayout(forStrongLayout) { +    } + +    void visitRecord(const RecordType *RT, CharUnits offset); + +    template <class Iterator, class GetOffsetFn> +    void visitAggregate(Iterator begin, Iterator end,  +                        CharUnits aggrOffset, +                        const GetOffsetFn &getOffset); + +    void visitField(const FieldDecl *field, CharUnits offset); + +    /// Add the layout of a block implementation. +    void visitBlock(const CGBlockInfo &blockInfo); + +    /// Is there any information for an interesting bitmap? +    bool hasBitmapData() const { return !IvarsInfo.empty(); } + +    llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC, +                                llvm::SmallVectorImpl<unsigned char> &buffer); + +    static void dump(ArrayRef<unsigned char> buffer) { +      const unsigned char *s = buffer.data(); +      for (unsigned i = 0, e = buffer.size(); i < e; i++) +        if (!(s[i] & 0xf0)) +          printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); +        else +          printf("0x%x%s",  s[i], s[i] != 0 ? ", " : ""); +      printf("\n"); +    } +  }; +} +  llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,                                                  const CGBlockInfo &blockInfo) {    llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy); -  if (CGM.getLangOpts().getGC() == LangOptions::NonGC && -      !CGM.getLangOpts().ObjCAutoRefCount) +  if (CGM.getLangOpts().getGC() == LangOptions::NonGC)      return nullPtr; -  bool hasUnion = false; -  SkipIvars.clear(); -  IvarsInfo.clear(); -  unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0); -  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth(); +  IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.BlockSize, +                            /*for strong layout*/ true); + +  builder.visitBlock(blockInfo); + +  if (!builder.hasBitmapData()) +    return nullPtr; + +  llvm::SmallVector<unsigned char, 32> buffer; +  llvm::Constant *C = builder.buildBitmap(*this, buffer); +  if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) { +    printf("\n block variable layout for block: "); +    builder.dump(buffer); +  } +  return C; +} + +void IvarLayoutBuilder::visitBlock(const CGBlockInfo &blockInfo) {    // __isa is the first field in block descriptor and must assume by runtime's    // convention that it is GC'able. -  IvarsInfo.push_back(GC_IVAR(0, 1)); +  IvarsInfo.push_back(IvarInfo(CharUnits::Zero(), 1));    const BlockDecl *blockDecl = blockInfo.getBlockDecl(); -  // Calculate the basic layout of the block structure. -  const llvm::StructLayout *layout = -    CGM.getDataLayout().getStructLayout(blockInfo.StructureType); -    // Ignore the optional 'this' capture: C++ objects are not assumed    // to be GC'ed. +  CharUnits lastFieldOffset; +    // Walk the captured variables.    for (const auto &CI : blockDecl->captures()) {      const VarDecl *variable = CI.getVariable(); @@ -1968,64 +2111,51 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,      // Ignore constant captures.      if (capture.isConstant()) continue; -    uint64_t fieldOffset = layout->getElementOffset(capture.getIndex()); +    CharUnits fieldOffset = capture.getOffset(); + +    // Block fields are not necessarily ordered; if we detect that we're +    // adding them out-of-order, make sure we sort later. +    if (fieldOffset < lastFieldOffset) +      IsDisordered = true; +    lastFieldOffset = fieldOffset;      // __block variables are passed by their descriptor address.      if (CI.isByRef()) { -      IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1)); +      IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1));        continue;      }      assert(!type->isArrayType() && "array variable should not be caught");      if (const RecordType *record = type->getAs<RecordType>()) { -      BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion); +      visitRecord(record, fieldOffset);        continue;      }      Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type); -    unsigned fieldSize = CGM.getContext().getTypeSize(type); - -    if (GCAttr == Qualifiers::Strong) -      IvarsInfo.push_back(GC_IVAR(fieldOffset, -                                  fieldSize / WordSizeInBits)); -    else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak) -      SkipIvars.push_back(GC_IVAR(fieldOffset, -                                  fieldSize / ByteSizeInBits)); -  } -   -  if (IvarsInfo.empty()) -    return nullPtr; -  // Sort on byte position; captures might not be allocated in order, -  // and unions can do funny things. -  llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end()); -  llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end()); -   -  std::string BitMap; -  llvm::Constant *C = BuildIvarLayoutBitmap(BitMap); -  if (CGM.getLangOpts().ObjCGCBitmapPrint) { -    printf("\n block variable layout for block: "); -    const unsigned char *s = (const unsigned char*)BitMap.c_str(); -    for (unsigned i = 0, e = BitMap.size(); i < e; i++) -      if (!(s[i] & 0xf0)) -        printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); -      else -        printf("0x%x%s",  s[i], s[i] != 0 ? ", " : ""); -    printf("\n"); +    if (GCAttr == Qualifiers::Strong) { +      assert(CGM.getContext().getTypeSize(type) +                == CGM.getTarget().getPointerWidth(0)); +      IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1)); +    }    } -   -  return C;  } +  /// getBlockCaptureLifetime - This routine returns life time of the captured  /// block variable for the purpose of block layout meta-data generation. FQT is  /// the type of the variable captured in the block.  Qualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,                                                                    bool ByrefLayout) { +  // If it has an ownership qualifier, we're done. +  if (auto lifetime = FQT.getObjCLifetime()) +    return lifetime; + +  // If it doesn't, and this is ARC, it has no ownership.    if (CGM.getLangOpts().ObjCAutoRefCount) -    return FQT.getObjCLifetime(); +    return Qualifiers::OCL_None; -  // MRR. +  // In MRC, retainable pointers are owned by non-__block variables.    if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())      return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong; @@ -2361,9 +2491,8 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {      }    } -  int e = Layout.size()-1; -  while (e >= 0) { -    unsigned char inst = Layout[e--]; +  while (!Layout.empty()) { +    unsigned char inst = Layout.back();      enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);      if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)        Layout.pop_back(); @@ -2376,19 +2505,19 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {      // Block variable layout instruction has been inlined.      if (CGM.getLangOpts().ObjCGCBitmapPrint) {        if (ComputeByrefLayout) -        printf("\n Inline instruction for BYREF variable layout: "); +        printf("\n Inline BYREF variable layout: ");        else -        printf("\n Inline instruction for block variable layout: "); -      printf("0x0%" PRIx64 "\n", Result); -    } -    if (WordSizeInBytes == 8) { -      const llvm::APInt Instruction(64, Result); -      return llvm::Constant::getIntegerValue(CGM.Int64Ty, Instruction); -    } -    else { -      const llvm::APInt Instruction(32, Result); -      return llvm::Constant::getIntegerValue(CGM.Int32Ty, Instruction); +        printf("\n Inline block variable layout: "); +      printf("0x0%" PRIx64 "", Result); +      if (auto numStrong = (Result & 0xF00) >> 8) +        printf(", BL_STRONG:%d", (int) numStrong); +      if (auto numByref = (Result & 0x0F0) >> 4) +        printf(", BL_BYREF:%d", (int) numByref); +      if (auto numWeak = (Result & 0x00F) >> 0) +        printf(", BL_WEAK:%d", (int) numWeak); +      printf(", BL_OPERATOR:0\n");      } +    return llvm::ConstantInt::get(CGM.IntPtrTy, Result);    }    unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0; @@ -2399,9 +2528,9 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {    if (CGM.getLangOpts().ObjCGCBitmapPrint) {      if (ComputeByrefLayout) -      printf("\n BYREF variable layout: "); +      printf("\n Byref variable layout: ");      else -      printf("\n block variable layout: "); +      printf("\n Block variable layout: ");      for (unsigned i = 0, e = BitMap.size(); i != e; i++) {        unsigned char inst = BitMap[i];        enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4); @@ -2443,7 +2572,7 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {    llvm::GlobalVariable *Entry = CreateMetadataVar(        "OBJC_CLASS_NAME_",        llvm::ConstantDataArray::getString(VMContext, BitMap, false), -      "__TEXT,__objc_classname,cstring_literals", 1, true); +      "__TEXT,__objc_classname,cstring_literals", CharUnits::One(), true);    return getConstantGEP(VMContext, Entry, 0, 0);  } @@ -2511,6 +2640,8 @@ llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,    if (const RecordType *record = T->getAs<RecordType>()) {      BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion, true /*ByrefLayout */);      llvm::Constant *Result = getBitmapBlockLayout(true); +    if (isa<llvm::ConstantInt>(Result)) +      Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.Int8PtrTy);      return Result;    }    llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy); @@ -2699,7 +2830,7 @@ CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,    // No special section, but goes in llvm.used    return CreateMetadataVar("\01l_OBJC_PROTOCOLEXT_" + PD->getName(), Init, -                           StringRef(), 0, true); +                           StringRef(), CGM.getPointerAlign(), true);  }  /* @@ -2738,7 +2869,7 @@ CGObjCMac::EmitProtocolList(Twine Name,    llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);    llvm::GlobalVariable *GV =      CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip", -                      4, false); +                      CGM.getPointerAlign(), false);    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);  } @@ -2779,15 +2910,26 @@ llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,                                         const ObjCCommonTypesHelper &ObjCTypes) {    SmallVector<llvm::Constant *, 16> Properties;    llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet; + +  auto AddProperty = [&](const ObjCPropertyDecl *PD) { +    llvm::Constant *Prop[] = {GetPropertyName(PD->getIdentifier()), +                              GetPropertyTypeString(PD, Container)}; +    Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop)); +  }; +  if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) +    for (const ObjCCategoryDecl *ClassExt : OID->known_extensions()) +      for (auto *PD : ClassExt->properties()) { +        PropertySet.insert(PD->getIdentifier()); +        AddProperty(PD); +      }    for (const auto *PD : OCD->properties()) { -    PropertySet.insert(PD->getIdentifier()); -    llvm::Constant *Prop[] = { -      GetPropertyName(PD->getIdentifier()), -      GetPropertyTypeString(PD, Container) -    }; -    Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, -                                                   Prop)); +    // Don't emit duplicate metadata for properties that were already in a +    // class extension. +    if (!PropertySet.insert(PD->getIdentifier()).second) +      continue; +    AddProperty(PD);    } +    if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {      for (const auto *P : OID->all_referenced_protocols())        PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes); @@ -2815,7 +2957,7 @@ llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,      CreateMetadataVar(Name, Init,                        (ObjCABI == 2) ? "__DATA, __objc_const" :                        "__OBJC,__property,regular,no_dead_strip", -                      (ObjCABI == 2) ? 8 : 4, +                      CGM.getPointerAlign(),                        true);    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);  } @@ -2834,7 +2976,7 @@ CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,    llvm::GlobalVariable *GV = CreateMetadataVar(        Name, Init, (ObjCABI == 2) ? "__DATA, __objc_const" : StringRef(), -      (ObjCABI == 2) ? 8 : 4, true); +      CGM.getPointerAlign(), true);    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);  } @@ -2872,7 +3014,8 @@ CGObjCMac::EmitMethodDescList(Twine Name, const char *Section,    Values[1] = llvm::ConstantArray::get(AT, Methods);    llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); -  llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); +  llvm::GlobalVariable *GV = +    CreateMetadataVar(Name, Init, Section, CGM.getPointerAlign(), true);    return llvm::ConstantExpr::getBitCast(GV,                                          ObjCTypes.MethodDescriptionListPtrTy);  } @@ -2944,7 +3087,8 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {    llvm::GlobalVariable *GV =        CreateMetadataVar("OBJC_CATEGORY_" + ExtName.str(), Init, -                        "__OBJC,__category,regular,no_dead_strip", 4, true); +                        "__OBJC,__category,regular,no_dead_strip", +                        CGM.getPointerAlign(), true);    DefinedCategories.push_back(GV);    DefinedCategoryNames.insert(ExtName.str());    // method definition entries must be clear for next implementation. @@ -2952,10 +3096,24 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {  }  enum FragileClassFlags { +  /// Apparently: is not a meta-class.    FragileABI_Class_Factory                 = 0x00001, + +  /// Is a meta-class.    FragileABI_Class_Meta                    = 0x00002, + +  /// Has a non-trivial constructor or destructor.    FragileABI_Class_HasCXXStructors         = 0x02000, -  FragileABI_Class_Hidden                  = 0x20000 + +  /// Has hidden visibility. +  FragileABI_Class_Hidden                  = 0x20000, + +  /// Class implementation was compiled under ARC. +  FragileABI_Class_CompiledByARC           = 0x04000000, + +  /// Class implementation was compiled under MRC and has MRC weak ivars. +  /// Exclusive with CompiledByARC. +  FragileABI_Class_HasMRCWeakIvars         = 0x08000000,  };  enum NonFragileClassFlags { @@ -2965,7 +3123,7 @@ enum NonFragileClassFlags {    /// Is a root class.    NonFragileABI_Class_Root                 = 0x00002, -  /// Has a C++ constructor and destructor. +  /// Has a non-trivial constructor or destructor.    NonFragileABI_Class_HasCXXStructors      = 0x00004,    /// Has hidden visibility. @@ -2981,9 +3139,46 @@ enum NonFragileClassFlags {    NonFragileABI_Class_CompiledByARC        = 0x00080,    /// Class has non-trivial destructors, but zero-initialization is okay. -  NonFragileABI_Class_HasCXXDestructorOnly = 0x00100 +  NonFragileABI_Class_HasCXXDestructorOnly = 0x00100, + +  /// Class implementation was compiled under MRC and has MRC weak ivars. +  /// Exclusive with CompiledByARC. +  NonFragileABI_Class_HasMRCWeakIvars      = 0x00200,  }; +static bool hasWeakMember(QualType type) { +  if (type.getObjCLifetime() == Qualifiers::OCL_Weak) { +    return true; +  } + +  if (auto recType = type->getAs<RecordType>()) { +    for (auto field : recType->getDecl()->fields()) { +      if (hasWeakMember(field->getType())) +        return true; +    } +  } + +  return false; +} + +/// For compatibility, we only want to set the "HasMRCWeakIvars" flag +/// (and actually fill in a layout string) if we really do have any +/// __weak ivars. +static bool hasMRCWeakIvars(CodeGenModule &CGM, +                            const ObjCImplementationDecl *ID) { +  if (!CGM.getLangOpts().ObjCWeak) return false; +  assert(CGM.getLangOpts().getGC() == LangOptions::NonGC); + +  for (const ObjCIvarDecl *ivar = +         ID->getClassInterface()->all_declared_ivar_begin(); +       ivar; ivar = ivar->getNextIvar()) { +    if (hasWeakMember(ivar->getType())) +      return true; +  } + +  return false; +} +  /*    struct _objc_class {    Class isa; @@ -3017,8 +3212,16 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {    unsigned Flags = FragileABI_Class_Factory;    if (ID->hasNonZeroConstructors() || ID->hasDestructors())      Flags |= FragileABI_Class_HasCXXStructors; -  unsigned Size = -    CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity(); + +  bool hasMRCWeak = false; + +  if (CGM.getLangOpts().ObjCAutoRefCount) +    Flags |= FragileABI_Class_CompiledByARC; +  else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID))) +    Flags |= FragileABI_Class_HasMRCWeakIvars; + +  CharUnits Size = +    CGM.getContext().getASTObjCImplementationLayout(ID).getSize();    // FIXME: Set CXX-structors flag.    if (ID->getClassInterface()->getVisibility() == HiddenVisibility) @@ -3062,7 +3265,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {    // Version is always 0.    Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);    Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); -  Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); +  Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size.getQuantity());    Values[ 6] = EmitIvarList(ID, false);    Values[7] = EmitMethodList("OBJC_INSTANCE_METHODS_" + ID->getName(),                               "__OBJC,__inst_meth,regular,no_dead_strip", @@ -3070,8 +3273,8 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {    // cache is always NULL.    Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);    Values[ 9] = Protocols; -  Values[10] = BuildIvarLayout(ID, true); -  Values[11] = EmitClassExtension(ID); +  Values[10] = BuildStrongIvarLayout(ID, CharUnits::Zero(), Size); +  Values[11] = EmitClassExtension(ID, Size, hasMRCWeak);    llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,                                                     Values);    std::string Name("OBJC_CLASS_"); @@ -3084,10 +3287,10 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {             "Forward metaclass reference has incorrect type.");      GV->setInitializer(Init);      GV->setSection(Section); -    GV->setAlignment(4); +    GV->setAlignment(CGM.getPointerAlign().getQuantity());      CGM.addCompilerUsedGlobal(GV);    } else -    GV = CreateMetadataVar(Name, Init, Section, 4, true); +    GV = CreateMetadataVar(Name, Init, Section, CGM.getPointerAlign(), true);    DefinedClasses.push_back(GV);    ImplementedClasses.push_back(Interface);    // method definition entries must be clear for next implementation. @@ -3198,6 +3401,10 @@ llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {  }  /* +  Emit a "class extension", which in this specific context means extra +  data that doesn't fit in the normal fragile-ABI class structure, and +  has nothing to do with the language concept of a class extension. +    struct objc_class_ext {    uint32_t size;    const char *weak_ivar_layout; @@ -3205,13 +3412,15 @@ llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {    };  */  llvm::Constant * -CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) { +CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID, +                              CharUnits InstanceSize, bool hasMRCWeakIvars) {    uint64_t Size =      CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);    llvm::Constant *Values[3];    Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); -  Values[1] = BuildIvarLayout(ID, false); +  Values[1] = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize, +                                  hasMRCWeakIvars);    Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),                                 ID, ID->getClassInterface(), ObjCTypes); @@ -3222,7 +3431,8 @@ CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {    llvm::Constant *Init =      llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);    return CreateMetadataVar("OBJC_CLASSEXT_" + ID->getName(), Init, -                           "__OBJC,__class_ext,regular,no_dead_strip", 4, true); +                           "__OBJC,__class_ext,regular,no_dead_strip", +                           CGM.getPointerAlign(), true);  }  /* @@ -3280,11 +3490,12 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,    if (ForClass)      GV =          CreateMetadataVar("OBJC_CLASS_VARIABLES_" + ID->getName(), Init, -                          "__OBJC,__class_vars,regular,no_dead_strip", 4, true); +                          "__OBJC,__class_vars,regular,no_dead_strip", +                          CGM.getPointerAlign(), true);    else      GV = CreateMetadataVar("OBJC_INSTANCE_VARIABLES_" + ID->getName(), Init, -                           "__OBJC,__instance_vars,regular,no_dead_strip", 4, -                           true); +                           "__OBJC,__instance_vars,regular,no_dead_strip", +                           CGM.getPointerAlign(), true);    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);  } @@ -3334,7 +3545,8 @@ llvm::Constant *CGObjCMac::EmitMethodList(Twine Name,    Values[2] = llvm::ConstantArray::get(AT, Methods);    llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); -  llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); +  llvm::GlobalVariable *GV = +    CreateMetadataVar(Name, Init, Section, CGM.getPointerAlign(), true);    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);  } @@ -3359,7 +3571,7 @@ llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,  llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,                                                           llvm::Constant *Init,                                                           StringRef Section, -                                                         unsigned Align, +                                                         CharUnits Align,                                                           bool AddToUsed) {    llvm::Type *Ty = Init->getType();    llvm::GlobalVariable *GV = @@ -3367,8 +3579,7 @@ llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,                               llvm::GlobalValue::PrivateLinkage, Init, Name);    if (!Section.empty())      GV->setSection(Section); -  if (Align) -    GV->setAlignment(Align); +  GV->setAlignment(Align.getQuantity());    if (AddToUsed)      CGM.addCompilerUsedGlobal(GV);    return GV; @@ -3421,16 +3632,16 @@ void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,  }  namespace { -  struct PerformFragileFinally : EHScopeStack::Cleanup { +  struct PerformFragileFinally final : EHScopeStack::Cleanup {      const Stmt &S; -    llvm::Value *SyncArgSlot; -    llvm::Value *CallTryExitVar; -    llvm::Value *ExceptionData; +    Address SyncArgSlot; +    Address CallTryExitVar; +    Address ExceptionData;      ObjCTypesHelper &ObjCTypes;      PerformFragileFinally(const Stmt *S, -                          llvm::Value *SyncArgSlot, -                          llvm::Value *CallTryExitVar, -                          llvm::Value *ExceptionData, +                          Address SyncArgSlot, +                          Address CallTryExitVar, +                          Address ExceptionData,                            ObjCTypesHelper *ObjCTypes)        : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),          ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {} @@ -3447,7 +3658,7 @@ namespace {        CGF.EmitBlock(FinallyCallExit);        CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(), -                                  ExceptionData); +                                  ExceptionData.getPointer());        CGF.EmitBlock(FinallyNoCallExit); @@ -3568,7 +3779,7 @@ void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {  void FragileHazards::emitHazardsInNewBlocks() {    if (Locals.empty()) return; -  CGBuilderTy Builder(CGF.getLLVMContext()); +  CGBuilderTy Builder(CGF, CGF.getLLVMContext());    // Iterate through all blocks, skipping those prior to the try.    for (llvm::Function::iterator @@ -3607,6 +3818,10 @@ static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {    if (V) S.insert(V);  } +static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, Address V) { +  if (V.isValid()) S.insert(V.getPointer()); +} +  void FragileHazards::collectLocals() {    // Compute a set of allocas to ignore.    llvm::DenseSet<llvm::Value*> AllocasToIgnore; @@ -3760,21 +3975,23 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,    // @synchronized.  We can't avoid a temp here because we need the    // value to be preserved.  If the backend ever does liveness    // correctly after setjmp, this will be unnecessary. -  llvm::Value *SyncArgSlot = nullptr; +  Address SyncArgSlot = Address::invalid();    if (!isTry) {      llvm::Value *SyncArg =        CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());      SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);      CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncEnterFn(), SyncArg); -    SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg"); +    SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), +                                       CGF.getPointerAlign(), "sync.arg");      CGF.Builder.CreateStore(SyncArg, SyncArgSlot);    }    // Allocate memory for the setjmp buffer.  This needs to be kept    // live throughout the try and catch blocks. -  llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy, -                                                    "exceptiondata.ptr"); +  Address ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy, +                                               CGF.getPointerAlign(), +                                               "exceptiondata.ptr");    // Create the fragile hazards.  Note that this will not capture any    // of the allocas required for exception processing, but will @@ -3790,12 +4007,13 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,    // The setjmp-safety rule here is that we should always store to this    // variable in a place that dominates the branch through the cleanup    // without passing through any setjmps. -  llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), -                                                     "_call_try_exit"); +  Address CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), +                                                CharUnits::One(), +                                                "_call_try_exit");    // A slot containing the exception to rethrow.  Only needed when we    // have both a @catch and a @finally. -  llvm::Value *PropagatingExnVar = nullptr; +  Address PropagatingExnVar = Address::invalid();    // Push a normal cleanup to leave the try scope.    CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalAndEHCleanup, &S, @@ -3808,13 +4026,14 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,    //  - Call objc_exception_try_enter to push ExceptionData on top of    //    the EH stack.    CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(), -                              ExceptionData); +                              ExceptionData.getPointer());    //  - Call setjmp on the exception data buffer.    llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);    llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };    llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP( -      ObjCTypes.ExceptionDataTy, ExceptionData, GEPIndexes, "setjmp_buffer"); +      ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes, +      "setjmp_buffer");    llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(        ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");    SetJmpResult->setCanReturnTwice(); @@ -3854,7 +4073,7 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,      // nothing can cross this so the value is already in SSA form.      llvm::CallInst *Caught =        CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(), -                                  ExceptionData, "caught"); +                                  ExceptionData.getPointer(), "caught");      // Push the exception to rethrow onto the EH value stack for the      // benefit of any @throws in the handlers. @@ -3870,13 +4089,14 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,        // Save the currently-propagating exception before        // objc_exception_try_enter clears the exception slot.        PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(), +                                               CGF.getPointerAlign(),                                                 "propagating_exception");        CGF.Builder.CreateStore(Caught, PropagatingExnVar);        // Enter a new exception try block (in case a @catch block        // throws an exception).        CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(), -                                  ExceptionData); +                                  ExceptionData.getPointer());        llvm::CallInst *SetJmpResult =          CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(), @@ -3928,7 +4148,7 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,            assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");            // These types work out because ConvertType(id) == i8*. -          CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam)); +          EmitInitOfCatchParam(CGF, Caught, CatchParam);          }          CGF.EmitStmt(CatchStmt->getCatchBody()); @@ -3975,7 +4195,7 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,        llvm::Value *Tmp =          CGF.Builder.CreateBitCast(Caught,                                    CGF.ConvertType(CatchParam->getType())); -      CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam)); +      EmitInitOfCatchParam(CGF, Tmp, CatchParam);        CGF.EmitStmt(CatchStmt->getCatchBody()); @@ -4008,10 +4228,10 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,        // Extract the new exception and save it to the        // propagating-exception slot. -      assert(PropagatingExnVar); +      assert(PropagatingExnVar.isValid());        llvm::CallInst *NewCaught =          CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(), -                                    ExceptionData, "caught"); +                                    ExceptionData.getPointer(), "caught");        CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);        // Don't pop the catch handler; the throw already did. @@ -4036,14 +4256,14 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,    if (CGF.HaveInsertPoint()) {      // If we have a propagating-exception variable, check it.      llvm::Value *PropagatingExn; -    if (PropagatingExnVar) { +    if (PropagatingExnVar.isValid()) {        PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);      // Otherwise, just look in the buffer for the exception to throw.      } else {        llvm::CallInst *Caught =          CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(), -                                    ExceptionData); +                                    ExceptionData.getPointer());        PropagatingExn = Caught;      } @@ -4083,14 +4303,13 @@ void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,  /// object: objc_read_weak (id *src)  ///  llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, -                                          llvm::Value *AddrWeakObj) { -  llvm::Type* DestTy = -    cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); +                                          Address AddrWeakObj) { +  llvm::Type* DestTy = AddrWeakObj.getElementType();    AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,                                            ObjCTypes.PtrObjectPtrTy);    llvm::Value *read_weak =      CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(), -                                AddrWeakObj, "weakread"); +                                AddrWeakObj.getPointer(), "weakread");    read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);    return read_weak;  } @@ -4099,7 +4318,7 @@ llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,  /// objc_assign_weak (id src, id *dst)  ///  void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, -                                   llvm::Value *src, llvm::Value *dst) { +                                   llvm::Value *src, Address dst) {    llvm::Type * SrcTy = src->getType();    if (!isa<llvm::PointerType>(SrcTy)) {      unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy); @@ -4110,7 +4329,7 @@ void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,    }    src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);    dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); -  llvm::Value *args[] = { src, dst }; +  llvm::Value *args[] = { src, dst.getPointer() };    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),                                args, "weakassign");    return; @@ -4120,7 +4339,7 @@ void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,  /// objc_assign_global (id src, id *dst)  ///  void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, -                                     llvm::Value *src, llvm::Value *dst, +                                     llvm::Value *src, Address dst,                                       bool threadlocal) {    llvm::Type * SrcTy = src->getType();    if (!isa<llvm::PointerType>(SrcTy)) { @@ -4132,7 +4351,7 @@ void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,    }    src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);    dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); -  llvm::Value *args[] = { src, dst }; +  llvm::Value *args[] = { src, dst.getPointer() };    if (!threadlocal)      CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),                                  args, "globalassign"); @@ -4146,7 +4365,7 @@ void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,  /// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)  ///  void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, -                                   llvm::Value *src, llvm::Value *dst, +                                   llvm::Value *src, Address dst,                                     llvm::Value *ivarOffset) {    assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");    llvm::Type * SrcTy = src->getType(); @@ -4159,7 +4378,7 @@ void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,    }    src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);    dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); -  llvm::Value *args[] = { src, dst, ivarOffset }; +  llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);    return;  } @@ -4168,7 +4387,7 @@ void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,  /// objc_assign_strongCast (id src, id *dst)  ///  void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, -                                         llvm::Value *src, llvm::Value *dst) { +                                         llvm::Value *src, Address dst) {    llvm::Type * SrcTy = src->getType();    if (!isa<llvm::PointerType>(SrcTy)) {      unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy); @@ -4179,19 +4398,19 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,    }    src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);    dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); -  llvm::Value *args[] = { src, dst }; +  llvm::Value *args[] = { src, dst.getPointer() };    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), -                              args, "weakassign"); +                              args, "strongassign");    return;  }  void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, -                                         llvm::Value *DestPtr, -                                         llvm::Value *SrcPtr, +                                         Address DestPtr, +                                         Address SrcPtr,                                           llvm::Value *size) {    SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);    DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); -  llvm::Value *args[] = { DestPtr, SrcPtr, size }; +  llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size };    CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);  } @@ -4283,7 +4502,7 @@ void CGObjCCommonMac::EmitImageInfo() {    // Indicate whether we're compiling this to run on a simulator.    const llvm::Triple &Triple = CGM.getTarget().getTriple(); -  if (Triple.isiOS() && +  if ((Triple.isiOS() || Triple.isWatchOS()) &&        (Triple.getArch() == llvm::Triple::x86 ||         Triple.getArch() == llvm::Triple::x86_64))      Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated", @@ -4312,7 +4531,8 @@ void CGObjCMac::EmitModuleInfo() {    };    CreateMetadataVar("OBJC_MODULES",                      llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values), -                    "__OBJC,__module_info,regular,no_dead_strip", 4, true); +                    "__OBJC,__module_info,regular,no_dead_strip", +                    CGM.getPointerAlign(), true);  }  llvm::Constant *CGObjCMac::EmitModuleSymbols() { @@ -4356,7 +4576,8 @@ llvm::Constant *CGObjCMac::EmitModuleSymbols() {    llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);    llvm::GlobalVariable *GV = CreateMetadataVar( -      "OBJC_SYMBOLS", Init, "__OBJC,__symbols,regular,no_dead_strip", 4, true); +      "OBJC_SYMBOLS", Init, "__OBJC,__symbols,regular,no_dead_strip", +      CGM.getPointerAlign(), true);    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);  } @@ -4372,10 +4593,11 @@ llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,                                     ObjCTypes.ClassPtrTy);      Entry = CreateMetadataVar(          "OBJC_CLASS_REFERENCES_", Casted, -        "__OBJC,__cls_refs,literal_pointers,no_dead_strip", 4, true); +        "__OBJC,__cls_refs,literal_pointers,no_dead_strip", +        CGM.getPointerAlign(), true);    } -  return CGF.Builder.CreateLoad(Entry); +  return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign());  }  llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF, @@ -4388,23 +4610,25 @@ llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {    return EmitClassRefFromId(CGF, II);  } -llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel, -                                     bool lvalue) { -  llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; +llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) { +  return CGF.Builder.CreateLoad(EmitSelectorAddr(CGF, Sel)); +} + +Address CGObjCMac::EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel) { +  CharUnits Align = CGF.getPointerAlign(); +  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];    if (!Entry) {      llvm::Constant *Casted =        llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),                                       ObjCTypes.SelectorPtrTy);      Entry = CreateMetadataVar(          "OBJC_SELECTOR_REFERENCES_", Casted, -        "__OBJC,__message_refs,literal_pointers,no_dead_strip", 4, true); +        "__OBJC,__message_refs,literal_pointers,no_dead_strip", Align, true);      Entry->setExternallyInitialized(true);    } -  if (lvalue) -    return Entry; -  return CGF.Builder.CreateLoad(Entry); +  return Address(Entry, Align);  }  llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) { @@ -4415,7 +4639,7 @@ llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {            llvm::ConstantDataArray::getString(VMContext, RuntimeName),            ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals"                            : "__TEXT,__cstring,cstring_literals"), -          1, true); +          CharUnits::One(), true);      return getConstantGEP(VMContext, Entry, 0, 0);  } @@ -4435,308 +4659,247 @@ llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,    return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);  } -void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT, -                                                unsigned int BytePos, -                                                bool ForStrongLayout, -                                                bool &HasUnion) { +void IvarLayoutBuilder::visitRecord(const RecordType *RT, +                                    CharUnits offset) {    const RecordDecl *RD = RT->getDecl(); -  // FIXME - Use iterator. -  SmallVector<const FieldDecl*, 16> Fields(RD->fields()); -  llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0)); -  const llvm::StructLayout *RecLayout = -    CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty)); -  BuildAggrIvarLayout(nullptr, RecLayout, RD, Fields, BytePos, ForStrongLayout, -                      HasUnion); -} +  // If this is a union, remember that we had one, because it might mess +  // up the ordering of layout entries. +  if (RD->isUnion()) +    IsDisordered = true; + +  const ASTRecordLayout *recLayout = nullptr; +  visitAggregate(RD->field_begin(), RD->field_end(), offset, +                 [&](const FieldDecl *field) -> CharUnits { +    if (!recLayout) +      recLayout = &CGM.getContext().getASTRecordLayout(RD); +    auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex()); +    return CGM.getContext().toCharUnitsFromBits(offsetInBits); +  }); +} + +template <class Iterator, class GetOffsetFn> +void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,  +                                       CharUnits aggregateOffset, +                                       const GetOffsetFn &getOffset) { +  for (; begin != end; ++begin) { +    auto field = *begin; + +    // Skip over bitfields. +    if (field->isBitField()) { +      continue; +    } -void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, -                             const llvm::StructLayout *Layout, -                             const RecordDecl *RD, -                             ArrayRef<const FieldDecl*> RecFields, -                             unsigned int BytePos, bool ForStrongLayout, -                             bool &HasUnion) { -  bool IsUnion = (RD && RD->isUnion()); -  uint64_t MaxUnionIvarSize = 0; -  uint64_t MaxSkippedUnionIvarSize = 0; -  const FieldDecl *MaxField = nullptr; -  const FieldDecl *MaxSkippedField = nullptr; -  const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr; -  uint64_t MaxFieldOffset = 0; -  uint64_t MaxSkippedFieldOffset = 0; -  uint64_t LastBitfieldOrUnnamedOffset = 0; -  uint64_t FirstFieldDelta = 0; +    // Compute the offset of the field within the aggregate. +    CharUnits fieldOffset = aggregateOffset + getOffset(field); -  if (RecFields.empty()) -    return; -  unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0); -  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth(); -  if (!RD && CGM.getLangOpts().ObjCAutoRefCount) { -    const FieldDecl *FirstField = RecFields[0]; -    FirstFieldDelta =  -      ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField)); +    visitField(field, fieldOffset);    } -   -  for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { -    const FieldDecl *Field = RecFields[i]; -    uint64_t FieldOffset; -    if (RD) { -      // 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) / ByteSizeInBits) - FirstFieldDelta; -    } else -      FieldOffset =  -        ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta; +} -    // Skip over unnamed or bitfields -    if (!Field->getIdentifier() || Field->isBitField()) { -      LastFieldBitfieldOrUnnamed = Field; -      LastBitfieldOrUnnamedOffset = FieldOffset; -      continue; -    } +/// Collect layout information for the given fields into IvarsInfo. +void IvarLayoutBuilder::visitField(const FieldDecl *field, +                                   CharUnits fieldOffset) { +  QualType fieldType = field->getType(); -    LastFieldBitfieldOrUnnamed = nullptr; -    QualType FQT = Field->getType(); -    if (FQT->isRecordType() || FQT->isUnionType()) { -      if (FQT->isUnionType()) -        HasUnion = true; +  // Drill down into arrays. +  uint64_t numElts = 1; +  while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) { +    numElts *= arrayType->getSize().getZExtValue(); +    fieldType = arrayType->getElementType(); +  } -      BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(), -                                BytePos + FieldOffset, -                                ForStrongLayout, HasUnion); -      continue; -    } +  assert(!fieldType->isArrayType() && "ivar of non-constant array type?"); -    if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { -      const ConstantArrayType *CArray = -        dyn_cast_or_null<ConstantArrayType>(Array); -      uint64_t ElCount = CArray->getSize().getZExtValue(); -      assert(CArray && "only array with known element size is supported"); -      FQT = CArray->getElementType(); -      while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { -        const ConstantArrayType *CArray = -          dyn_cast_or_null<ConstantArrayType>(Array); -        ElCount *= CArray->getSize().getZExtValue(); -        FQT = CArray->getElementType(); -      } -      if (FQT->isRecordType() && ElCount) { -        int OldIndex = IvarsInfo.size() - 1; -        int OldSkIndex = SkipIvars.size() -1; +  // If we ended up with a zero-sized array, we've done what we can do within +  // the limits of this layout encoding. +  if (numElts == 0) return; -        const RecordType *RT = FQT->getAs<RecordType>(); -        BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset, -                                  ForStrongLayout, HasUnion); +  // Recurse if the base element type is a record type. +  if (auto recType = fieldType->getAs<RecordType>()) { +    size_t oldEnd = IvarsInfo.size(); -        // Replicate layout information for each array element. Note that -        // one element is already done. -        uint64_t ElIx = 1; -        for (int FirstIndex = IvarsInfo.size() - 1, -               FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) { -          uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits; -          for (int i = OldIndex+1; i <= FirstIndex; ++i) -            IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx, -                                        IvarsInfo[i].ivar_size)); -          for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i) -            SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx, -                                        SkipIvars[i].ivar_size)); -        } -        continue; -      } -    } -    // At this point, we are done with Record/Union and array there of. -    // For other arrays we are down to its element type. -    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT); - -    unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType()); -    if ((ForStrongLayout && GCAttr == Qualifiers::Strong) -        || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { -      if (IsUnion) { -        uint64_t UnionIvarSize = FieldSize / WordSizeInBits; -        if (UnionIvarSize > MaxUnionIvarSize) { -          MaxUnionIvarSize = UnionIvarSize; -          MaxField = Field; -          MaxFieldOffset = FieldOffset; -        } -      } else { -        IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, -                                    FieldSize / WordSizeInBits)); -      } -    } else if ((ForStrongLayout && -                (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)) -               || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) { -      if (IsUnion) { -        // FIXME: Why the asymmetry? We divide by word size in bits on other -        // side. -        uint64_t UnionIvarSize = FieldSize / ByteSizeInBits; -        if (UnionIvarSize > MaxSkippedUnionIvarSize) { -          MaxSkippedUnionIvarSize = UnionIvarSize; -          MaxSkippedField = Field; -          MaxSkippedFieldOffset = FieldOffset; +    visitRecord(recType, fieldOffset); + +    // If we have an array, replicate the first entry's layout information. +    auto numEltEntries = IvarsInfo.size() - oldEnd; +    if (numElts != 1 && numEltEntries != 0) { +      CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType); +      for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) { +        // Copy the last numEltEntries onto the end of the array, adjusting +        // each for the element size. +        for (size_t i = 0; i != numEltEntries; ++i) { +          auto firstEntry = IvarsInfo[oldEnd + i]; +          IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize, +                                       firstEntry.SizeInWords));          } -      } else { -        // FIXME: Why the asymmetry, we divide by byte size in bits here? -        SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, -                                    FieldSize / ByteSizeInBits));        }      } + +    return;    } -  if (LastFieldBitfieldOrUnnamed) { -    if (LastFieldBitfieldOrUnnamed->isBitField()) { -      // Last field was a bitfield. Must update skip info. -      uint64_t BitFieldSize -          = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext()); -      GC_IVAR skivar; -      skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset; -      skivar.ivar_size = (BitFieldSize / ByteSizeInBits) -        + ((BitFieldSize % ByteSizeInBits) != 0); -      SkipIvars.push_back(skivar); -    } else { -      assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed"); -      // Last field was unnamed. Must update skip info. -      unsigned FieldSize -          = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType()); -      SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset, -                                  FieldSize / ByteSizeInBits)); -    } +  // Classify the element type. +  Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType); + +  // If it matches what we're looking for, add an entry. +  if ((ForStrongLayout && GCAttr == Qualifiers::Strong) +      || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { +    assert(CGM.getContext().getTypeSizeInChars(fieldType) +             == CGM.getPointerSize()); +    IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));    } +} -  if (MaxField) -    IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset, -                                MaxUnionIvarSize)); -  if (MaxSkippedField) -    SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset, -                                MaxSkippedUnionIvarSize)); -} - -/// BuildIvarLayoutBitmap - This routine is the horsework for doing all -/// the computations and returning the layout bitmap (for ivar or blocks) in -/// the given argument BitMap string container. Routine reads -/// two containers, IvarsInfo and SkipIvars which are assumed to be -/// filled already by the caller. -llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) { -  unsigned int WordsToScan, WordsToSkip; -  llvm::Type *PtrTy = CGM.Int8PtrTy; -   -  // Build the string of skip/scan nibbles -  SmallVector<SKIP_SCAN, 32> SkipScanIvars; -  unsigned int WordSize = -  CGM.getTypes().getDataLayout().getTypeAllocSize(PtrTy); -  if (IvarsInfo[0].ivar_bytepos == 0) { -    WordsToSkip = 0; -    WordsToScan = IvarsInfo[0].ivar_size; +/// buildBitmap - This routine does the horsework of taking the offsets of +/// strong/weak references and creating a bitmap.  The bitmap is also +/// returned in the given buffer, suitable for being passed to \c dump(). +llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC, +                                llvm::SmallVectorImpl<unsigned char> &buffer) { +  // The bitmap is a series of skip/scan instructions, aligned to word +  // boundaries.  The skip is performed first. +  const unsigned char MaxNibble = 0xF; +  const unsigned char SkipMask = 0xF0, SkipShift = 4; +  const unsigned char ScanMask = 0x0F, ScanShift = 0; + +  assert(!IvarsInfo.empty() && "generating bitmap for no data"); + +  // Sort the ivar info on byte position in case we encounterred a +  // union nested in the ivar list. +  if (IsDisordered) { +    // This isn't a stable sort, but our algorithm should handle it fine. +    llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());    } else { -    WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize; -    WordsToScan = IvarsInfo[0].ivar_size; -  } -  for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) { -    unsigned int TailPrevGCObjC = -    IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize; -    if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) { -      // consecutive 'scanned' object pointers. -      WordsToScan += IvarsInfo[i].ivar_size; -    } else { -      // Skip over 'gc'able object pointer which lay over each other. -      if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos) -        continue; -      // Must skip over 1 or more words. We save current skip/scan values -      //  and start a new pair. -      SKIP_SCAN SkScan; -      SkScan.skip = WordsToSkip; -      SkScan.scan = WordsToScan; -      SkipScanIvars.push_back(SkScan); -       -      // Skip the hole. -      SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize; -      SkScan.scan = 0; -      SkipScanIvars.push_back(SkScan); -      WordsToSkip = 0; -      WordsToScan = IvarsInfo[i].ivar_size; +#ifndef NDEBUG +    for (unsigned i = 1; i != IvarsInfo.size(); ++i) { +      assert(IvarsInfo[i - 1].Offset <= IvarsInfo[i].Offset);      } +#endif    } -  if (WordsToScan > 0) { -    SKIP_SCAN SkScan; -    SkScan.skip = WordsToSkip; -    SkScan.scan = WordsToScan; -    SkipScanIvars.push_back(SkScan); -  } -   -  if (!SkipIvars.empty()) { -    unsigned int LastIndex = SkipIvars.size()-1; -    int LastByteSkipped = -    SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size; -    LastIndex = IvarsInfo.size()-1; -    int LastByteScanned = -    IvarsInfo[LastIndex].ivar_bytepos + -    IvarsInfo[LastIndex].ivar_size * WordSize; -    // Compute number of bytes to skip at the tail end of the last ivar scanned. -    if (LastByteSkipped > LastByteScanned) { -      unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize; -      SKIP_SCAN SkScan; -      SkScan.skip = TotalWords - (LastByteScanned/WordSize); -      SkScan.scan = 0; -      SkipScanIvars.push_back(SkScan); +  assert(IvarsInfo.back().Offset < InstanceEnd); + +  assert(buffer.empty()); + +  // Skip the next N words. +  auto skip = [&](unsigned numWords) { +    assert(numWords > 0); + +    // Try to merge into the previous byte.  Since scans happen second, we +    // can't do this if it includes a scan. +    if (!buffer.empty() && !(buffer.back() & ScanMask)) { +      unsigned lastSkip = buffer.back() >> SkipShift; +      if (lastSkip < MaxNibble) { +        unsigned claimed = std::min(MaxNibble - lastSkip, numWords); +        numWords -= claimed; +        lastSkip += claimed; +        buffer.back() = (lastSkip << SkipShift); +      }      } -  } -  // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced -  // as 0xMN. -  int SkipScan = SkipScanIvars.size()-1; -  for (int i = 0; i <= SkipScan; i++) { -    if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0 -        && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) { -      // 0xM0 followed by 0x0N detected. -      SkipScanIvars[i].scan = SkipScanIvars[i+1].scan; -      for (int j = i+1; j < SkipScan; j++) -        SkipScanIvars[j] = SkipScanIvars[j+1]; -      --SkipScan; + +    while (numWords >= MaxNibble) { +      buffer.push_back(MaxNibble << SkipShift); +      numWords -= MaxNibble;      } -  } -   -  // Generate the string. -  for (int i = 0; i <= SkipScan; i++) { -    unsigned char byte; -    unsigned int skip_small = SkipScanIvars[i].skip % 0xf; -    unsigned int scan_small = SkipScanIvars[i].scan % 0xf; -    unsigned int skip_big  = SkipScanIvars[i].skip / 0xf; -    unsigned int scan_big  = SkipScanIvars[i].scan / 0xf; -     -    // first skip big. -    for (unsigned int ix = 0; ix < skip_big; ix++) -      BitMap += (unsigned char)(0xf0); -     -    // next (skip small, scan) -    if (skip_small) { -      byte = skip_small << 4; -      if (scan_big > 0) { -        byte |= 0xf; -        --scan_big; -      } else if (scan_small) { -        byte |= scan_small; -        scan_small = 0; +    if (numWords) { +      buffer.push_back(numWords << SkipShift); +    } +  }; + +  // Scan the next N words. +  auto scan = [&](unsigned numWords) { +    assert(numWords > 0); + +    // Try to merge into the previous byte.  Since scans happen second, we can +    // do this even if it includes a skip. +    if (!buffer.empty()) { +      unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift; +      if (lastScan < MaxNibble) { +        unsigned claimed = std::min(MaxNibble - lastScan, numWords); +        numWords -= claimed; +        lastScan += claimed; +        buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);        } -      BitMap += byte;      } -    // next scan big -    for (unsigned int ix = 0; ix < scan_big; ix++) -      BitMap += (unsigned char)(0x0f); -    // last scan small -    if (scan_small) { -      byte = scan_small; -      BitMap += byte; + +    while (numWords >= MaxNibble) { +      buffer.push_back(MaxNibble << ScanShift); +      numWords -= MaxNibble; +    } +    if (numWords) { +      buffer.push_back(numWords << ScanShift); +    } +  }; + +  // One past the end of the last scan. +  unsigned endOfLastScanInWords = 0; +  const CharUnits WordSize = CGM.getPointerSize(); + +  // Consider all the scan requests. +  for (auto &request : IvarsInfo) { +    CharUnits beginOfScan = request.Offset - InstanceBegin; + +    // Ignore scan requests that don't start at an even multiple of the +    // word size.  We can't encode them. +    if ((beginOfScan % WordSize) != 0) continue; + +    // Ignore scan requests that start before the instance start. +    // This assumes that scans never span that boundary.  The boundary +    // isn't the true start of the ivars, because in the fragile-ARC case +    // it's rounded up to word alignment, but the test above should leave +    // us ignoring that possibility. +    if (beginOfScan.isNegative()) { +      assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin); +      continue;      } + +    unsigned beginOfScanInWords = beginOfScan / WordSize; +    unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords; + +    // If the scan starts some number of words after the last one ended, +    // skip forward. +    if (beginOfScanInWords > endOfLastScanInWords) { +      skip(beginOfScanInWords - endOfLastScanInWords); + +    // Otherwise, start scanning where the last left off. +    } else { +      beginOfScanInWords = endOfLastScanInWords; + +      // If that leaves us with nothing to scan, ignore this request. +      if (beginOfScanInWords >= endOfScanInWords) continue; +    } + +    // Scan to the end of the request. +    assert(beginOfScanInWords < endOfScanInWords); +    scan(endOfScanInWords - beginOfScanInWords); +    endOfLastScanInWords = endOfScanInWords;    } -  // null terminate string. -  unsigned char zero = 0; -  BitMap += zero; -  llvm::GlobalVariable *Entry = CreateMetadataVar( +  if (buffer.empty()) +    return llvm::ConstantPointerNull::get(CGM.Int8PtrTy); + +  // For GC layouts, emit a skip to the end of the allocation so that we +  // have precise information about the entire thing.  This isn't useful +  // or necessary for the ARC-style layout strings. +  if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { +    unsigned lastOffsetInWords = +      (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize; +    if (lastOffsetInWords > endOfLastScanInWords) { +      skip(lastOffsetInWords - endOfLastScanInWords); +    } +  } + +  // Null terminate the string. +  buffer.push_back(0); + +  bool isNonFragileABI = CGObjC.isNonFragileABI(); + +  llvm::GlobalVariable *Entry = CGObjC.CreateMetadataVar(        "OBJC_CLASS_NAME_", -      llvm::ConstantDataArray::getString(VMContext, BitMap, false), -      ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals" -                      : "__TEXT,__cstring,cstring_literals"), -      1, true); -  return getConstantGEP(VMContext, Entry, 0, 0); +      llvm::ConstantDataArray::get(CGM.getLLVMContext(), buffer), +      (isNonFragileABI ? "__TEXT,__objc_classname,cstring_literals" +                       : "__TEXT,__cstring,cstring_literals"), +      CharUnits::One(), true); +  return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);  }  /// BuildIvarLayout - Builds ivar layout bitmap for the class @@ -4755,62 +4918,75 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) {  /// 2. When ForStrongLayout is false, following ivars are scanned:  /// - __weak anything  /// -llvm::Constant *CGObjCCommonMac::BuildIvarLayout( -  const ObjCImplementationDecl *OMD, -  bool ForStrongLayout) { -  bool hasUnion = false; - +llvm::Constant * +CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD, +                                 CharUnits beginOffset, CharUnits endOffset, +                                 bool ForStrongLayout, bool HasMRCWeakIvars) { +  // If this is MRC, and we're either building a strong layout or there +  // are no weak ivars, bail out early.    llvm::Type *PtrTy = CGM.Int8PtrTy;    if (CGM.getLangOpts().getGC() == LangOptions::NonGC && -      !CGM.getLangOpts().ObjCAutoRefCount) +      !CGM.getLangOpts().ObjCAutoRefCount && +      (ForStrongLayout || !HasMRCWeakIvars))      return llvm::Constant::getNullValue(PtrTy);    const ObjCInterfaceDecl *OI = OMD->getClassInterface(); -  SmallVector<const FieldDecl*, 32> RecFields; -  if (CGM.getLangOpts().ObjCAutoRefCount) { +  SmallVector<const ObjCIvarDecl*, 32> ivars; + +  // GC layout strings include the complete object layout, possibly +  // inaccurately in the non-fragile ABI; the runtime knows how to fix this +  // up. +  // +  // ARC layout strings only include the class's ivars.  In non-fragile +  // runtimes, that means starting at InstanceStart, rounded up to word +  // alignment.  In fragile runtimes, there's no InstanceStart, so it means +  // starting at the offset of the first ivar, rounded up to word alignment. +  // +  // MRC weak layout strings follow the ARC style. +  CharUnits baseOffset; +  if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {      for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();            IVD; IVD = IVD->getNextIvar()) -      RecFields.push_back(cast<FieldDecl>(IVD)); +      ivars.push_back(IVD); + +    if (isNonFragileABI()) { +      baseOffset = beginOffset; // InstanceStart +    } else if (!ivars.empty()) { +      baseOffset = +        CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0])); +    } else { +      baseOffset = CharUnits::Zero(); +    } + +    baseOffset = baseOffset.RoundUpToAlignment(CGM.getPointerAlign());    }    else { -    SmallVector<const ObjCIvarDecl*, 32> Ivars; -    CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars); +    CGM.getContext().DeepCollectObjCIvars(OI, true, ivars); -    // FIXME: This is not ideal; we shouldn't have to do this copy. -    RecFields.append(Ivars.begin(), Ivars.end()); +    baseOffset = CharUnits::Zero();    } -  if (RecFields.empty()) +  if (ivars.empty())      return llvm::Constant::getNullValue(PtrTy); -  SkipIvars.clear(); -  IvarsInfo.clear(); +  IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout); + +  builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(), +                         [&](const ObjCIvarDecl *ivar) -> CharUnits { +      return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar)); +  }); -  BuildAggrIvarLayout(OMD, nullptr, nullptr, RecFields, 0, ForStrongLayout, -                      hasUnion); -  if (IvarsInfo.empty()) +  if (!builder.hasBitmapData())      return llvm::Constant::getNullValue(PtrTy); -  // Sort on byte position in case we encounterred a union nested in -  // the ivar list. -  if (hasUnion && !IvarsInfo.empty()) -    std::sort(IvarsInfo.begin(), IvarsInfo.end()); -  if (hasUnion && !SkipIvars.empty()) -    std::sort(SkipIvars.begin(), SkipIvars.end()); -   -  std::string BitMap; -  llvm::Constant *C = BuildIvarLayoutBitmap(BitMap); + +  llvm::SmallVector<unsigned char, 4> buffer; +  llvm::Constant *C = builder.buildBitmap(*this, buffer); -   if (CGM.getLangOpts().ObjCGCBitmapPrint) { +   if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {      printf("\n%s ivar layout for class '%s': ",             ForStrongLayout ? "strong" : "weak",             OMD->getClassInterface()->getName().str().c_str()); -    const unsigned char *s = (const unsigned char*)BitMap.c_str(); -    for (unsigned i = 0, e = BitMap.size(); i < e; i++) -      if (!(s[i] & 0xf0)) -        printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); -      else -        printf("0x%x%s",  s[i], s[i] != 0 ? ", " : ""); -    printf("\n"); +    builder.dump(buffer);    }    return C;  } @@ -4825,7 +5001,7 @@ llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {          llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),          ((ObjCABI == 2) ? "__TEXT,__objc_methname,cstring_literals"                          : "__TEXT,__cstring,cstring_literals"), -        1, true); +        CharUnits::One(), true);    return getConstantGEP(VMContext, Entry, 0, 0);  } @@ -4847,7 +5023,7 @@ llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {          llvm::ConstantDataArray::getString(VMContext, TypeStr),          ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals"                          : "__TEXT,__cstring,cstring_literals"), -        1, true); +        CharUnits::One(), true);    return getConstantGEP(VMContext, Entry, 0, 0);  } @@ -4866,7 +5042,7 @@ llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,          llvm::ConstantDataArray::getString(VMContext, TypeStr),          ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals"                          : "__TEXT,__cstring,cstring_literals"), -        1, true); +        CharUnits::One(), true);    return getConstantGEP(VMContext, Entry, 0, 0);  } @@ -4879,7 +5055,7 @@ llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {      Entry = CreateMetadataVar(          "OBJC_PROP_NAME_ATTR_",          llvm::ConstantDataArray::getString(VMContext, Ident->getName()), -        "__TEXT,__cstring,cstring_literals", 1, true); +        "__TEXT,__cstring,cstring_literals", CharUnits::One(), true);    return getConstantGEP(VMContext, Entry, 0, 0);  } @@ -5583,8 +5759,14 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(    std::string ClassName = ID->getObjCRuntimeNameAsString();    llvm::Constant *Values[10]; // 11 for 64bit targets! +  CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart); +  CharUnits endInstance = CharUnits::fromQuantity(InstanceSize); + +  bool hasMRCWeak = false;    if (CGM.getLangOpts().ObjCAutoRefCount)      flags |= NonFragileABI_Class_CompiledByARC; +  else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID))) +    flags |= NonFragileABI_Class_HasMRCWeakIvars;    Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);    Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart); @@ -5592,7 +5774,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(    // FIXME. For 64bit targets add 0 here.    Values[ 3] = (flags & NonFragileABI_Class_Meta)      ? GetIvarLayoutName(nullptr, ObjCTypes) -    : BuildIvarLayout(ID, true); +    : BuildStrongIvarLayout(ID, beginInstance, endInstance);    Values[ 4] = GetClassName(ID->getObjCRuntimeNameAsString());    // const struct _method_list_t * const baseMethods;    std::vector<llvm::Constant*> Methods; @@ -5639,7 +5821,8 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(      Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);    } else {      Values[ 7] = EmitIvarList(ID); -    Values[ 8] = BuildIvarLayout(ID, false); +    Values[ 8] = BuildWeakIvarLayout(ID, beginInstance, endInstance, +                                     hasMRCWeak);      Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),                                    ID, ID->getClassInterface(), ObjCTypes);    } @@ -5731,7 +5914,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {      // Make this entry NULL for any iOS device target, any iOS simulator target,      // OS X with deployment target 10.9 or later.      const llvm::Triple &Triple = CGM.getTarget().getTriple(); -    if (Triple.isiOS() || (Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 9))) +    if (Triple.isiOS() || Triple.isWatchOS() || +        (Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 9)))        // This entry will be null.        ObjCEmptyVtableVar = nullptr;      else @@ -5887,9 +6071,11 @@ llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,    std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");    ProtocolName += PD->getObjCRuntimeNameAsString(); +  CharUnits Align = CGF.getPointerAlign(); +    llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);    if (PTGV) -    return CGF.Builder.CreateLoad(PTGV); +    return CGF.Builder.CreateAlignedLoad(PTGV, Align);    PTGV = new llvm::GlobalVariable(      CGM.getModule(),      Init->getType(), false, @@ -5898,8 +6084,9 @@ llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,      ProtocolName);    PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");    PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); +  PTGV->setAlignment(Align.getQuantity());    CGM.addCompilerUsedGlobal(PTGV); -  return CGF.Builder.CreateLoad(PTGV); +  return CGF.Builder.CreateAlignedLoad(PTGV, Align);  }  /// GenerateCategory - Build metadata for a category implementation. @@ -6428,7 +6615,8 @@ llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(    const ObjCInterfaceDecl *Interface,    const ObjCIvarDecl *Ivar) {    llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar); -  IvarOffsetValue = CGF.Builder.CreateLoad(IvarOffsetValue, "ivar"); +  IvarOffsetValue = CGF.Builder.CreateAlignedLoad(IvarOffsetValue, +                                                  CGF.getSizeAlign(), "ivar");    if (IsIvarOffsetKnownIdempotent(CGF, Ivar))      cast<llvm::LoadInst>(IvarOffsetValue)          ->setMetadata(CGM.getModule().getMDKindID("invariant.load"), @@ -6559,16 +6747,17 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,        }      } -  llvm::Value *mref = -    CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy); +  Address mref = +    Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy), +            CGF.getPointerAlign());    // Update the message ref argument. -  args[1].RV = RValue::get(mref); +  args[1].RV = RValue::get(mref.getPointer());    // Load the function to call from the message ref table. -  llvm::Value *callee = -      CGF.Builder.CreateStructGEP(ObjCTypes.MessageRefTy, mref, 0); -  callee = CGF.Builder.CreateLoad(callee, "msgSend_fn"); +  Address calleeAddr = +      CGF.Builder.CreateStructGEP(mref, 0, CharUnits::Zero()); +  llvm::Value *callee = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn");    callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType); @@ -6594,7 +6783,7 @@ CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,      : EmitMessageSend(CGF, Return, ResultType,                        EmitSelector(CGF, Sel),                        Receiver, CGF.getContext().getObjCIdType(), -                      false, CallArgs, Method, ObjCTypes); +                      false, CallArgs, Method, Class, ObjCTypes);  }  llvm::GlobalVariable * @@ -6617,6 +6806,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,                                                          IdentifierInfo *II,                                                          bool Weak,                                                          const ObjCInterfaceDecl *ID) { +  CharUnits Align = CGF.getPointerAlign();    llvm::GlobalVariable *&Entry = ClassReferences[II];    if (!Entry) { @@ -6627,13 +6817,11 @@ llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,      Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,                                       false, llvm::GlobalValue::PrivateLinkage,                                       ClassGV, "OBJC_CLASSLIST_REFERENCES_$_"); -    Entry->setAlignment( -                        CGM.getDataLayout().getABITypeAlignment( -                                                                ObjCTypes.ClassnfABIPtrTy)); +    Entry->setAlignment(Align.getQuantity());      Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");      CGM.addCompilerUsedGlobal(Entry);    } -  return CGF.Builder.CreateLoad(Entry); +  return CGF.Builder.CreateAlignedLoad(Entry, Align);  }  llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF, @@ -6644,12 +6832,13 @@ llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,  llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(                                                      CodeGenFunction &CGF) {    IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool"); -  return EmitClassRefFromId(CGF, II, false, 0); +  return EmitClassRefFromId(CGF, II, false, nullptr);  }  llvm::Value *  CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,                                            const ObjCInterfaceDecl *ID) { +  CharUnits Align = CGF.getPointerAlign();    llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];    if (!Entry) { @@ -6660,13 +6849,11 @@ CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,      Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,                                       false, llvm::GlobalValue::PrivateLinkage,                                       ClassGV, "OBJC_CLASSLIST_SUP_REFS_$_"); -    Entry->setAlignment( -      CGM.getDataLayout().getABITypeAlignment( -        ObjCTypes.ClassnfABIPtrTy)); +    Entry->setAlignment(Align.getQuantity());      Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");      CGM.addCompilerUsedGlobal(Entry);    } -  return CGF.Builder.CreateLoad(Entry); +  return CGF.Builder.CreateAlignedLoad(Entry, Align);  }  /// EmitMetaClassRef - Return a Value * of the address of _class_t @@ -6675,6 +6862,7 @@ CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,  llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,                                                        const ObjCInterfaceDecl *ID,                                                        bool Weak) { +  CharUnits Align = CGF.getPointerAlign();    llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];    if (!Entry) {      llvm::SmallString<64> MetaClassName(getMetaclassSymbolPrefix()); @@ -6685,14 +6873,13 @@ llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,      Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,                                       false, llvm::GlobalValue::PrivateLinkage,                                       MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_"); -    Entry->setAlignment( -        CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABIPtrTy)); +    Entry->setAlignment(Align.getQuantity());      Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");      CGM.addCompilerUsedGlobal(Entry);    } -  return CGF.Builder.CreateLoad(Entry); +  return CGF.Builder.CreateAlignedLoad(Entry, Align);  }  /// GetClass - Return a reference to the class for the given interface @@ -6727,14 +6914,15 @@ 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.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super"); +  Address ObjCSuper = +    CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(), +                         "objc_super");    llvm::Value *ReceiverAsObject =      CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);    CGF.Builder.CreateStore(        ReceiverAsObject, -      CGF.Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 0)); +      CGF.Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero()));    // If this is a class message the metaclass is passed as the target.    llvm::Value *Target; @@ -6749,22 +6937,33 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,      CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());    Target = CGF.Builder.CreateBitCast(Target, ClassTy);    CGF.Builder.CreateStore( -      Target, CGF.Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 1)); +      Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1, CGF.getPointerSize()));    return (isVTableDispatchedSelector(Sel))      ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, -                            ObjCSuper, ObjCTypes.SuperPtrCTy, +                            ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,                              true, CallArgs, Method)      : EmitMessageSend(CGF, Return, ResultType,                        EmitSelector(CGF, Sel), -                      ObjCSuper, ObjCTypes.SuperPtrCTy, -                      true, CallArgs, Method, ObjCTypes); +                      ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy, +                      true, CallArgs, Method, Class, ObjCTypes);  }  llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF, -                                                  Selector Sel, bool lval) { +                                                  Selector Sel) { +  Address Addr = EmitSelectorAddr(CGF, Sel); + +  llvm::LoadInst* LI = CGF.Builder.CreateLoad(Addr); +  LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),  +                  llvm::MDNode::get(VMContext, None)); +  return LI; +} + +Address CGObjCNonFragileABIMac::EmitSelectorAddr(CodeGenFunction &CGF, +                                                 Selector Sel) {    llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; +  CharUnits Align = CGF.getPointerAlign();    if (!Entry) {      llvm::Constant *Casted =        llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), @@ -6774,23 +6973,19 @@ llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,                                       Casted, "OBJC_SELECTOR_REFERENCES_");      Entry->setExternallyInitialized(true);      Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip"); +    Entry->setAlignment(Align.getQuantity());      CGM.addCompilerUsedGlobal(Entry);    } -  if (lval) -    return Entry; -  llvm::LoadInst* LI = CGF.Builder.CreateLoad(Entry); -   -  LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),  -                  llvm::MDNode::get(VMContext, None)); -  return LI; +  return Address(Entry, Align);  } +  /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.  /// objc_assign_ivar (id src, id *dst, ptrdiff_t)  ///  void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,                                                  llvm::Value *src, -                                                llvm::Value *dst, +                                                Address dst,                                                  llvm::Value *ivarOffset) {    llvm::Type * SrcTy = src->getType();    if (!isa<llvm::PointerType>(SrcTy)) { @@ -6802,7 +6997,7 @@ void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,    }    src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);    dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); -  llvm::Value *args[] = { src, dst, ivarOffset }; +  llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);  } @@ -6811,7 +7006,7 @@ void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,  ///  void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(    CodeGen::CodeGenFunction &CGF, -  llvm::Value *src, llvm::Value *dst) { +  llvm::Value *src, Address dst) {    llvm::Type * SrcTy = src->getType();    if (!isa<llvm::PointerType>(SrcTy)) {      unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy); @@ -6822,19 +7017,19 @@ void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(    }    src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);    dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); -  llvm::Value *args[] = { src, dst }; +  llvm::Value *args[] = { src, dst.getPointer() };    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),                                args, "weakassign");  }  void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(    CodeGen::CodeGenFunction &CGF, -  llvm::Value *DestPtr, -  llvm::Value *SrcPtr, +  Address DestPtr, +  Address SrcPtr,    llvm::Value *Size) {    SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);    DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); -  llvm::Value *args[] = { DestPtr, SrcPtr, Size }; +  llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size };    CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);  } @@ -6843,13 +7038,12 @@ void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(  ///  llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(    CodeGen::CodeGenFunction &CGF, -  llvm::Value *AddrWeakObj) { -  llvm::Type* DestTy = -    cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); +  Address AddrWeakObj) { +  llvm::Type *DestTy = AddrWeakObj.getElementType();    AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);    llvm::Value *read_weak =      CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(), -                                AddrWeakObj, "weakread"); +                                AddrWeakObj.getPointer(), "weakread");    read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);    return read_weak;  } @@ -6858,7 +7052,7 @@ llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(  /// objc_assign_weak (id src, id *dst)  ///  void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, -                                                llvm::Value *src, llvm::Value *dst) { +                                                llvm::Value *src, Address dst) {    llvm::Type * SrcTy = src->getType();    if (!isa<llvm::PointerType>(SrcTy)) {      unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy); @@ -6869,7 +7063,7 @@ void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,    }    src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);    dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); -  llvm::Value *args[] = { src, dst }; +  llvm::Value *args[] = { src, dst.getPointer() };    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),                                args, "weakassign");  } @@ -6878,7 +7072,7 @@ void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,  /// objc_assign_global (id src, id *dst)  ///  void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, -                                          llvm::Value *src, llvm::Value *dst, +                                          llvm::Value *src, Address dst,                                            bool threadlocal) {    llvm::Type * SrcTy = src->getType();    if (!isa<llvm::PointerType>(SrcTy)) { @@ -6890,7 +7084,7 @@ void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,    }    src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);    dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); -  llvm::Value *args[] = { src, dst }; +  llvm::Value *args[] = { src, dst.getPointer() };    if (!threadlocal)      CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),                                  args, "globalassign"); @@ -7043,6 +7237,7 @@ CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {    case ObjCRuntime::MacOSX:    case ObjCRuntime::iOS: +  case ObjCRuntime::WatchOS:      return new CGObjCNonFragileABIMac(CGM);    case ObjCRuntime::GNUstep: | 
