brintos

brintos / llvm-project-archived public Read only

0
0
Text · 295.2 KiB · cb5bb40 Raw
7774 lines · cpp
1//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This provides Objective-C code generation targeting the Apple runtime.10//11//===----------------------------------------------------------------------===//12 13#include "CGBlocks.h"14#include "CGCleanup.h"15#include "CGObjCRuntime.h"16#include "CGRecordLayout.h"17#include "CodeGenFunction.h"18#include "CodeGenModule.h"19#include "clang/AST/ASTContext.h"20#include "clang/AST/Attr.h"21#include "clang/AST/Decl.h"22#include "clang/AST/DeclObjC.h"23#include "clang/AST/Mangle.h"24#include "clang/AST/RecordLayout.h"25#include "clang/AST/StmtObjC.h"26#include "clang/Basic/CodeGenOptions.h"27#include "clang/Basic/LangOptions.h"28#include "clang/CodeGen/ConstantInitBuilder.h"29#include "llvm/ADT/CachedHashString.h"30#include "llvm/ADT/DenseSet.h"31#include "llvm/ADT/SetVector.h"32#include "llvm/ADT/SmallPtrSet.h"33#include "llvm/ADT/SmallString.h"34#include "llvm/IR/DataLayout.h"35#include "llvm/IR/InlineAsm.h"36#include "llvm/IR/IntrinsicInst.h"37#include "llvm/IR/LLVMContext.h"38#include "llvm/IR/Module.h"39#include "llvm/Support/ScopedPrinter.h"40#include "llvm/Support/raw_ostream.h"41#include <cstdio>42 43using namespace clang;44using namespace CodeGen;45 46namespace {47 48// FIXME: We should find a nicer way to make the labels for metadata, string49// concatenation is lame.50 51class ObjCCommonTypesHelper {52protected:53  llvm::LLVMContext &VMContext;54 55private:56  // The types of these functions don't really matter because we57  // should always bitcast before calling them.58 59  /// id objc_msgSend (id, SEL, ...)60  ///61  /// The default messenger, used for sends whose ABI is unchanged from62  /// the all-integer/pointer case.63  llvm::FunctionCallee getMessageSendFn() const {64    // Add the non-lazy-bind attribute, since objc_msgSend is likely to65    // be called a lot.66    llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};67    return CGM.CreateRuntimeFunction(68        llvm::FunctionType::get(ObjectPtrTy, params, true), "objc_msgSend",69        llvm::AttributeList::get(CGM.getLLVMContext(),70                                 llvm::AttributeList::FunctionIndex,71                                 llvm::Attribute::NonLazyBind));72  }73 74  /// void objc_msgSend_stret (id, SEL, ...)75  ///76  /// The messenger used when the return value is an aggregate returned77  /// by indirect reference in the first argument, and therefore the78  /// self and selector parameters are shifted over by one.79  llvm::FunctionCallee getMessageSendStretFn() const {80    llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};81    return CGM.CreateRuntimeFunction(82        llvm::FunctionType::get(CGM.VoidTy, params, true),83        "objc_msgSend_stret");84  }85 86  /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)87  ///88  /// The messenger used when the return value is returned on the x8789  /// floating-point stack; without a special entrypoint, the nil case90  /// would be unbalanced.91  llvm::FunctionCallee getMessageSendFpretFn() const {92    llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};93    return CGM.CreateRuntimeFunction(94        llvm::FunctionType::get(CGM.DoubleTy, params, true),95        "objc_msgSend_fpret");96  }97 98  /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)99  ///100  /// The messenger used when the return value is returned in two values on the101  /// x87 floating point stack; without a special entrypoint, the nil case102  /// would be unbalanced. Only used on 64-bit X86.103  llvm::FunctionCallee getMessageSendFp2retFn() const {104    llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};105    llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);106    llvm::Type *resultType =107        llvm::StructType::get(longDoubleType, longDoubleType);108 109    return CGM.CreateRuntimeFunction(110        llvm::FunctionType::get(resultType, params, true),111        "objc_msgSend_fp2ret");112  }113 114  /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)115  ///116  /// The messenger used for super calls, which have different dispatch117  /// semantics.  The class passed is the superclass of the current118  /// class.119  llvm::FunctionCallee getMessageSendSuperFn() const {120    llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};121    return CGM.CreateRuntimeFunction(122        llvm::FunctionType::get(ObjectPtrTy, params, true),123        "objc_msgSendSuper");124  }125 126  /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)127  ///128  /// A slightly different messenger used for super calls.  The class129  /// passed is the current class.130  llvm::FunctionCallee getMessageSendSuperFn2() const {131    llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};132    return CGM.CreateRuntimeFunction(133        llvm::FunctionType::get(ObjectPtrTy, params, true),134        "objc_msgSendSuper2");135  }136 137  /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,138  ///                              SEL op, ...)139  ///140  /// The messenger used for super calls which return an aggregate indirectly.141  llvm::FunctionCallee getMessageSendSuperStretFn() const {142    llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};143    return CGM.CreateRuntimeFunction(144        llvm::FunctionType::get(CGM.VoidTy, params, true),145        "objc_msgSendSuper_stret");146  }147 148  /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,149  ///                               SEL op, ...)150  ///151  /// objc_msgSendSuper_stret with the super2 semantics.152  llvm::FunctionCallee getMessageSendSuperStretFn2() const {153    llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};154    return CGM.CreateRuntimeFunction(155        llvm::FunctionType::get(CGM.VoidTy, params, true),156        "objc_msgSendSuper2_stret");157  }158 159  llvm::FunctionCallee getMessageSendSuperFpretFn() const {160    // There is no objc_msgSendSuper_fpret? How can that work?161    return getMessageSendSuperFn();162  }163 164  llvm::FunctionCallee getMessageSendSuperFpretFn2() const {165    // There is no objc_msgSendSuper_fpret? How can that work?166    return getMessageSendSuperFn2();167  }168 169protected:170  CodeGen::CodeGenModule &CGM;171 172public:173  llvm::IntegerType *ShortTy, *IntTy, *LongTy;174  llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;175  llvm::PointerType *Int8PtrProgramASTy;176  llvm::Type *IvarOffsetVarTy;177 178  /// ObjectPtrTy - LLVM type for object handles (typeof(id))179  llvm::PointerType *ObjectPtrTy;180 181  /// PtrObjectPtrTy - LLVM type for id *182  llvm::PointerType *PtrObjectPtrTy;183 184  /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))185  llvm::PointerType *SelectorPtrTy;186 187  // SuperCTy - clang type for struct objc_super.188  QualType SuperCTy;189  // SuperPtrCTy - clang type for struct objc_super *.190  QualType SuperPtrCTy;191 192  /// SuperTy - LLVM type for struct objc_super.193  llvm::StructType *SuperTy;194  /// SuperPtrTy - LLVM type for struct objc_super *.195  llvm::PointerType *SuperPtrTy;196 197  /// PropertyTy - LLVM type for struct objc_property (struct _prop_t198  /// in GCC parlance).199  llvm::StructType *PropertyTy;200 201  /// PropertyListTy - LLVM type for struct objc_property_list202  /// (_prop_list_t in GCC parlance).203  llvm::StructType *PropertyListTy;204  /// PropertyListPtrTy - LLVM type for struct objc_property_list*.205  llvm::PointerType *PropertyListPtrTy;206 207  // MethodTy - LLVM type for struct objc_method.208  llvm::StructType *MethodTy;209 210  /// CacheTy - LLVM type for struct objc_cache.211  llvm::Type *CacheTy;212  /// CachePtrTy - LLVM type for struct objc_cache *.213  llvm::PointerType *CachePtrTy;214 215  llvm::FunctionCallee getGetPropertyFn() {216    CodeGen::CodeGenTypes &Types = CGM.getTypes();217    ASTContext &Ctx = CGM.getContext();218    // id objc_getProperty (id, SEL, ptrdiff_t, bool)219    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());220    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());221    CanQualType Params[] = {222        IdType, SelType,223        Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(), Ctx.BoolTy};224    llvm::FunctionType *FTy = Types.GetFunctionType(225        Types.arrangeBuiltinFunctionDeclaration(IdType, Params));226    return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");227  }228 229  llvm::FunctionCallee getSetPropertyFn() {230    CodeGen::CodeGenTypes &Types = CGM.getTypes();231    ASTContext &Ctx = CGM.getContext();232    // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)233    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());234    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());235    CanQualType Params[] = {236        IdType,237        SelType,238        Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(),239        IdType,240        Ctx.BoolTy,241        Ctx.BoolTy};242    llvm::FunctionType *FTy = Types.GetFunctionType(243        Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));244    return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");245  }246 247  llvm::FunctionCallee getOptimizedSetPropertyFn(bool atomic, bool copy) {248    CodeGen::CodeGenTypes &Types = CGM.getTypes();249    ASTContext &Ctx = CGM.getContext();250    // void objc_setProperty_atomic(id self, SEL _cmd,251    //                              id newValue, ptrdiff_t offset);252    // void objc_setProperty_nonatomic(id self, SEL _cmd,253    //                                 id newValue, ptrdiff_t offset);254    // void objc_setProperty_atomic_copy(id self, SEL _cmd,255    //                                   id newValue, ptrdiff_t offset);256    // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,257    //                                      id newValue, ptrdiff_t offset);258 259    SmallVector<CanQualType, 4> Params;260    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());261    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());262    Params.push_back(IdType);263    Params.push_back(SelType);264    Params.push_back(IdType);265    Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());266    llvm::FunctionType *FTy = Types.GetFunctionType(267        Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));268    const char *name;269    if (atomic && copy)270      name = "objc_setProperty_atomic_copy";271    else if (atomic && !copy)272      name = "objc_setProperty_atomic";273    else if (!atomic && copy)274      name = "objc_setProperty_nonatomic_copy";275    else276      name = "objc_setProperty_nonatomic";277 278    return CGM.CreateRuntimeFunction(FTy, name);279  }280 281  llvm::FunctionCallee getCopyStructFn() {282    CodeGen::CodeGenTypes &Types = CGM.getTypes();283    ASTContext &Ctx = CGM.getContext();284    // void objc_copyStruct (void *, const void *, size_t, bool, bool)285    SmallVector<CanQualType, 5> Params;286    Params.push_back(Ctx.VoidPtrTy);287    Params.push_back(Ctx.VoidPtrTy);288    Params.push_back(Ctx.getCanonicalSizeType());289    Params.push_back(Ctx.BoolTy);290    Params.push_back(Ctx.BoolTy);291    llvm::FunctionType *FTy = Types.GetFunctionType(292        Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));293    return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");294  }295 296  /// This routine declares and returns address of:297  /// void objc_copyCppObjectAtomic(298  ///         void *dest, const void *src,299  ///         void (*copyHelper) (void *dest, const void *source));300  llvm::FunctionCallee getCppAtomicObjectFunction() {301    CodeGen::CodeGenTypes &Types = CGM.getTypes();302    ASTContext &Ctx = CGM.getContext();303    /// void objc_copyCppObjectAtomic(void *dest, const void *src, void304    /// *helper);305    SmallVector<CanQualType, 3> Params;306    Params.push_back(Ctx.VoidPtrTy);307    Params.push_back(Ctx.VoidPtrTy);308    Params.push_back(Ctx.VoidPtrTy);309    llvm::FunctionType *FTy = Types.GetFunctionType(310        Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));311    return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");312  }313 314  llvm::FunctionCallee getEnumerationMutationFn() {315    CodeGen::CodeGenTypes &Types = CGM.getTypes();316    ASTContext &Ctx = CGM.getContext();317    // void objc_enumerationMutation (id)318    SmallVector<CanQualType, 1> Params;319    Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));320    llvm::FunctionType *FTy = Types.GetFunctionType(321        Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));322    return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");323  }324 325  llvm::FunctionCallee getLookUpClassFn() {326    CodeGen::CodeGenTypes &Types = CGM.getTypes();327    ASTContext &Ctx = CGM.getContext();328    // Class objc_lookUpClass (const char *)329    SmallVector<CanQualType, 1> Params;330    Params.push_back(331        Ctx.getCanonicalType(Ctx.getPointerType(Ctx.CharTy.withConst())));332    llvm::FunctionType *FTy =333        Types.GetFunctionType(Types.arrangeBuiltinFunctionDeclaration(334            Ctx.getCanonicalType(Ctx.getObjCClassType()), Params));335    return CGM.CreateRuntimeFunction(FTy, "objc_lookUpClass");336  }337 338  /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.339  llvm::FunctionCallee getGcReadWeakFn() {340    // id objc_read_weak (id *)341    llvm::Type *args[] = {CGM.DefaultPtrTy};342    llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args, false);343    return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");344  }345 346  /// GcAssignWeakFn -- LLVM objc_assign_weak function.347  llvm::FunctionCallee getGcAssignWeakFn() {348    // id objc_assign_weak (id, id *)349    llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};350    llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args, false);351    return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");352  }353 354  /// GcAssignGlobalFn -- LLVM objc_assign_global function.355  llvm::FunctionCallee getGcAssignGlobalFn() {356    // id objc_assign_global(id, id *)357    llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};358    llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args, false);359    return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");360  }361 362  /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.363  llvm::FunctionCallee getGcAssignThreadLocalFn() {364    // id objc_assign_threadlocal(id src, id * dest)365    llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};366    llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args, false);367    return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");368  }369 370  /// GcAssignIvarFn -- LLVM objc_assign_ivar function.371  llvm::FunctionCallee getGcAssignIvarFn() {372    // id objc_assign_ivar(id, id *, ptrdiff_t)373    llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy, CGM.PtrDiffTy};374    llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args, false);375    return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");376  }377 378  /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.379  llvm::FunctionCallee GcMemmoveCollectableFn() {380    // void *objc_memmove_collectable(void *dst, const void *src, size_t size)381    llvm::Type *args[] = {Int8PtrTy, Int8PtrTy, LongTy};382    llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);383    return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");384  }385 386  /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.387  llvm::FunctionCallee getGcAssignStrongCastFn() {388    // id objc_assign_strongCast(id, id *)389    llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};390    llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args, false);391    return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");392  }393 394  /// ExceptionThrowFn - LLVM objc_exception_throw function.395  llvm::FunctionCallee getExceptionThrowFn() {396    // void objc_exception_throw(id)397    llvm::Type *args[] = {ObjectPtrTy};398    llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, args, false);399    return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");400  }401 402  /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.403  llvm::FunctionCallee getExceptionRethrowFn() {404    // void objc_exception_rethrow(void)405    llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);406    return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");407  }408 409  /// SyncEnterFn - LLVM object_sync_enter function.410  llvm::FunctionCallee getSyncEnterFn() {411    // int objc_sync_enter (id)412    llvm::Type *args[] = {ObjectPtrTy};413    llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.IntTy, args, false);414    return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");415  }416 417  /// SyncExitFn - LLVM object_sync_exit function.418  llvm::FunctionCallee getSyncExitFn() {419    // int objc_sync_exit (id)420    llvm::Type *args[] = {ObjectPtrTy};421    llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.IntTy, args, false);422    return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");423  }424 425  llvm::FunctionCallee getSendFn(bool IsSuper) const {426    return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();427  }428 429  llvm::FunctionCallee getSendFn2(bool IsSuper) const {430    return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();431  }432 433  llvm::FunctionCallee getSendStretFn(bool IsSuper) const {434    return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();435  }436 437  llvm::FunctionCallee getSendStretFn2(bool IsSuper) const {438    return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();439  }440 441  llvm::FunctionCallee getSendFpretFn(bool IsSuper) const {442    return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();443  }444 445  llvm::FunctionCallee getSendFpretFn2(bool IsSuper) const {446    return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();447  }448 449  llvm::FunctionCallee getSendFp2retFn(bool IsSuper) const {450    return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();451  }452 453  llvm::FunctionCallee getSendFp2RetFn2(bool IsSuper) const {454    return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();455  }456 457  ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);458};459 460/// ObjCTypesHelper - Helper class that encapsulates lazy461/// construction of varies types used during ObjC generation.462class ObjCTypesHelper : public ObjCCommonTypesHelper {463public:464  /// SymtabTy - LLVM type for struct objc_symtab.465  llvm::StructType *SymtabTy;466  /// SymtabPtrTy - LLVM type for struct objc_symtab *.467  llvm::PointerType *SymtabPtrTy;468  /// ModuleTy - LLVM type for struct objc_module.469  llvm::StructType *ModuleTy;470 471  /// ProtocolTy - LLVM type for struct objc_protocol.472  llvm::StructType *ProtocolTy;473  /// ProtocolPtrTy - LLVM type for struct objc_protocol *.474  llvm::PointerType *ProtocolPtrTy;475  /// ProtocolExtensionTy - LLVM type for struct476  /// objc_protocol_extension.477  llvm::StructType *ProtocolExtensionTy;478  /// ProtocolExtensionTy - LLVM type for struct479  /// objc_protocol_extension *.480  llvm::PointerType *ProtocolExtensionPtrTy;481  /// MethodDescriptionTy - LLVM type for struct482  /// objc_method_description.483  llvm::StructType *MethodDescriptionTy;484  /// MethodDescriptionListTy - LLVM type for struct485  /// objc_method_description_list.486  llvm::StructType *MethodDescriptionListTy;487  /// MethodDescriptionListPtrTy - LLVM type for struct488  /// objc_method_description_list *.489  llvm::PointerType *MethodDescriptionListPtrTy;490  /// ProtocolListTy - LLVM type for struct objc_property_list.491  llvm::StructType *ProtocolListTy;492  /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.493  llvm::PointerType *ProtocolListPtrTy;494  /// CategoryTy - LLVM type for struct objc_category.495  llvm::StructType *CategoryTy;496  /// ClassTy - LLVM type for struct objc_class.497  llvm::StructType *ClassTy;498  /// ClassPtrTy - LLVM type for struct objc_class *.499  llvm::PointerType *ClassPtrTy;500  /// ClassExtensionTy - LLVM type for struct objc_class_ext.501  llvm::StructType *ClassExtensionTy;502  /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.503  llvm::PointerType *ClassExtensionPtrTy;504  // IvarTy - LLVM type for struct objc_ivar.505  llvm::StructType *IvarTy;506  /// IvarListTy - LLVM type for struct objc_ivar_list.507  llvm::StructType *IvarListTy;508  /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.509  llvm::PointerType *IvarListPtrTy;510  /// MethodListTy - LLVM type for struct objc_method_list.511  llvm::StructType *MethodListTy;512  /// MethodListPtrTy - LLVM type for struct objc_method_list *.513  llvm::PointerType *MethodListPtrTy;514 515  /// ExceptionDataTy - LLVM type for struct _objc_exception_data.516  llvm::StructType *ExceptionDataTy;517 518  /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.519  llvm::FunctionCallee getExceptionTryEnterFn() {520    llvm::Type *params[] = {CGM.DefaultPtrTy};521    return CGM.CreateRuntimeFunction(522        llvm::FunctionType::get(CGM.VoidTy, params, false),523        "objc_exception_try_enter");524  }525 526  /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.527  llvm::FunctionCallee getExceptionTryExitFn() {528    llvm::Type *params[] = {CGM.DefaultPtrTy};529    return CGM.CreateRuntimeFunction(530        llvm::FunctionType::get(CGM.VoidTy, params, false),531        "objc_exception_try_exit");532  }533 534  /// ExceptionExtractFn - LLVM objc_exception_extract function.535  llvm::FunctionCallee getExceptionExtractFn() {536    llvm::Type *params[] = {CGM.DefaultPtrTy};537    return CGM.CreateRuntimeFunction(538        llvm::FunctionType::get(ObjectPtrTy, params, false),539        "objc_exception_extract");540  }541 542  /// ExceptionMatchFn - LLVM objc_exception_match function.543  llvm::FunctionCallee getExceptionMatchFn() {544    llvm::Type *params[] = {ClassPtrTy, ObjectPtrTy};545    return CGM.CreateRuntimeFunction(546        llvm::FunctionType::get(CGM.Int32Ty, params, false),547        "objc_exception_match");548  }549 550  /// SetJmpFn - LLVM _setjmp function.551  llvm::FunctionCallee getSetJmpFn() {552    // This is specifically the prototype for x86.553    llvm::Type *params[] = {CGM.DefaultPtrTy};554    return CGM.CreateRuntimeFunction(555        llvm::FunctionType::get(CGM.Int32Ty, params, false), "_setjmp",556        llvm::AttributeList::get(CGM.getLLVMContext(),557                                 llvm::AttributeList::FunctionIndex,558                                 llvm::Attribute::NonLazyBind));559  }560 561public:562  ObjCTypesHelper(CodeGen::CodeGenModule &cgm);563};564 565/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's566/// modern abi567class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {568public:569  // MethodListnfABITy - LLVM for struct _method_list_t570  llvm::StructType *MethodListnfABITy;571 572  // MethodListnfABIPtrTy - LLVM for struct _method_list_t*573  llvm::PointerType *MethodListnfABIPtrTy;574 575  // ProtocolnfABITy = LLVM for struct _protocol_t576  llvm::StructType *ProtocolnfABITy;577 578  // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*579  llvm::PointerType *ProtocolnfABIPtrTy;580 581  // ProtocolListnfABITy - LLVM for struct _objc_protocol_list582  llvm::StructType *ProtocolListnfABITy;583 584  // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*585  llvm::PointerType *ProtocolListnfABIPtrTy;586 587  // ClassnfABITy - LLVM for struct _class_t588  llvm::StructType *ClassnfABITy;589 590  // ClassnfABIPtrTy - LLVM for struct _class_t*591  llvm::PointerType *ClassnfABIPtrTy;592 593  // IvarnfABITy - LLVM for struct _ivar_t594  llvm::StructType *IvarnfABITy;595 596  // IvarListnfABITy - LLVM for struct _ivar_list_t597  llvm::StructType *IvarListnfABITy;598 599  // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*600  llvm::PointerType *IvarListnfABIPtrTy;601 602  // ClassRonfABITy - LLVM for struct _class_ro_t603  llvm::StructType *ClassRonfABITy;604 605  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)606  llvm::PointerType *ImpnfABITy;607 608  // CategorynfABITy - LLVM for struct _category_t609  llvm::StructType *CategorynfABITy;610 611  // New types for nonfragile abi messaging.612 613  // MessageRefTy - LLVM for:614  // struct _message_ref_t {615  //   IMP messenger;616  //   SEL name;617  // };618  llvm::StructType *MessageRefTy;619  // MessageRefCTy - clang type for struct _message_ref_t620  QualType MessageRefCTy;621 622  // MessageRefPtrTy - LLVM for struct _message_ref_t*623  llvm::Type *MessageRefPtrTy;624  // MessageRefCPtrTy - clang type for struct _message_ref_t*625  QualType MessageRefCPtrTy;626 627  // SuperMessageRefTy - LLVM for:628  // struct _super_message_ref_t {629  //   SUPER_IMP messenger;630  //   SEL name;631  // };632  llvm::StructType *SuperMessageRefTy;633 634  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*635  llvm::PointerType *SuperMessageRefPtrTy;636 637  llvm::FunctionCallee getMessageSendFixupFn() {638    // id objc_msgSend_fixup(id, struct message_ref_t*, ...)639    llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};640    return CGM.CreateRuntimeFunction(641        llvm::FunctionType::get(ObjectPtrTy, params, true),642        "objc_msgSend_fixup");643  }644 645  llvm::FunctionCallee getMessageSendFpretFixupFn() {646    // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)647    llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};648    return CGM.CreateRuntimeFunction(649        llvm::FunctionType::get(ObjectPtrTy, params, true),650        "objc_msgSend_fpret_fixup");651  }652 653  llvm::FunctionCallee getMessageSendStretFixupFn() {654    // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)655    llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};656    return CGM.CreateRuntimeFunction(657        llvm::FunctionType::get(ObjectPtrTy, params, true),658        "objc_msgSend_stret_fixup");659  }660 661  llvm::FunctionCallee getMessageSendSuper2FixupFn() {662    // id objc_msgSendSuper2_fixup (struct objc_super *,663    //                              struct _super_message_ref_t*, ...)664    llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};665    return CGM.CreateRuntimeFunction(666        llvm::FunctionType::get(ObjectPtrTy, params, true),667        "objc_msgSendSuper2_fixup");668  }669 670  llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {671    // id objc_msgSendSuper2_stret_fixup(struct objc_super *,672    //                                   struct _super_message_ref_t*, ...)673    llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};674    return CGM.CreateRuntimeFunction(675        llvm::FunctionType::get(ObjectPtrTy, params, true),676        "objc_msgSendSuper2_stret_fixup");677  }678 679  llvm::FunctionCallee getObjCEndCatchFn() {680    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),681                                     "objc_end_catch");682  }683 684  llvm::FunctionCallee getObjCBeginCatchFn() {685    llvm::Type *params[] = {Int8PtrTy};686    return CGM.CreateRuntimeFunction(687        llvm::FunctionType::get(Int8PtrTy, params, false), "objc_begin_catch");688  }689 690  /// Class objc_loadClassref (void *)691  ///692  /// Loads from a classref. For Objective-C stub classes, this invokes the693  /// initialization callback stored inside the stub. For all other classes694  /// this simply dereferences the pointer.695  llvm::FunctionCallee getLoadClassrefFn() const {696    // Add the non-lazy-bind attribute, since objc_loadClassref is likely to697    // be called a lot.698    //699    // Also it is safe to make it readnone, since we never load or store the700    // classref except by calling this function.701    llvm::Type *params[] = {Int8PtrPtrTy};702    llvm::LLVMContext &C = CGM.getLLVMContext();703    llvm::AttributeSet AS = llvm::AttributeSet::get(704        C, {705               llvm::Attribute::get(C, llvm::Attribute::NonLazyBind),706               llvm::Attribute::getWithMemoryEffects(707                   C, llvm::MemoryEffects::none()),708               llvm::Attribute::get(C, llvm::Attribute::NoUnwind),709           });710    llvm::FunctionCallee F = CGM.CreateRuntimeFunction(711        llvm::FunctionType::get(ClassnfABIPtrTy, params, false),712        "objc_loadClassref",713        llvm::AttributeList::get(CGM.getLLVMContext(),714                                 llvm::AttributeList::FunctionIndex, AS));715    if (!CGM.getTriple().isOSBinFormatCOFF())716      cast<llvm::Function>(F.getCallee())717          ->setLinkage(llvm::Function::ExternalWeakLinkage);718 719    return F;720  }721 722  llvm::StructType *EHTypeTy;723  llvm::Type *EHTypePtrTy;724 725  ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);726};727 728enum class ObjCLabelType {729  ClassName,730  MethodVarName,731  MethodVarType,732  PropertyName,733};734 735class CGObjCCommonMac : public CodeGen::CGObjCRuntime {736public:737  class SKIP_SCAN {738  public:739    unsigned skip;740    unsigned scan;741    SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)742        : skip(_skip), scan(_scan) {}743  };744 745  // clang-format off746  /// opcode for captured block variables layout 'instructions'.747  /// In the following descriptions, 'I' is the value of the immediate field.748  /// (field following the opcode).749  ///750  enum BLOCK_LAYOUT_OPCODE {751    /// An operator which affects how the following layout should be752    /// interpreted.753    ///   I == 0: Halt interpretation and treat everything else as754    ///           a non-pointer.  Note that this instruction is equal755    ///           to '\0'.756    ///   I != 0: Currently unused.757    BLOCK_LAYOUT_OPERATOR            = 0,758 759    /// The next I+1 bytes do not contain a value of object pointer type.760    /// Note that this can leave the stream unaligned, meaning that761    /// subsequent word-size instructions do not begin at a multiple of762    /// the pointer size.763    BLOCK_LAYOUT_NON_OBJECT_BYTES    = 1,764 765    /// The next I+1 words do not contain a value of object pointer type.766    /// This is simply an optimized version of BLOCK_LAYOUT_BYTES for767    /// when the required skip quantity is a multiple of the pointer size.768    BLOCK_LAYOUT_NON_OBJECT_WORDS    = 2,769 770    /// The next I+1 words are __strong pointers to Objective-C771    /// objects or blocks.772    BLOCK_LAYOUT_STRONG              = 3,773 774    /// The next I+1 words are pointers to __block variables.775    BLOCK_LAYOUT_BYREF               = 4,776 777    /// The next I+1 words are __weak pointers to Objective-C778    /// objects or blocks.779    BLOCK_LAYOUT_WEAK                = 5,780 781    /// The next I+1 words are __unsafe_unretained pointers to782    /// Objective-C objects or blocks.783    BLOCK_LAYOUT_UNRETAINED          = 6784 785    /// The next I+1 words are block or object pointers with some786    /// as-yet-unspecified ownership semantics.  If we add more787    /// flavors of ownership semantics, values will be taken from788    /// this range.789    ///790    /// This is included so that older tools can at least continue791    /// processing the layout past such things.792    // BLOCK_LAYOUT_OWNERSHIP_UNKNOWN = 7..10,793 794    /// All other opcodes are reserved.  Halt interpretation and795    /// treat everything else as opaque.796  };797  // clang-format on798 799  class RUN_SKIP {800  public:801    enum BLOCK_LAYOUT_OPCODE opcode;802    CharUnits block_var_bytepos;803    CharUnits block_var_size;804    RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,805             CharUnits BytePos = CharUnits::Zero(),806             CharUnits Size = CharUnits::Zero())807        : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}808 809    // Allow sorting based on byte pos.810    bool operator<(const RUN_SKIP &b) const {811      return block_var_bytepos < b.block_var_bytepos;812    }813  };814 815protected:816  llvm::LLVMContext &VMContext;817  // FIXME! May not be needing this after all.818  unsigned ObjCABI;819 820  // arc/mrr layout of captured block literal variables.821  SmallVector<RUN_SKIP, 16> RunSkipBlockVars;822 823  /// LazySymbols - Symbols to generate a lazy reference for. See824  /// DefinedSymbols and FinishModule().825  llvm::SetVector<IdentifierInfo *> LazySymbols;826 827  /// DefinedSymbols - External symbols which are defined by this828  /// module. The symbols in this list and LazySymbols are used to add829  /// special linker symbols which ensure that Objective-C modules are830  /// linked properly.831  llvm::SetVector<IdentifierInfo *> DefinedSymbols;832 833  /// ClassNames - uniqued class names.834  llvm::StringMap<llvm::GlobalVariable *> ClassNames;835 836  /// MethodVarNames - uniqued method variable names.837  llvm::DenseMap<Selector, llvm::GlobalVariable *> MethodVarNames;838 839  /// DefinedCategoryNames - list of category names in form Class_Category.840  llvm::SmallSetVector<llvm::CachedHashString, 16> DefinedCategoryNames;841 842  /// MethodVarTypes - uniqued method type signatures. We have to use843  /// a StringMap here because have no other unique reference.844  llvm::StringMap<llvm::GlobalVariable *> MethodVarTypes;845 846  /// MethodDefinitions - map of methods which have been defined in847  /// this translation unit.848  llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *> MethodDefinitions;849 850  /// DirectMethodDefinitions - map of direct methods which have been defined in851  /// this translation unit.852  llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *>853      DirectMethodDefinitions;854 855  /// PropertyNames - uniqued method variable names.856  llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> PropertyNames;857 858  /// ClassReferences - uniqued class references.859  llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> ClassReferences;860 861  /// SelectorReferences - uniqued selector references.862  llvm::DenseMap<Selector, llvm::GlobalVariable *> SelectorReferences;863 864  /// Protocols - Protocols for which an objc_protocol structure has865  /// been emitted. Forward declarations are handled by creating an866  /// empty structure whose initializer is filled in when/if defined.867  llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> Protocols;868 869  /// DefinedProtocols - Protocols which have actually been870  /// defined. We should not need this, see FIXME in GenerateProtocol.871  llvm::DenseSet<IdentifierInfo *> DefinedProtocols;872 873  /// DefinedClasses - List of defined classes.874  SmallVector<llvm::GlobalValue *, 16> DefinedClasses;875 876  /// ImplementedClasses - List of @implemented classes.877  SmallVector<const ObjCInterfaceDecl *, 16> ImplementedClasses;878 879  /// DefinedNonLazyClasses - List of defined "non-lazy" classes.880  SmallVector<llvm::GlobalValue *, 16> DefinedNonLazyClasses;881 882  /// DefinedCategories - List of defined categories.883  SmallVector<llvm::GlobalValue *, 16> DefinedCategories;884 885  /// DefinedStubCategories - List of defined categories on class stubs.886  SmallVector<llvm::GlobalValue *, 16> DefinedStubCategories;887 888  /// DefinedNonLazyCategories - List of defined "non-lazy" categories.889  SmallVector<llvm::GlobalValue *, 16> DefinedNonLazyCategories;890 891  /// Cached reference to the class for constant strings. This value has type892  /// int * but is actually an Obj-C class pointer.893  llvm::WeakTrackingVH ConstantStringClassRef;894 895  /// The LLVM type corresponding to NSConstantString.896  llvm::StructType *NSConstantStringType = nullptr;897 898  llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;899 900  /// GetMethodVarName - Return a unique constant for the given901  /// selector's name. The return value has type char *.902  llvm::Constant *GetMethodVarName(Selector Sel);903  llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);904 905  /// GetMethodVarType - Return a unique constant for the given906  /// method's type encoding string. The return value has type char *.907 908  // FIXME: This is a horrible name.909  llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D,910                                   bool Extended = false);911  llvm::Constant *GetMethodVarType(const FieldDecl *D);912 913  /// GetPropertyName - Return a unique constant for the given914  /// name. The return value has type char *.915  llvm::Constant *GetPropertyName(IdentifierInfo *Ident);916 917  // FIXME: This can be dropped once string functions are unified.918  llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,919                                        const Decl *Container);920 921  /// GetClassName - Return a unique constant for the given selector's922  /// runtime name (which may change via use of objc_runtime_name attribute on923  /// class or protocol definition. The return value has type char *.924  llvm::Constant *GetClassName(StringRef RuntimeName);925 926  llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);927 928  /// BuildIvarLayout - Builds ivar layout bitmap for the class929  /// implementation for the __strong or __weak case.930  ///931  /// \param hasMRCWeakIvars - Whether we are compiling in MRC and there932  ///   are any weak ivars defined directly in the class.  Meaningless unless933  ///   building a weak layout.  Does not guarantee that the layout will934  ///   actually have any entries, because the ivar might be under-aligned.935  llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,936                                  CharUnits beginOffset, CharUnits endOffset,937                                  bool forStrongLayout, bool hasMRCWeakIvars);938 939  llvm::Constant *BuildStrongIvarLayout(const ObjCImplementationDecl *OI,940                                        CharUnits beginOffset,941                                        CharUnits endOffset) {942    return BuildIvarLayout(OI, beginOffset, endOffset, true, false);943  }944 945  llvm::Constant *BuildWeakIvarLayout(const ObjCImplementationDecl *OI,946                                      CharUnits beginOffset,947                                      CharUnits endOffset,948                                      bool hasMRCWeakIvars) {949    return BuildIvarLayout(OI, beginOffset, endOffset, false, hasMRCWeakIvars);950  }951 952  Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT,953                                                   bool ByrefLayout);954 955  void UpdateRunSkipBlockVars(bool IsByref, Qualifiers::ObjCLifetime LifeTime,956                              CharUnits FieldOffset, CharUnits FieldSize);957 958  void BuildRCBlockVarRecordLayout(const RecordType *RT, CharUnits BytePos,959                                   bool &HasUnion, bool ByrefLayout = false);960 961  void BuildRCRecordLayout(const llvm::StructLayout *RecLayout,962                           const RecordDecl *RD,963                           ArrayRef<const FieldDecl *> RecFields,964                           CharUnits BytePos, bool &HasUnion, bool ByrefLayout);965 966  uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);967 968  llvm::Constant *getBitmapBlockLayout(bool ComputeByrefLayout);969 970  /// GetIvarLayoutName - Returns a unique constant for the given971  /// ivar layout bitmap.972  llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,973                                    const ObjCCommonTypesHelper &ObjCTypes);974 975  /// EmitPropertyList - Emit the given property list. The return976  /// value has type PropertyListPtrTy.977  llvm::Constant *EmitPropertyList(Twine Name, const Decl *Container,978                                   const ObjCContainerDecl *OCD,979                                   const ObjCCommonTypesHelper &ObjCTypes,980                                   bool IsClassProperty);981 982  /// EmitProtocolMethodTypes - Generate the array of extended method type983  /// strings. The return value has type Int8PtrPtrTy.984  llvm::Constant *985  EmitProtocolMethodTypes(Twine Name, ArrayRef<llvm::Constant *> MethodTypes,986                          const ObjCCommonTypesHelper &ObjCTypes);987 988  /// GetProtocolRef - Return a reference to the internal protocol989  /// description, creating an empty one if it has not been990  /// defined. The return value has type ProtocolPtrTy.991  llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);992 993  /// Return a reference to the given Class using runtime calls rather than994  /// by a symbol reference.995  llvm::Value *EmitClassRefViaRuntime(CodeGenFunction &CGF,996                                      const ObjCInterfaceDecl *ID,997                                      ObjCCommonTypesHelper &ObjCTypes);998 999  std::string GetSectionName(StringRef Section, StringRef MachOAttributes);1000 1001public:1002  /// CreateMetadataVar - Create a global variable with internal1003  /// linkage for use by the Objective-C runtime.1004  ///1005  /// This is a convenience wrapper which not only creates the1006  /// variable, but also sets the section and alignment and adds the1007  /// global to the "llvm.used" list.1008  ///1009  /// \param Name - The variable name.1010  /// \param Init - The variable initializer; this is also used to1011  ///   define the type of the variable.1012  /// \param Section - The section the variable should go into, or empty.1013  /// \param Align - The alignment for the variable, or 0.1014  /// \param AddToUsed - Whether the variable should be added to1015  ///   "llvm.used".1016  llvm::GlobalVariable *CreateMetadataVar(Twine Name,1017                                          ConstantStructBuilder &Init,1018                                          StringRef Section, CharUnits Align,1019                                          bool AddToUsed);1020  llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *Init,1021                                          StringRef Section, CharUnits Align,1022                                          bool AddToUsed);1023 1024  llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,1025                                             ObjCLabelType LabelType,1026                                             bool ForceNonFragileABI = false,1027                                             bool NullTerminate = true);1028 1029protected:1030  CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,1031                                  ReturnValueSlot Return, QualType ResultType,1032                                  Selector Sel, llvm::Value *Arg0,1033                                  QualType Arg0Ty, bool IsSuper,1034                                  const CallArgList &CallArgs,1035                                  const ObjCMethodDecl *OMD,1036                                  const ObjCInterfaceDecl *ClassReceiver,1037                                  const ObjCCommonTypesHelper &ObjCTypes);1038 1039  /// EmitImageInfo - Emit the image info marker used to encode some module1040  /// level information.1041  void EmitImageInfo();1042 1043public:1044  CGObjCCommonMac(CodeGen::CodeGenModule &cgm)1045      : CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) {}1046 1047  bool isNonFragileABI() const { return ObjCABI == 2; }1048 1049  ConstantAddress GenerateConstantString(const StringLiteral *SL) override;1050  ConstantAddress GenerateConstantNSString(const StringLiteral *SL);1051 1052  llvm::Function *1053  GenerateMethod(const ObjCMethodDecl *OMD,1054                 const ObjCContainerDecl *CD = nullptr) override;1055 1056  llvm::Function *GenerateDirectMethod(const ObjCMethodDecl *OMD,1057                                       const ObjCContainerDecl *CD);1058 1059  void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn,1060                                    const ObjCMethodDecl *OMD,1061                                    const ObjCContainerDecl *CD) override;1062 1063  void GenerateProtocol(const ObjCProtocolDecl *PD) override;1064 1065  /// GetOrEmitProtocolRef - Get a forward reference to the protocol1066  /// object for the given declaration, emitting it if needed. These1067  /// forward references will be filled in with empty bodies if no1068  /// definition is seen. The return value has type ProtocolPtrTy.1069  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) = 0;1070 1071  virtual llvm::Constant *getNSConstantStringClassRef() = 0;1072 1073  llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,1074                                     const CGBlockInfo &blockInfo) override;1075  llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,1076                                     const CGBlockInfo &blockInfo) override;1077  std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM,1078                                  const CGBlockInfo &blockInfo) override;1079 1080  llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,1081                                   QualType T) override;1082 1083private:1084  void fillRunSkipBlockVars(CodeGenModule &CGM, const CGBlockInfo &blockInfo);1085};1086 1087namespace {1088 1089enum class MethodListType {1090  CategoryInstanceMethods,1091  CategoryClassMethods,1092  InstanceMethods,1093  ClassMethods,1094  ProtocolInstanceMethods,1095  ProtocolClassMethods,1096  OptionalProtocolInstanceMethods,1097  OptionalProtocolClassMethods,1098};1099 1100/// A convenience class for splitting the methods of a protocol into1101/// the four interesting groups.1102class ProtocolMethodLists {1103public:1104  enum Kind {1105    RequiredInstanceMethods,1106    RequiredClassMethods,1107    OptionalInstanceMethods,1108    OptionalClassMethods1109  };1110  enum { NumProtocolMethodLists = 4 };1111 1112  static MethodListType getMethodListKind(Kind kind) {1113    switch (kind) {1114    case RequiredInstanceMethods:1115      return MethodListType::ProtocolInstanceMethods;1116    case RequiredClassMethods:1117      return MethodListType::ProtocolClassMethods;1118    case OptionalInstanceMethods:1119      return MethodListType::OptionalProtocolInstanceMethods;1120    case OptionalClassMethods:1121      return MethodListType::OptionalProtocolClassMethods;1122    }1123    llvm_unreachable("bad kind");1124  }1125 1126  SmallVector<const ObjCMethodDecl *, 4> Methods[NumProtocolMethodLists];1127 1128  static ProtocolMethodLists get(const ObjCProtocolDecl *PD) {1129    ProtocolMethodLists result;1130 1131    for (auto *MD : PD->methods()) {1132      size_t index =1133          (2 * size_t(MD->isOptional())) + (size_t(MD->isClassMethod()));1134      result.Methods[index].push_back(MD);1135    }1136 1137    return result;1138  }1139 1140  template <class Self>1141  SmallVector<llvm::Constant *, 8> emitExtendedTypesArray(Self *self) const {1142    // In both ABIs, the method types list is parallel with the1143    // concatenation of the methods arrays in the following order:1144    //   instance methods1145    //   class methods1146    //   optional instance methods1147    //   optional class methods1148    SmallVector<llvm::Constant *, 8> result;1149 1150    // Methods is already in the correct order for both ABIs.1151    for (auto &list : Methods) {1152      for (auto MD : list) {1153        result.push_back(self->GetMethodVarType(MD, true));1154      }1155    }1156 1157    return result;1158  }1159 1160  template <class Self>1161  llvm::Constant *emitMethodList(Self *self, const ObjCProtocolDecl *PD,1162                                 Kind kind) const {1163    return self->emitMethodList(PD->getObjCRuntimeNameAsString(),1164                                getMethodListKind(kind), Methods[kind]);1165  }1166};1167 1168} // end anonymous namespace1169 1170class CGObjCMac : public CGObjCCommonMac {1171private:1172  friend ProtocolMethodLists;1173 1174  ObjCTypesHelper ObjCTypes;1175 1176  /// EmitModuleInfo - Another marker encoding module level1177  /// information.1178  void EmitModuleInfo();1179 1180  /// EmitModuleSymols - Emit module symbols, the list of defined1181  /// classes and categories. The result has type SymtabPtrTy.1182  llvm::Constant *EmitModuleSymbols();1183 1184  /// FinishModule - Write out global data structures at the end of1185  /// processing a translation unit.1186  void FinishModule();1187 1188  /// EmitClassExtension - Generate the class extension structure used1189  /// to store the weak ivar layout and properties. The return value1190  /// has type ClassExtensionPtrTy.1191  llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID,1192                                     CharUnits instanceSize,1193                                     bool hasMRCWeakIvars, bool isMetaclass);1194 1195  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,1196  /// for the given class.1197  llvm::Value *EmitClassRef(CodeGenFunction &CGF, const ObjCInterfaceDecl *ID);1198 1199  llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II);1200 1201  llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;1202 1203  /// EmitSuperClassRef - Emits reference to class's main metadata class.1204  llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);1205 1206  /// EmitIvarList - Emit the ivar list for the given1207  /// implementation. If ForClass is true the list of class ivars1208  /// (i.e. metaclass ivars) is emitted, otherwise the list of1209  /// interface ivars will be emitted. The return value has type1210  /// IvarListPtrTy.1211  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID, bool ForClass);1212 1213  /// EmitMetaClass - Emit a forward reference to the class structure1214  /// for the metaclass of the given interface. The return value has1215  /// type ClassPtrTy.1216  llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);1217 1218  /// EmitMetaClass - Emit a class structure for the metaclass of the1219  /// given implementation. The return value has type ClassPtrTy.1220  llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,1221                                llvm::Constant *Protocols,1222                                ArrayRef<const ObjCMethodDecl *> Methods);1223 1224  void emitMethodConstant(ConstantArrayBuilder &builder,1225                          const ObjCMethodDecl *MD);1226 1227  void emitMethodDescriptionConstant(ConstantArrayBuilder &builder,1228                                     const ObjCMethodDecl *MD);1229 1230  /// EmitMethodList - Emit the method list for the given1231  /// implementation. The return value has type MethodListPtrTy.1232  llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,1233                                 ArrayRef<const ObjCMethodDecl *> Methods);1234 1235  /// GetOrEmitProtocol - Get the protocol object for the given1236  /// declaration, emitting it if necessary. The return value has type1237  /// ProtocolPtrTy.1238  llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;1239 1240  /// GetOrEmitProtocolRef - Get a forward reference to the protocol1241  /// object for the given declaration, emitting it if needed. These1242  /// forward references will be filled in with empty bodies if no1243  /// definition is seen. The return value has type ProtocolPtrTy.1244  llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;1245 1246  /// EmitProtocolExtension - Generate the protocol extension1247  /// structure used to store optional instance and class methods, and1248  /// protocol properties. The return value has type1249  /// ProtocolExtensionPtrTy.1250  llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD,1251                                        const ProtocolMethodLists &methodLists);1252 1253  /// EmitProtocolList - Generate the list of referenced1254  /// protocols. The return value has type ProtocolListPtrTy.1255  llvm::Constant *EmitProtocolList(Twine Name,1256                                   ObjCProtocolDecl::protocol_iterator begin,1257                                   ObjCProtocolDecl::protocol_iterator end);1258 1259  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,1260  /// for the given selector.1261  llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);1262  ConstantAddress EmitSelectorAddr(Selector Sel);1263 1264public:1265  CGObjCMac(CodeGen::CodeGenModule &cgm);1266 1267  llvm::Constant *getNSConstantStringClassRef() override;1268 1269  llvm::Function *ModuleInitFunction() override;1270 1271  CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,1272                                      ReturnValueSlot Return,1273                                      QualType ResultType, Selector Sel,1274                                      llvm::Value *Receiver,1275                                      const CallArgList &CallArgs,1276                                      const ObjCInterfaceDecl *Class,1277                                      const ObjCMethodDecl *Method) override;1278 1279  CodeGen::RValue GenerateMessageSendSuper(1280      CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,1281      QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class,1282      bool isCategoryImpl, llvm::Value *Receiver, bool IsClassMessage,1283      const CallArgList &CallArgs, const ObjCMethodDecl *Method) override;1284 1285  llvm::Value *GetClass(CodeGenFunction &CGF,1286                        const ObjCInterfaceDecl *ID) override;1287 1288  llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override;1289  Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override;1290 1291  /// The NeXT/Apple runtimes do not support typed selectors; just emit an1292  /// untyped one.1293  llvm::Value *GetSelector(CodeGenFunction &CGF,1294                           const ObjCMethodDecl *Method) override;1295 1296  llvm::Constant *GetEHType(QualType T) override;1297 1298  void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;1299 1300  void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;1301 1302  void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}1303 1304  llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,1305                                   const ObjCProtocolDecl *PD) override;1306 1307  llvm::FunctionCallee GetPropertyGetFunction() override;1308  llvm::FunctionCallee GetPropertySetFunction() override;1309  llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,1310                                                       bool copy) override;1311  llvm::FunctionCallee GetGetStructFunction() override;1312  llvm::FunctionCallee GetSetStructFunction() override;1313  llvm::FunctionCallee GetCppAtomicObjectGetFunction() override;1314  llvm::FunctionCallee GetCppAtomicObjectSetFunction() override;1315  llvm::FunctionCallee EnumerationMutationFunction() override;1316 1317  void EmitTryStmt(CodeGen::CodeGenFunction &CGF,1318                   const ObjCAtTryStmt &S) override;1319  void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,1320                            const ObjCAtSynchronizedStmt &S) override;1321  void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);1322  void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,1323                     bool ClearInsertionPoint = true) override;1324  llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,1325                                Address AddrWeakObj) override;1326  void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,1327                          Address dst) override;1328  void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,1329                            Address dest, bool threadlocal = false) override;1330  void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,1331                          Address dest, llvm::Value *ivarOffset) override;1332  void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,1333                                Address dest) override;1334  void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address dest,1335                                Address src, llvm::Value *size) override;1336 1337  LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,1338                              llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,1339                              unsigned CVRQualifiers) override;1340  llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,1341                              const ObjCInterfaceDecl *Interface,1342                              const ObjCIvarDecl *Ivar) override;1343};1344 1345class CGObjCNonFragileABIMac : public CGObjCCommonMac {1346private:1347  friend ProtocolMethodLists;1348  ObjCNonFragileABITypesHelper ObjCTypes;1349  llvm::GlobalVariable *ObjCEmptyCacheVar;1350  llvm::Constant *ObjCEmptyVtableVar;1351 1352  /// SuperClassReferences - uniqued super class references.1353  llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> SuperClassReferences;1354 1355  /// MetaClassReferences - uniqued meta class references.1356  llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> MetaClassReferences;1357 1358  /// EHTypeReferences - uniqued class ehtype references.1359  llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> EHTypeReferences;1360 1361  /// VTableDispatchMethods - List of methods for which we generate1362  /// vtable-based message dispatch.1363  llvm::DenseSet<Selector> VTableDispatchMethods;1364 1365  /// DefinedMetaClasses - List of defined meta-classes.1366  std::vector<llvm::GlobalValue *> DefinedMetaClasses;1367 1368  /// isVTableDispatchedSelector - Returns true if SEL is a1369  /// vtable-based selector.1370  bool isVTableDispatchedSelector(Selector Sel);1371 1372  /// FinishNonFragileABIModule - Write out global data structures at the end of1373  /// processing a translation unit.1374  void FinishNonFragileABIModule();1375 1376  /// AddModuleClassList - Add the given list of class pointers to the1377  /// module with the provided symbol and section names.1378  void AddModuleClassList(ArrayRef<llvm::GlobalValue *> Container,1379                          StringRef SymbolName, StringRef SectionName);1380 1381  llvm::GlobalVariable *1382  BuildClassRoTInitializer(unsigned flags, unsigned InstanceStart,1383                           unsigned InstanceSize,1384                           const ObjCImplementationDecl *ID);1385  llvm::GlobalVariable *1386  BuildClassObject(const ObjCInterfaceDecl *CI, bool isMetaclass,1387                   llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,1388                   llvm::Constant *ClassRoGV, bool HiddenVisibility);1389 1390  void emitMethodConstant(ConstantArrayBuilder &builder,1391                          const ObjCMethodDecl *MD, bool forProtocol);1392 1393  /// Emit the method list for the given implementation. The return value1394  /// has type MethodListnfABITy.1395  llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,1396                                 ArrayRef<const ObjCMethodDecl *> Methods);1397 1398  /// EmitIvarList - Emit the ivar list for the given1399  /// implementation. If ForClass is true the list of class ivars1400  /// (i.e. metaclass ivars) is emitted, otherwise the list of1401  /// interface ivars will be emitted. The return value has type1402  /// IvarListnfABIPtrTy.1403  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);1404 1405  llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,1406                                    const ObjCIvarDecl *Ivar,1407                                    unsigned long int offset);1408 1409  /// GetOrEmitProtocol - Get the protocol object for the given1410  /// declaration, emitting it if necessary. The return value has type1411  /// ProtocolPtrTy.1412  llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;1413 1414  /// GetOrEmitProtocolRef - Get a forward reference to the protocol1415  /// object for the given declaration, emitting it if needed. These1416  /// forward references will be filled in with empty bodies if no1417  /// definition is seen. The return value has type ProtocolPtrTy.1418  llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;1419 1420  /// EmitProtocolList - Generate the list of referenced1421  /// protocols. The return value has type ProtocolListPtrTy.1422  llvm::Constant *EmitProtocolList(Twine Name,1423                                   ObjCProtocolDecl::protocol_iterator begin,1424                                   ObjCProtocolDecl::protocol_iterator end);1425 1426  CodeGen::RValue EmitVTableMessageSend(1427      CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,1428      QualType ResultType, Selector Sel, llvm::Value *Receiver, QualType Arg0Ty,1429      bool IsSuper, const CallArgList &CallArgs, const ObjCMethodDecl *Method);1430 1431  /// GetClassGlobal - Return the global variable for the Objective-C1432  /// class of the given name.1433  llvm::Constant *GetClassGlobal(StringRef Name,1434                                 ForDefinition_t IsForDefinition,1435                                 bool Weak = false, bool DLLImport = false);1436  llvm::Constant *GetClassGlobal(const ObjCInterfaceDecl *ID, bool isMetaclass,1437                                 ForDefinition_t isForDefinition);1438 1439  llvm::Constant *GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID);1440 1441  llvm::Value *EmitLoadOfClassRef(CodeGenFunction &CGF,1442                                  const ObjCInterfaceDecl *ID,1443                                  llvm::GlobalVariable *Entry);1444 1445  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,1446  /// for the given class reference.1447  llvm::Value *EmitClassRef(CodeGenFunction &CGF, const ObjCInterfaceDecl *ID);1448 1449  llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II,1450                                  const ObjCInterfaceDecl *ID);1451 1452  llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;1453 1454  /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,1455  /// for the given super class reference.1456  llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,1457                                 const ObjCInterfaceDecl *ID);1458 1459  /// EmitMetaClassRef - Return a Value * of the address of _class_t1460  /// meta-data1461  llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,1462                                const ObjCInterfaceDecl *ID, bool Weak);1463 1464  /// ObjCIvarOffsetVariable - Returns the ivar offset variable for1465  /// the given ivar.1466  ///1467  llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,1468                                               const ObjCIvarDecl *Ivar);1469 1470  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,1471  /// for the given selector.1472  llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);1473  ConstantAddress EmitSelectorAddr(Selector Sel);1474 1475  /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C1476  /// interface. The return value has type EHTypePtrTy.1477  llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,1478                                     ForDefinition_t IsForDefinition);1479 1480  StringRef getMetaclassSymbolPrefix() const { return "OBJC_METACLASS_$_"; }1481 1482  StringRef getClassSymbolPrefix() const { return "OBJC_CLASS_$_"; }1483 1484  void GetClassSizeInfo(const ObjCImplementationDecl *OID,1485                        uint32_t &InstanceStart, uint32_t &InstanceSize);1486 1487  // Shamelessly stolen from Analysis/CFRefCount.cpp1488  Selector GetNullarySelector(const char *name) const {1489    const IdentifierInfo *II = &CGM.getContext().Idents.get(name);1490    return CGM.getContext().Selectors.getSelector(0, &II);1491  }1492 1493  Selector GetUnarySelector(const char *name) const {1494    const IdentifierInfo *II = &CGM.getContext().Idents.get(name);1495    return CGM.getContext().Selectors.getSelector(1, &II);1496  }1497 1498  /// ImplementationIsNonLazy - Check whether the given category or1499  /// class implementation is "non-lazy".1500  bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;1501 1502  bool IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction &CGF,1503                                   const ObjCIvarDecl *IV) {1504    // Annotate the load as an invariant load iff inside an instance method1505    // and ivar belongs to instance method's class and one of its super class.1506    // This check is needed because the ivar offset is a lazily1507    // initialised value that may depend on objc_msgSend to perform a fixup on1508    // the first message dispatch.1509    //1510    // An additional opportunity to mark the load as invariant arises when the1511    // base of the ivar access is a parameter to an Objective C method.1512    // However, because the parameters are not available in the current1513    // interface, we cannot perform this check.1514    //1515    // Note that for direct methods, because objc_msgSend is skipped,1516    // and that the method may be inlined, this optimization actually1517    // can't be performed.1518    if (const ObjCMethodDecl *MD =1519            dyn_cast_or_null<ObjCMethodDecl>(CGF.CurFuncDecl))1520      if (MD->isInstanceMethod() && !MD->isDirectMethod())1521        if (const ObjCInterfaceDecl *ID = MD->getClassInterface())1522          return IV->getContainingInterface()->isSuperClassOf(ID);1523    return false;1524  }1525 1526  bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {1527    // Test a class by checking its superclasses up to1528    // its base class if it has one.1529    assert(ID != nullptr && "Passed a null class to check layout");1530    for (; ID != nullptr; ID = ID->getSuperClass()) {1531      // The layout of base class NSObject1532      // is guaranteed to be statically known1533      if (ID->getIdentifier()->getName() == "NSObject")1534        return true;1535 1536      // If we cannot see the @implementation of a class,1537      // we cannot statically know the class layout.1538      if (!ID->getImplementation())1539        return false;1540    }1541 1542    // We know the layout of all the intermediate classes and superclasses.1543    return true;1544  }1545 1546public:1547  CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);1548 1549  llvm::Constant *getNSConstantStringClassRef() override;1550 1551  llvm::Function *ModuleInitFunction() override;1552 1553  CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,1554                                      ReturnValueSlot Return,1555                                      QualType ResultType, Selector Sel,1556                                      llvm::Value *Receiver,1557                                      const CallArgList &CallArgs,1558                                      const ObjCInterfaceDecl *Class,1559                                      const ObjCMethodDecl *Method) override;1560 1561  CodeGen::RValue GenerateMessageSendSuper(1562      CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,1563      QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class,1564      bool isCategoryImpl, llvm::Value *Receiver, bool IsClassMessage,1565      const CallArgList &CallArgs, const ObjCMethodDecl *Method) override;1566 1567  llvm::Value *GetClass(CodeGenFunction &CGF,1568                        const ObjCInterfaceDecl *ID) override;1569 1570  llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override {1571    return EmitSelector(CGF, Sel);1572  }1573  Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override {1574    return EmitSelectorAddr(Sel);1575  }1576 1577  /// The NeXT/Apple runtimes do not support typed selectors; just emit an1578  /// untyped one.1579  llvm::Value *GetSelector(CodeGenFunction &CGF,1580                           const ObjCMethodDecl *Method) override {1581    return EmitSelector(CGF, Method->getSelector());1582  }1583 1584  void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;1585 1586  void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;1587 1588  void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}1589 1590  llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,1591                                   const ObjCProtocolDecl *PD) override;1592 1593  llvm::Constant *GetEHType(QualType T) override;1594 1595  llvm::FunctionCallee GetPropertyGetFunction() override {1596    return ObjCTypes.getGetPropertyFn();1597  }1598  llvm::FunctionCallee GetPropertySetFunction() override {1599    return ObjCTypes.getSetPropertyFn();1600  }1601 1602  llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,1603                                                       bool copy) override {1604    return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);1605  }1606 1607  llvm::FunctionCallee GetSetStructFunction() override {1608    return ObjCTypes.getCopyStructFn();1609  }1610 1611  llvm::FunctionCallee GetGetStructFunction() override {1612    return ObjCTypes.getCopyStructFn();1613  }1614 1615  llvm::FunctionCallee GetCppAtomicObjectSetFunction() override {1616    return ObjCTypes.getCppAtomicObjectFunction();1617  }1618 1619  llvm::FunctionCallee GetCppAtomicObjectGetFunction() override {1620    return ObjCTypes.getCppAtomicObjectFunction();1621  }1622 1623  llvm::FunctionCallee EnumerationMutationFunction() override {1624    return ObjCTypes.getEnumerationMutationFn();1625  }1626 1627  void EmitTryStmt(CodeGen::CodeGenFunction &CGF,1628                   const ObjCAtTryStmt &S) override;1629  void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,1630                            const ObjCAtSynchronizedStmt &S) override;1631  void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,1632                     bool ClearInsertionPoint = true) override;1633  llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,1634                                Address AddrWeakObj) override;1635  void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,1636                          Address edst) override;1637  void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,1638                            Address dest, bool threadlocal = false) override;1639  void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,1640                          Address dest, llvm::Value *ivarOffset) override;1641  void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,1642                                Address dest) override;1643  void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address dest,1644                                Address src, llvm::Value *size) override;1645  LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,1646                              llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,1647                              unsigned CVRQualifiers) override;1648  llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,1649                              const ObjCInterfaceDecl *Interface,1650                              const ObjCIvarDecl *Ivar) override;1651};1652 1653/// A helper class for performing the null-initialization of a return1654/// value.1655struct NullReturnState {1656  llvm::BasicBlock *NullBB = nullptr;1657  NullReturnState() = default;1658 1659  /// Perform a null-check of the given receiver.1660  void init(CodeGenFunction &CGF, llvm::Value *receiver) {1661    // Make blocks for the null-receiver and call edges.1662    NullBB = CGF.createBasicBlock("msgSend.null-receiver");1663    llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call");1664 1665    // Check for a null receiver and, if there is one, jump to the1666    // null-receiver block.  There's no point in trying to avoid it:1667    // we're always going to put *something* there, because otherwise1668    // we shouldn't have done this null-check in the first place.1669    llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);1670    CGF.Builder.CreateCondBr(isNull, NullBB, callBB);1671 1672    // Otherwise, start performing the call.1673    CGF.EmitBlock(callBB);1674  }1675 1676  /// Complete the null-return operation.  It is valid to call this1677  /// regardless of whether 'init' has been called.1678  RValue complete(CodeGenFunction &CGF, ReturnValueSlot returnSlot,1679                  RValue result, QualType resultType,1680                  const CallArgList &CallArgs, const ObjCMethodDecl *Method) {1681    // If we never had to do a null-check, just use the raw result.1682    if (!NullBB)1683      return result;1684 1685    // The continuation block.  This will be left null if we don't have an1686    // IP, which can happen if the method we're calling is marked noreturn.1687    llvm::BasicBlock *contBB = nullptr;1688 1689    // Finish the call path.1690    llvm::BasicBlock *callBB = CGF.Builder.GetInsertBlock();1691    if (callBB) {1692      contBB = CGF.createBasicBlock("msgSend.cont");1693      CGF.Builder.CreateBr(contBB);1694    }1695 1696    // Okay, start emitting the null-receiver block.1697    CGF.EmitBlock(NullBB);1698 1699    // Destroy any consumed arguments we've got.1700    if (Method) {1701      CGObjCRuntime::destroyCalleeDestroyedArguments(CGF, Method, CallArgs);1702    }1703 1704    // The phi code below assumes that we haven't needed any control flow yet.1705    assert(CGF.Builder.GetInsertBlock() == NullBB);1706 1707    // If we've got a void return, just jump to the continuation block.1708    if (result.isScalar() && resultType->isVoidType()) {1709      // No jumps required if the message-send was noreturn.1710      if (contBB)1711        CGF.EmitBlock(contBB);1712      return result;1713    }1714 1715    // If we've got a scalar return, build a phi.1716    if (result.isScalar()) {1717      // Derive the null-initialization value.1718      llvm::Value *null =1719          CGF.EmitFromMemory(CGF.CGM.EmitNullConstant(resultType), resultType);1720 1721      // If no join is necessary, just flow out.1722      if (!contBB)1723        return RValue::get(null);1724 1725      // Otherwise, build a phi.1726      CGF.EmitBlock(contBB);1727      llvm::PHINode *phi = CGF.Builder.CreatePHI(null->getType(), 2);1728      phi->addIncoming(result.getScalarVal(), callBB);1729      phi->addIncoming(null, NullBB);1730      return RValue::get(phi);1731    }1732 1733    // If we've got an aggregate return, null the buffer out.1734    // FIXME: maybe we should be doing things differently for all the1735    // cases where the ABI has us returning (1) non-agg values in1736    // memory or (2) agg values in registers.1737    if (result.isAggregate()) {1738      assert(result.isAggregate() && "null init of non-aggregate result?");1739      if (!returnSlot.isUnused())1740        CGF.EmitNullInitialization(result.getAggregateAddress(), resultType);1741      if (contBB)1742        CGF.EmitBlock(contBB);1743      return result;1744    }1745 1746    // Complex types.1747    CGF.EmitBlock(contBB);1748    CodeGenFunction::ComplexPairTy callResult = result.getComplexVal();1749 1750    // Find the scalar type and its zero value.1751    llvm::Type *scalarTy = callResult.first->getType();1752    llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);1753 1754    // Build phis for both coordinates.1755    llvm::PHINode *real = CGF.Builder.CreatePHI(scalarTy, 2);1756    real->addIncoming(callResult.first, callBB);1757    real->addIncoming(scalarZero, NullBB);1758    llvm::PHINode *imag = CGF.Builder.CreatePHI(scalarTy, 2);1759    imag->addIncoming(callResult.second, callBB);1760    imag->addIncoming(scalarZero, NullBB);1761    return RValue::getComplex(real, imag);1762  }1763};1764 1765} // end anonymous namespace1766 1767/* *** Helper Functions *** */1768 1769/// getConstantGEP() - Help routine to construct simple GEPs.1770static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,1771                                      llvm::GlobalVariable *C, unsigned idx0,1772                                      unsigned idx1) {1773  llvm::Value *Idxs[] = {1774      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),1775      llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)};1776  return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);1777}1778 1779/// hasObjCExceptionAttribute - Return true if this class or any super1780/// class has the __objc_exception__ attribute.1781static bool hasObjCExceptionAttribute(ASTContext &Context,1782                                      const ObjCInterfaceDecl *OID) {1783  if (OID->hasAttr<ObjCExceptionAttr>())1784    return true;1785  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())1786    return hasObjCExceptionAttribute(Context, Super);1787  return false;1788}1789 1790static llvm::GlobalValue::LinkageTypes1791getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section) {1792  if (CGM.getTriple().isOSBinFormatMachO() &&1793      (Section.empty() || Section.starts_with("__DATA")))1794    return llvm::GlobalValue::InternalLinkage;1795  return llvm::GlobalValue::PrivateLinkage;1796}1797 1798/// A helper function to create an internal or private global variable.1799static llvm::GlobalVariable *1800finishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder,1801                      const llvm::Twine &Name, CodeGenModule &CGM) {1802  std::string SectionName;1803  if (CGM.getTriple().isOSBinFormatMachO())1804    SectionName = "__DATA, __objc_const";1805  auto *GV = Builder.finishAndCreateGlobal(1806      Name, CGM.getPointerAlign(), /*constant*/ false,1807      getLinkageTypeForObjCMetadata(CGM, SectionName));1808  GV->setSection(SectionName);1809  return GV;1810}1811 1812/* *** CGObjCMac Public Interface *** */1813 1814CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)1815    : CGObjCCommonMac(cgm), ObjCTypes(cgm) {1816  ObjCABI = 1;1817  EmitImageInfo();1818}1819 1820/// GetClass - Return a reference to the class for the given interface1821/// decl.1822llvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,1823                                 const ObjCInterfaceDecl *ID) {1824  return EmitClassRef(CGF, ID);1825}1826 1827/// GetSelector - Return the pointer to the unique'd string for this selector.1828llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {1829  return EmitSelector(CGF, Sel);1830}1831Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {1832  return EmitSelectorAddr(Sel);1833}1834llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF,1835                                    const ObjCMethodDecl *Method) {1836  return EmitSelector(CGF, Method->getSelector());1837}1838 1839llvm::Constant *CGObjCMac::GetEHType(QualType T) {1840  if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {1841    return CGM.GetAddrOfRTTIDescriptor(1842        CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);1843  }1844  if (T->isObjCClassType() || T->isObjCQualifiedClassType()) {1845    return CGM.GetAddrOfRTTIDescriptor(1846        CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);1847  }1848  if (T->isObjCObjectPointerType())1849    return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true);1850 1851  llvm_unreachable("asking for catch type for ObjC type in fragile runtime");1852}1853 1854/// Generate a constant CFString object.1855/*1856  struct __builtin_CFString {1857  const int *isa; // point to __CFConstantStringClassReference1858  int flags;1859  const char *str;1860  long length;1861  };1862*/1863 1864/// or Generate a constant NSString object.1865/*1866   struct __builtin_NSString {1867     const int *isa; // point to __NSConstantStringClassReference1868     const char *str;1869     unsigned int length;1870   };1871*/1872 1873ConstantAddress1874CGObjCCommonMac::GenerateConstantString(const StringLiteral *SL) {1875  return (!CGM.getLangOpts().NoConstantCFStrings1876              ? CGM.GetAddrOfConstantCFString(SL)1877              : GenerateConstantNSString(SL));1878}1879 1880static llvm::StringMapEntry<llvm::GlobalVariable *> &1881GetConstantStringEntry(llvm::StringMap<llvm::GlobalVariable *> &Map,1882                       const StringLiteral *Literal, unsigned &StringLength) {1883  StringRef String = Literal->getString();1884  StringLength = String.size();1885  return *Map.insert(std::make_pair(String, nullptr)).first;1886}1887 1888llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {1889  if (llvm::Value *V = ConstantStringClassRef)1890    return cast<llvm::Constant>(V);1891 1892  auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;1893  std::string str = StringClass.empty() ? "_NSConstantStringClassReference"1894                                        : "_" + StringClass + "ClassReference";1895 1896  llvm::Type *PTy = llvm::ArrayType::get(CGM.IntTy, 0);1897  auto GV = CGM.CreateRuntimeVariable(PTy, str);1898  ConstantStringClassRef = GV;1899  return GV;1900}1901 1902llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {1903  if (llvm::Value *V = ConstantStringClassRef)1904    return cast<llvm::Constant>(V);1905 1906  auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;1907  std::string str = StringClass.empty() ? "OBJC_CLASS_$_NSConstantString"1908                                        : "OBJC_CLASS_$_" + StringClass;1909  llvm::Constant *GV = GetClassGlobal(str, NotForDefinition);1910  ConstantStringClassRef = GV;1911  return GV;1912}1913 1914ConstantAddress1915CGObjCCommonMac::GenerateConstantNSString(const StringLiteral *Literal) {1916  unsigned StringLength = 0;1917  llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =1918      GetConstantStringEntry(NSConstantStringMap, Literal, StringLength);1919 1920  if (auto *C = Entry.second)1921    return ConstantAddress(C, C->getValueType(),1922                           CharUnits::fromQuantity(C->getAlignment()));1923 1924  // If we don't already have it, get _NSConstantStringClassReference.1925  llvm::Constant *Class = getNSConstantStringClassRef();1926 1927  // If we don't already have it, construct the type for a constant NSString.1928  if (!NSConstantStringType) {1929    NSConstantStringType =1930        llvm::StructType::create({CGM.DefaultPtrTy, CGM.Int8PtrTy, CGM.IntTy},1931                                 "struct.__builtin_NSString");1932  }1933 1934  ConstantInitBuilder Builder(CGM);1935  auto Fields = Builder.beginStruct(NSConstantStringType);1936 1937  // Class pointer.1938  Fields.addSignedPointer(Class,1939                          CGM.getCodeGenOpts().PointerAuth.ObjCIsaPointers,1940                          GlobalDecl(), QualType());1941 1942  // String pointer.1943  llvm::Constant *C =1944      llvm::ConstantDataArray::getString(VMContext, Entry.first());1945 1946  llvm::GlobalValue::LinkageTypes Linkage = llvm::GlobalValue::PrivateLinkage;1947  bool isConstant = !CGM.getLangOpts().WritableStrings;1948 1949  auto *GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), isConstant,1950                                      Linkage, C, ".str");1951  GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);1952  // Don't enforce the target's minimum global alignment, since the only use1953  // of the string is via this class initializer.1954  GV->setAlignment(llvm::Align(1));1955  Fields.add(GV);1956 1957  // String length.1958  Fields.addInt(CGM.IntTy, StringLength);1959 1960  // The struct.1961  CharUnits Alignment = CGM.getPointerAlign();1962  GV = Fields.finishAndCreateGlobal("_unnamed_nsstring_", Alignment,1963                                    /*constant*/ true,1964                                    llvm::GlobalVariable::PrivateLinkage);1965  const char *NSStringSection = "__OBJC,__cstring_object,regular,no_dead_strip";1966  const char *NSStringNonFragileABISection =1967      "__DATA,__objc_stringobj,regular,no_dead_strip";1968  // FIXME. Fix section.1969  GV->setSection(CGM.getLangOpts().ObjCRuntime.isNonFragile()1970                     ? NSStringNonFragileABISection1971                     : NSStringSection);1972  Entry.second = GV;1973 1974  return ConstantAddress(GV, GV->getValueType(), Alignment);1975}1976 1977enum { kCFTaggedObjectID_Integer = (1 << 1) + 1 };1978 1979/// Generates a message send where the super is the receiver.  This is1980/// a message send to self with special delivery semantics indicating1981/// which class's method should be called.1982CodeGen::RValue CGObjCMac::GenerateMessageSendSuper(1983    CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,1984    Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,1985    llvm::Value *Receiver, bool IsClassMessage,1986    const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {1987  // Create and init a super structure; this is a (receiver, class)1988  // pair we will pass to objc_msgSendSuper.1989  RawAddress ObjCSuper = CGF.CreateTempAlloca(1990      ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super");1991  llvm::Value *ReceiverAsObject =1992      CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);1993  CGF.Builder.CreateStore(ReceiverAsObject,1994                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));1995 1996  // If this is a class message the metaclass is passed as the target.1997  llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(VMContext);1998  llvm::Value *Target;1999  if (IsClassMessage) {2000    if (isCategoryImpl) {2001      // Message sent to 'super' in a class method defined in a category2002      // implementation requires an odd treatment.2003      // If we are in a class method, we must retrieve the2004      // _metaclass_ for the current class, pointed at by2005      // the class's "isa" pointer.  The following assumes that2006      // isa" is the first ivar in a class (which it must be).2007      Target = EmitClassRef(CGF, Class->getSuperClass());2008      Target = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, Target, 0);2009      Target = CGF.Builder.CreateAlignedLoad(ClassTyPtr, Target,2010                                             CGF.getPointerAlign());2011    } else {2012      llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);2013      llvm::Value *SuperPtr =2014          CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, MetaClassPtr, 1);2015      llvm::Value *Super = CGF.Builder.CreateAlignedLoad(ClassTyPtr, SuperPtr,2016                                                         CGF.getPointerAlign());2017      Target = Super;2018    }2019  } else if (isCategoryImpl)2020    Target = EmitClassRef(CGF, Class->getSuperClass());2021  else {2022    llvm::Value *ClassPtr = EmitSuperClassRef(Class);2023    ClassPtr = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, ClassPtr, 1);2024    Target = CGF.Builder.CreateAlignedLoad(ClassTyPtr, ClassPtr,2025                                           CGF.getPointerAlign());2026  }2027  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and2028  // ObjCTypes types.2029  llvm::Type *ClassTy =2030      CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());2031  Target = CGF.Builder.CreateBitCast(Target, ClassTy);2032  CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));2033  return EmitMessageSend(CGF, Return, ResultType, Sel, ObjCSuper.getPointer(),2034                         ObjCTypes.SuperPtrCTy, true, CallArgs, Method, Class,2035                         ObjCTypes);2036}2037 2038/// Generate code for a message send expression.2039CodeGen::RValue CGObjCMac::GenerateMessageSend(2040    CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,2041    Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,2042    const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {2043  return EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,2044                         CGF.getContext().getObjCIdType(), false, CallArgs,2045                         Method, Class, ObjCTypes);2046}2047 2048CodeGen::RValue CGObjCCommonMac::EmitMessageSend(2049    CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,2050    Selector Sel, llvm::Value *Arg0, QualType Arg0Ty, bool IsSuper,2051    const CallArgList &CallArgs, const ObjCMethodDecl *Method,2052    const ObjCInterfaceDecl *ClassReceiver,2053    const ObjCCommonTypesHelper &ObjCTypes) {2054  CodeGenTypes &Types = CGM.getTypes();2055  auto selTy = CGF.getContext().getObjCSelType();2056  llvm::Value *SelValue = llvm::UndefValue::get(Types.ConvertType(selTy));2057 2058  CallArgList ActualArgs;2059  if (!IsSuper)2060    Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);2061  ActualArgs.add(RValue::get(Arg0), Arg0Ty);2062  if (!Method || !Method->isDirectMethod())2063    ActualArgs.add(RValue::get(SelValue), selTy);2064  ActualArgs.addFrom(CallArgs);2065 2066  // If we're calling a method, use the formal signature.2067  MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);2068 2069  if (Method)2070    assert(CGM.getContext().getCanonicalType(Method->getReturnType()) ==2071               CGM.getContext().getCanonicalType(ResultType) &&2072           "Result type mismatch!");2073 2074  bool ReceiverCanBeNull =2075      canMessageReceiverBeNull(CGF, Method, IsSuper, ClassReceiver, Arg0);2076 2077  bool RequiresNullCheck = false;2078  bool RequiresSelValue = true;2079 2080  llvm::FunctionCallee Fn = nullptr;2081  if (Method && Method->isDirectMethod()) {2082    assert(!IsSuper);2083    Fn = GenerateDirectMethod(Method, Method->getClassInterface());2084    // Direct methods will synthesize the proper `_cmd` internally,2085    // so just don't bother with setting the `_cmd` argument.2086    RequiresSelValue = false;2087  } else if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {2088    if (ReceiverCanBeNull)2089      RequiresNullCheck = true;2090    Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)2091                        : ObjCTypes.getSendStretFn(IsSuper);2092  } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {2093    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)2094                        : ObjCTypes.getSendFpretFn(IsSuper);2095  } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {2096    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)2097                        : ObjCTypes.getSendFp2retFn(IsSuper);2098  } else {2099    // arm64 uses objc_msgSend for stret methods and yet null receiver check2100    // must be made for it.2101    if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(MSI.CallInfo))2102      RequiresNullCheck = true;2103    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)2104                        : ObjCTypes.getSendFn(IsSuper);2105  }2106 2107  // Cast function to proper signature2108  llvm::Constant *BitcastFn = cast<llvm::Constant>(2109      CGF.Builder.CreateBitCast(Fn.getCallee(), MSI.MessengerType));2110 2111  // We don't need to emit a null check to zero out an indirect result if the2112  // result is ignored.2113  if (Return.isUnused())2114    RequiresNullCheck = false;2115 2116  // Emit a null-check if there's a consumed argument other than the receiver.2117  if (!RequiresNullCheck && Method && Method->hasParamDestroyedInCallee())2118    RequiresNullCheck = true;2119 2120  NullReturnState nullReturn;2121  if (RequiresNullCheck) {2122    nullReturn.init(CGF, Arg0);2123  }2124 2125  // If a selector value needs to be passed, emit the load before the call.2126  if (RequiresSelValue) {2127    SelValue = GetSelector(CGF, Sel);2128    ActualArgs[1] = CallArg(RValue::get(SelValue), selTy);2129  }2130 2131  llvm::CallBase *CallSite;2132  CGCallee Callee = CGCallee::forDirect(BitcastFn);2133  RValue rvalue =2134      CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, &CallSite);2135 2136  // Mark the call as noreturn if the method is marked noreturn and the2137  // receiver cannot be null.2138  if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {2139    CallSite->setDoesNotReturn();2140  }2141 2142  return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,2143                             RequiresNullCheck ? Method : nullptr);2144}2145 2146static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT,2147                                           bool pointee = false) {2148  // Note that GC qualification applies recursively to C pointer types2149  // that aren't otherwise decorated.  This is weird, but it's probably2150  // an intentional workaround to the unreliable placement of GC qualifiers.2151  if (FQT.isObjCGCStrong())2152    return Qualifiers::Strong;2153 2154  if (FQT.isObjCGCWeak())2155    return Qualifiers::Weak;2156 2157  if (auto ownership = FQT.getObjCLifetime()) {2158    // Ownership does not apply recursively to C pointer types.2159    if (pointee)2160      return Qualifiers::GCNone;2161    switch (ownership) {2162    case Qualifiers::OCL_Weak:2163      return Qualifiers::Weak;2164    case Qualifiers::OCL_Strong:2165      return Qualifiers::Strong;2166    case Qualifiers::OCL_ExplicitNone:2167      return Qualifiers::GCNone;2168    case Qualifiers::OCL_Autoreleasing:2169      llvm_unreachable("autoreleasing ivar?");2170    case Qualifiers::OCL_None:2171      llvm_unreachable("known nonzero");2172    }2173    llvm_unreachable("bad objc ownership");2174  }2175 2176  // Treat unqualified retainable pointers as strong.2177  if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())2178    return Qualifiers::Strong;2179 2180  // Walk into C pointer types, but only in GC.2181  if (Ctx.getLangOpts().getGC() != LangOptions::NonGC) {2182    if (const PointerType *PT = FQT->getAs<PointerType>())2183      return GetGCAttrTypeForType(Ctx, PT->getPointeeType(), /*pointee*/ true);2184  }2185 2186  return Qualifiers::GCNone;2187}2188 2189namespace {2190struct IvarInfo {2191  CharUnits Offset;2192  uint64_t SizeInWords;2193  IvarInfo(CharUnits offset, uint64_t sizeInWords)2194      : Offset(offset), SizeInWords(sizeInWords) {}2195 2196  // Allow sorting based on byte pos.2197  bool operator<(const IvarInfo &other) const { return Offset < other.Offset; }2198};2199 2200/// A helper class for building GC layout strings.2201class IvarLayoutBuilder {2202  CodeGenModule &CGM;2203 2204  /// The start of the layout.  Offsets will be relative to this value,2205  /// and entries less than this value will be silently discarded.2206  CharUnits InstanceBegin;2207 2208  /// The end of the layout.  Offsets will never exceed this value.2209  CharUnits InstanceEnd;2210 2211  /// Whether we're generating the strong layout or the weak layout.2212  bool ForStrongLayout;2213 2214  /// Whether the offsets in IvarsInfo might be out-of-order.2215  bool IsDisordered = false;2216 2217  llvm::SmallVector<IvarInfo, 8> IvarsInfo;2218 2219public:2220  IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,2221                    CharUnits instanceEnd, bool forStrongLayout)2222      : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),2223        ForStrongLayout(forStrongLayout) {}2224 2225  void visitRecord(const RecordType *RT, CharUnits offset);2226 2227  template <class Iterator, class GetOffsetFn>2228  void visitAggregate(Iterator begin, Iterator end, CharUnits aggrOffset,2229                      const GetOffsetFn &getOffset);2230 2231  void visitField(const FieldDecl *field, CharUnits offset);2232 2233  /// Add the layout of a block implementation.2234  void visitBlock(const CGBlockInfo &blockInfo);2235 2236  /// Is there any information for an interesting bitmap?2237  bool hasBitmapData() const { return !IvarsInfo.empty(); }2238 2239  llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,2240                              llvm::SmallVectorImpl<unsigned char> &buffer);2241 2242  static void dump(ArrayRef<unsigned char> buffer) {2243    const unsigned char *s = buffer.data();2244    for (unsigned i = 0, e = buffer.size(); i < e; i++)2245      if (!(s[i] & 0xf0))2246        printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");2247      else2248        printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");2249    printf("\n");2250  }2251};2252} // end anonymous namespace2253 2254llvm::Constant *2255CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,2256                                    const CGBlockInfo &blockInfo) {2257 2258  llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);2259  if (CGM.getLangOpts().getGC() == LangOptions::NonGC)2260    return nullPtr;2261 2262  IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.BlockSize,2263                            /*for strong layout*/ true);2264 2265  builder.visitBlock(blockInfo);2266 2267  if (!builder.hasBitmapData())2268    return nullPtr;2269 2270  llvm::SmallVector<unsigned char, 32> buffer;2271  llvm::Constant *C = builder.buildBitmap(*this, buffer);2272  if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {2273    printf("\n block variable layout for block: ");2274    builder.dump(buffer);2275  }2276 2277  return C;2278}2279 2280void IvarLayoutBuilder::visitBlock(const CGBlockInfo &blockInfo) {2281  // __isa is the first field in block descriptor and must assume by runtime's2282  // convention that it is GC'able.2283  IvarsInfo.push_back(IvarInfo(CharUnits::Zero(), 1));2284 2285  const BlockDecl *blockDecl = blockInfo.getBlockDecl();2286 2287  // Ignore the optional 'this' capture: C++ objects are not assumed2288  // to be GC'ed.2289 2290  CharUnits lastFieldOffset;2291 2292  // Walk the captured variables.2293  for (const auto &CI : blockDecl->captures()) {2294    const VarDecl *variable = CI.getVariable();2295    QualType type = variable->getType();2296 2297    const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);2298 2299    // Ignore constant captures.2300    if (capture.isConstant())2301      continue;2302 2303    CharUnits fieldOffset = capture.getOffset();2304 2305    // Block fields are not necessarily ordered; if we detect that we're2306    // adding them out-of-order, make sure we sort later.2307    if (fieldOffset < lastFieldOffset)2308      IsDisordered = true;2309    lastFieldOffset = fieldOffset;2310 2311    // __block variables are passed by their descriptor address.2312    if (CI.isByRef()) {2313      IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1));2314      continue;2315    }2316 2317    assert(!type->isArrayType() && "array variable should not be caught");2318    if (const RecordType *record = type->getAsCanonical<RecordType>()) {2319      visitRecord(record, fieldOffset);2320      continue;2321    }2322 2323    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);2324 2325    if (GCAttr == Qualifiers::Strong) {2326      assert(CGM.getContext().getTypeSize(type) ==2327             CGM.getTarget().getPointerWidth(LangAS::Default));2328      IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1));2329    }2330  }2331}2332 2333/// getBlockCaptureLifetime - This routine returns life time of the captured2334/// block variable for the purpose of block layout meta-data generation. FQT is2335/// the type of the variable captured in the block.2336Qualifiers::ObjCLifetime2337CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT, bool ByrefLayout) {2338  // If it has an ownership qualifier, we're done.2339  if (auto lifetime = FQT.getObjCLifetime())2340    return lifetime;2341 2342  // If it doesn't, and this is ARC, it has no ownership.2343  if (CGM.getLangOpts().ObjCAutoRefCount)2344    return Qualifiers::OCL_None;2345 2346  // In MRC, retainable pointers are owned by non-__block variables.2347  if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())2348    return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;2349 2350  return Qualifiers::OCL_None;2351}2352 2353void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,2354                                             Qualifiers::ObjCLifetime LifeTime,2355                                             CharUnits FieldOffset,2356                                             CharUnits FieldSize) {2357  // __block variables are passed by their descriptor address.2358  if (IsByref)2359    RunSkipBlockVars.push_back(2360        RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset, FieldSize));2361  else if (LifeTime == Qualifiers::OCL_Strong)2362    RunSkipBlockVars.push_back(2363        RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset, FieldSize));2364  else if (LifeTime == Qualifiers::OCL_Weak)2365    RunSkipBlockVars.push_back(2366        RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset, FieldSize));2367  else if (LifeTime == Qualifiers::OCL_ExplicitNone)2368    RunSkipBlockVars.push_back(2369        RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset, FieldSize));2370  else2371    RunSkipBlockVars.push_back(2372        RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES, FieldOffset, FieldSize));2373}2374 2375void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,2376                                          const RecordDecl *RD,2377                                          ArrayRef<const FieldDecl *> RecFields,2378                                          CharUnits BytePos, bool &HasUnion,2379                                          bool ByrefLayout) {2380  bool IsUnion = (RD && RD->isUnion());2381  CharUnits MaxUnionSize = CharUnits::Zero();2382  const FieldDecl *MaxField = nullptr;2383  const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;2384  CharUnits MaxFieldOffset = CharUnits::Zero();2385  CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();2386 2387  if (RecFields.empty())2388    return;2389  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();2390 2391  for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {2392    const FieldDecl *Field = RecFields[i];2393    // Note that 'i' here is actually the field index inside RD of Field,2394    // although this dependency is hidden.2395    const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);2396    CharUnits FieldOffset =2397        CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i));2398 2399    // Skip over unnamed or bitfields2400    if (!Field->getIdentifier() || Field->isBitField()) {2401      LastFieldBitfieldOrUnnamed = Field;2402      LastBitfieldOrUnnamedOffset = FieldOffset;2403      continue;2404    }2405 2406    LastFieldBitfieldOrUnnamed = nullptr;2407    QualType FQT = Field->getType();2408    if (FQT->isRecordType() || FQT->isUnionType()) {2409      if (FQT->isUnionType())2410        HasUnion = true;2411 2412      BuildRCBlockVarRecordLayout(FQT->castAsCanonical<RecordType>(),2413                                  BytePos + FieldOffset, HasUnion);2414      continue;2415    }2416 2417    if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {2418      auto *CArray = cast<ConstantArrayType>(Array);2419      uint64_t ElCount = CArray->getZExtSize();2420      assert(CArray && "only array with known element size is supported");2421      FQT = CArray->getElementType();2422      while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {2423        auto *CArray = cast<ConstantArrayType>(Array);2424        ElCount *= CArray->getZExtSize();2425        FQT = CArray->getElementType();2426      }2427      if (FQT->isRecordType() && ElCount) {2428        int OldIndex = RunSkipBlockVars.size() - 1;2429        auto *RT = FQT->castAsCanonical<RecordType>();2430        BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset, HasUnion);2431 2432        // Replicate layout information for each array element. Note that2433        // one element is already done.2434        uint64_t ElIx = 1;2435        for (int FirstIndex = RunSkipBlockVars.size() - 1; ElIx < ElCount;2436             ElIx++) {2437          CharUnits Size = CGM.getContext().getTypeSizeInChars(RT);2438          for (int i = OldIndex + 1; i <= FirstIndex; ++i)2439            RunSkipBlockVars.push_back(2440                RUN_SKIP(RunSkipBlockVars[i].opcode,2441                         RunSkipBlockVars[i].block_var_bytepos + Size * ElIx,2442                         RunSkipBlockVars[i].block_var_size));2443        }2444        continue;2445      }2446    }2447    CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType());2448    if (IsUnion) {2449      CharUnits UnionIvarSize = FieldSize;2450      if (UnionIvarSize > MaxUnionSize) {2451        MaxUnionSize = UnionIvarSize;2452        MaxField = Field;2453        MaxFieldOffset = FieldOffset;2454      }2455    } else {2456      UpdateRunSkipBlockVars(false, getBlockCaptureLifetime(FQT, ByrefLayout),2457                             BytePos + FieldOffset, FieldSize);2458    }2459  }2460 2461  if (LastFieldBitfieldOrUnnamed) {2462    if (LastFieldBitfieldOrUnnamed->isBitField()) {2463      // Last field was a bitfield. Must update the info.2464      uint64_t BitFieldSize = LastFieldBitfieldOrUnnamed->getBitWidthValue();2465      unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +2466                         ((BitFieldSize % ByteSizeInBits) != 0);2467      CharUnits Size = CharUnits::fromQuantity(UnsSize);2468      Size += LastBitfieldOrUnnamedOffset;2469      UpdateRunSkipBlockVars(2470          false,2471          getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),2472                                  ByrefLayout),2473          BytePos + LastBitfieldOrUnnamedOffset, Size);2474    } else {2475      assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&2476             "Expected unnamed");2477      // Last field was unnamed. Must update skip info.2478      CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(2479          LastFieldBitfieldOrUnnamed->getType());2480      UpdateRunSkipBlockVars(2481          false,2482          getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),2483                                  ByrefLayout),2484          BytePos + LastBitfieldOrUnnamedOffset, FieldSize);2485    }2486  }2487 2488  if (MaxField)2489    UpdateRunSkipBlockVars(2490        false, getBlockCaptureLifetime(MaxField->getType(), ByrefLayout),2491        BytePos + MaxFieldOffset, MaxUnionSize);2492}2493 2494void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,2495                                                  CharUnits BytePos,2496                                                  bool &HasUnion,2497                                                  bool ByrefLayout) {2498  const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();2499  SmallVector<const FieldDecl *, 16> Fields(RD->fields());2500  llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));2501  const llvm::StructLayout *RecLayout =2502      CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));2503 2504  BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);2505}2506 2507/// InlineLayoutInstruction - This routine produce an inline instruction for the2508/// block variable layout if it can. If not, it returns 0. Rules are as follow:2509/// If ((uintptr_t) layout) < (1 << 12), the layout is inline. In the 64bit2510/// world, an inline layout of value 0x0000000000000xyz is interpreted as2511/// follows: x captured object pointers of BLOCK_LAYOUT_STRONG. Followed by y2512/// captured object of BLOCK_LAYOUT_BYREF. Followed by z captured object of2513/// BLOCK_LAYOUT_WEAK. If any of the above is missing, zero replaces it. For2514/// example, 0x00000x00 means x BLOCK_LAYOUT_STRONG and no BLOCK_LAYOUT_BYREF2515/// and no BLOCK_LAYOUT_WEAK objects are captured.2516uint64_t CGObjCCommonMac::InlineLayoutInstruction(2517    SmallVectorImpl<unsigned char> &Layout) {2518  uint64_t Result = 0;2519  if (Layout.size() <= 3) {2520    unsigned size = Layout.size();2521    unsigned strong_word_count = 0, byref_word_count = 0, weak_word_count = 0;2522    unsigned char inst;2523    enum BLOCK_LAYOUT_OPCODE opcode;2524    switch (size) {2525    case 3:2526      inst = Layout[0];2527      opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);2528      if (opcode == BLOCK_LAYOUT_STRONG)2529        strong_word_count = (inst & 0xF) + 1;2530      else2531        return 0;2532      inst = Layout[1];2533      opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);2534      if (opcode == BLOCK_LAYOUT_BYREF)2535        byref_word_count = (inst & 0xF) + 1;2536      else2537        return 0;2538      inst = Layout[2];2539      opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);2540      if (opcode == BLOCK_LAYOUT_WEAK)2541        weak_word_count = (inst & 0xF) + 1;2542      else2543        return 0;2544      break;2545 2546    case 2:2547      inst = Layout[0];2548      opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);2549      if (opcode == BLOCK_LAYOUT_STRONG) {2550        strong_word_count = (inst & 0xF) + 1;2551        inst = Layout[1];2552        opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);2553        if (opcode == BLOCK_LAYOUT_BYREF)2554          byref_word_count = (inst & 0xF) + 1;2555        else if (opcode == BLOCK_LAYOUT_WEAK)2556          weak_word_count = (inst & 0xF) + 1;2557        else2558          return 0;2559      } else if (opcode == BLOCK_LAYOUT_BYREF) {2560        byref_word_count = (inst & 0xF) + 1;2561        inst = Layout[1];2562        opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);2563        if (opcode == BLOCK_LAYOUT_WEAK)2564          weak_word_count = (inst & 0xF) + 1;2565        else2566          return 0;2567      } else2568        return 0;2569      break;2570 2571    case 1:2572      inst = Layout[0];2573      opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);2574      if (opcode == BLOCK_LAYOUT_STRONG)2575        strong_word_count = (inst & 0xF) + 1;2576      else if (opcode == BLOCK_LAYOUT_BYREF)2577        byref_word_count = (inst & 0xF) + 1;2578      else if (opcode == BLOCK_LAYOUT_WEAK)2579        weak_word_count = (inst & 0xF) + 1;2580      else2581        return 0;2582      break;2583 2584    default:2585      return 0;2586    }2587 2588    // Cannot inline when any of the word counts is 15. Because this is one less2589    // than the actual work count (so 15 means 16 actual word counts),2590    // and we can only display 0 thru 15 word counts.2591    if (strong_word_count == 16 || byref_word_count == 16 ||2592        weak_word_count == 16)2593      return 0;2594 2595    unsigned count = (strong_word_count != 0) + (byref_word_count != 0) +2596                     (weak_word_count != 0);2597 2598    if (size == count) {2599      if (strong_word_count)2600        Result = strong_word_count;2601      Result <<= 4;2602      if (byref_word_count)2603        Result += byref_word_count;2604      Result <<= 4;2605      if (weak_word_count)2606        Result += weak_word_count;2607    }2608  }2609  return Result;2610}2611 2612llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {2613  llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);2614  if (RunSkipBlockVars.empty())2615    return nullPtr;2616  unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(LangAS::Default);2617  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();2618  unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;2619 2620  // Sort on byte position; captures might not be allocated in order,2621  // and unions can do funny things.2622  llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());2623  SmallVector<unsigned char, 16> Layout;2624 2625  unsigned size = RunSkipBlockVars.size();2626  for (unsigned i = 0; i < size; i++) {2627    enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;2628    CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;2629    CharUnits end_byte_pos = start_byte_pos;2630    unsigned j = i + 1;2631    while (j < size) {2632      if (opcode == RunSkipBlockVars[j].opcode) {2633        end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;2634        i++;2635      } else2636        break;2637    }2638    CharUnits size_in_bytes =2639        end_byte_pos - start_byte_pos + RunSkipBlockVars[j - 1].block_var_size;2640    if (j < size) {2641      CharUnits gap = RunSkipBlockVars[j].block_var_bytepos -2642                      RunSkipBlockVars[j - 1].block_var_bytepos -2643                      RunSkipBlockVars[j - 1].block_var_size;2644      size_in_bytes += gap;2645    }2646    CharUnits residue_in_bytes = CharUnits::Zero();2647    if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {2648      residue_in_bytes = size_in_bytes % WordSizeInBytes;2649      size_in_bytes -= residue_in_bytes;2650      opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;2651    }2652 2653    unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;2654    while (size_in_words >= 16) {2655      // Note that value in imm. is one less that the actual2656      // value. So, 0xf means 16 words follow!2657      unsigned char inst = (opcode << 4) | 0xf;2658      Layout.push_back(inst);2659      size_in_words -= 16;2660    }2661    if (size_in_words > 0) {2662      // Note that value in imm. is one less that the actual2663      // value. So, we subtract 1 away!2664      unsigned char inst = (opcode << 4) | (size_in_words - 1);2665      Layout.push_back(inst);2666    }2667    if (residue_in_bytes > CharUnits::Zero()) {2668      unsigned char inst = (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) |2669                           (residue_in_bytes.getQuantity() - 1);2670      Layout.push_back(inst);2671    }2672  }2673 2674  while (!Layout.empty()) {2675    unsigned char inst = Layout.back();2676    enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);2677    if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES ||2678        opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)2679      Layout.pop_back();2680    else2681      break;2682  }2683 2684  uint64_t Result = InlineLayoutInstruction(Layout);2685  if (Result != 0) {2686    // Block variable layout instruction has been inlined.2687    if (CGM.getLangOpts().ObjCGCBitmapPrint) {2688      if (ComputeByrefLayout)2689        printf("\n Inline BYREF variable layout: ");2690      else2691        printf("\n Inline block variable layout: ");2692      printf("0x0%" PRIx64 "", Result);2693      if (auto numStrong = (Result & 0xF00) >> 8)2694        printf(", BL_STRONG:%d", (int)numStrong);2695      if (auto numByref = (Result & 0x0F0) >> 4)2696        printf(", BL_BYREF:%d", (int)numByref);2697      if (auto numWeak = (Result & 0x00F) >> 0)2698        printf(", BL_WEAK:%d", (int)numWeak);2699      printf(", BL_OPERATOR:0\n");2700    }2701    return llvm::ConstantInt::get(CGM.IntPtrTy, Result);2702  }2703 2704  unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;2705  Layout.push_back(inst);2706  std::string BitMap;2707  for (unsigned char C : Layout)2708    BitMap += C;2709 2710  if (CGM.getLangOpts().ObjCGCBitmapPrint) {2711    if (ComputeByrefLayout)2712      printf("\n Byref variable layout: ");2713    else2714      printf("\n Block variable layout: ");2715    for (unsigned i = 0, e = BitMap.size(); i != e; i++) {2716      unsigned char inst = BitMap[i];2717      enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE)(inst >> 4);2718      unsigned delta = 1;2719      switch (opcode) {2720      case BLOCK_LAYOUT_OPERATOR:2721        printf("BL_OPERATOR:");2722        delta = 0;2723        break;2724      case BLOCK_LAYOUT_NON_OBJECT_BYTES:2725        printf("BL_NON_OBJECT_BYTES:");2726        break;2727      case BLOCK_LAYOUT_NON_OBJECT_WORDS:2728        printf("BL_NON_OBJECT_WORD:");2729        break;2730      case BLOCK_LAYOUT_STRONG:2731        printf("BL_STRONG:");2732        break;2733      case BLOCK_LAYOUT_BYREF:2734        printf("BL_BYREF:");2735        break;2736      case BLOCK_LAYOUT_WEAK:2737        printf("BL_WEAK:");2738        break;2739      case BLOCK_LAYOUT_UNRETAINED:2740        printf("BL_UNRETAINED:");2741        break;2742      }2743      // Actual value of word count is one more that what is in the imm.2744      // field of the instruction2745      printf("%d", (inst & 0xf) + delta);2746      if (i < e - 1)2747        printf(", ");2748      else2749        printf("\n");2750    }2751  }2752 2753  auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::ClassName,2754                                     /*ForceNonFragileABI=*/true,2755                                     /*NullTerminate=*/false);2756  return getConstantGEP(VMContext, Entry, 0, 0);2757}2758 2759static std::string getBlockLayoutInfoString(2760    const SmallVectorImpl<CGObjCCommonMac::RUN_SKIP> &RunSkipBlockVars,2761    bool HasCopyDisposeHelpers) {2762  std::string Str;2763  for (const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {2764    if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {2765      // Copy/dispose helpers don't have any information about2766      // __unsafe_unretained captures, so unconditionally concatenate a string.2767      Str += "u";2768    } else if (HasCopyDisposeHelpers) {2769      // Information about __strong, __weak, or byref captures has already been2770      // encoded into the names of the copy/dispose helpers. We have to add a2771      // string here only when the copy/dispose helpers aren't generated (which2772      // happens when the block is non-escaping).2773      continue;2774    } else {2775      switch (R.opcode) {2776      case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:2777        Str += "s";2778        break;2779      case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:2780        Str += "r";2781        break;2782      case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:2783        Str += "w";2784        break;2785      default:2786        continue;2787      }2788    }2789    Str += llvm::to_string(R.block_var_bytepos.getQuantity());2790    Str += "l" + llvm::to_string(R.block_var_size.getQuantity());2791  }2792  return Str;2793}2794 2795void CGObjCCommonMac::fillRunSkipBlockVars(CodeGenModule &CGM,2796                                           const CGBlockInfo &blockInfo) {2797  assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);2798 2799  RunSkipBlockVars.clear();2800  bool hasUnion = false;2801 2802  unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(LangAS::Default);2803  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();2804  unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;2805 2806  const BlockDecl *blockDecl = blockInfo.getBlockDecl();2807 2808  // Calculate the basic layout of the block structure.2809  const llvm::StructLayout *layout =2810      CGM.getDataLayout().getStructLayout(blockInfo.StructureType);2811 2812  // Ignore the optional 'this' capture: C++ objects are not assumed2813  // to be GC'ed.2814  if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero())2815    UpdateRunSkipBlockVars(false, Qualifiers::OCL_None,2816                           blockInfo.BlockHeaderForcedGapOffset,2817                           blockInfo.BlockHeaderForcedGapSize);2818  // Walk the captured variables.2819  for (const auto &CI : blockDecl->captures()) {2820    const VarDecl *variable = CI.getVariable();2821    QualType type = variable->getType();2822 2823    const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);2824 2825    // Ignore constant captures.2826    if (capture.isConstant())2827      continue;2828 2829    CharUnits fieldOffset =2830        CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));2831 2832    assert(!type->isArrayType() && "array variable should not be caught");2833    if (!CI.isByRef())2834      if (const auto *record = type->getAsCanonical<RecordType>()) {2835        BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);2836        continue;2837      }2838    CharUnits fieldSize;2839    if (CI.isByRef())2840      fieldSize = CharUnits::fromQuantity(WordSizeInBytes);2841    else2842      fieldSize = CGM.getContext().getTypeSizeInChars(type);2843    UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type, false),2844                           fieldOffset, fieldSize);2845  }2846}2847 2848llvm::Constant *2849CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,2850                                    const CGBlockInfo &blockInfo) {2851  fillRunSkipBlockVars(CGM, blockInfo);2852  return getBitmapBlockLayout(false);2853}2854 2855std::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM,2856                                                 const CGBlockInfo &blockInfo) {2857  fillRunSkipBlockVars(CGM, blockInfo);2858  return getBlockLayoutInfoString(RunSkipBlockVars, blockInfo.NeedsCopyDispose);2859}2860 2861llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,2862                                                  QualType T) {2863  assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);2864  assert(!T->isArrayType() && "__block array variable should not be caught");2865  CharUnits fieldOffset;2866  RunSkipBlockVars.clear();2867  bool hasUnion = false;2868  if (const auto *record = T->getAsCanonical<RecordType>()) {2869    BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,2870                                true /*ByrefLayout */);2871    llvm::Constant *Result = getBitmapBlockLayout(true);2872    if (isa<llvm::ConstantInt>(Result))2873      Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.Int8PtrTy);2874    return Result;2875  }2876  llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);2877  return nullPtr;2878}2879 2880llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,2881                                            const ObjCProtocolDecl *PD) {2882  // FIXME: I don't understand why gcc generates this, or where it is2883  // resolved. Investigate. Its also wasteful to look this up over and over.2884  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));2885 2886  return GetProtocolRef(PD);2887}2888 2889void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {2890  // FIXME: We shouldn't need this, the protocol decl should contain enough2891  // information to tell us whether this was a declaration or a definition.2892  DefinedProtocols.insert(PD->getIdentifier());2893 2894  // If we have generated a forward reference to this protocol, emit2895  // it now. Otherwise do nothing, the protocol objects are lazily2896  // emitted.2897  if (Protocols.count(PD->getIdentifier()))2898    GetOrEmitProtocol(PD);2899}2900 2901llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {2902  if (DefinedProtocols.count(PD->getIdentifier()))2903    return GetOrEmitProtocol(PD);2904 2905  return GetOrEmitProtocolRef(PD);2906}2907 2908llvm::Value *2909CGObjCCommonMac::EmitClassRefViaRuntime(CodeGenFunction &CGF,2910                                        const ObjCInterfaceDecl *ID,2911                                        ObjCCommonTypesHelper &ObjCTypes) {2912  llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();2913 2914  llvm::Value *className = CGF.CGM2915                               .GetAddrOfConstantCString(std::string(2916                                   ID->getObjCRuntimeNameAsString()))2917                               .getPointer();2918  ASTContext &ctx = CGF.CGM.getContext();2919  className = CGF.Builder.CreateBitCast(2920      className, CGF.ConvertType(ctx.getPointerType(ctx.CharTy.withConst())));2921  llvm::CallInst *call = CGF.Builder.CreateCall(lookUpClassFn, className);2922  call->setDoesNotThrow();2923  return call;2924}2925 2926/*2927// Objective-C 1.0 extensions2928struct _objc_protocol {2929struct _objc_protocol_extension *isa;2930char *protocol_name;2931struct _objc_protocol_list *protocol_list;2932struct _objc__method_prototype_list *instance_methods;2933struct _objc__method_prototype_list *class_methods2934};2935 2936See EmitProtocolExtension().2937*/2938llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {2939  llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];2940 2941  // Early exit if a defining object has already been generated.2942  if (Entry && Entry->hasInitializer())2943    return Entry;2944 2945  // Use the protocol definition, if there is one.2946  if (const ObjCProtocolDecl *Def = PD->getDefinition())2947    PD = Def;2948 2949  // FIXME: I don't understand why gcc generates this, or where it is2950  // resolved. Investigate. Its also wasteful to look this up over and over.2951  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));2952 2953  // Construct method lists.2954  auto methodLists = ProtocolMethodLists::get(PD);2955 2956  ConstantInitBuilder builder(CGM);2957  auto values = builder.beginStruct(ObjCTypes.ProtocolTy);2958  values.add(EmitProtocolExtension(PD, methodLists));2959  values.add(GetClassName(PD->getObjCRuntimeNameAsString()));2960  values.add(EmitProtocolList("OBJC_PROTOCOL_REFS_" + PD->getName(),2961                              PD->protocol_begin(), PD->protocol_end()));2962  values.add(methodLists.emitMethodList(2963      this, PD, ProtocolMethodLists::RequiredInstanceMethods));2964  values.add(methodLists.emitMethodList(2965      this, PD, ProtocolMethodLists::RequiredClassMethods));2966 2967  if (Entry) {2968    // Already created, update the initializer.2969    assert(Entry->hasPrivateLinkage());2970    values.finishAndSetAsInitializer(Entry);2971  } else {2972    Entry = values.finishAndCreateGlobal(2973        "OBJC_PROTOCOL_" + PD->getName(), CGM.getPointerAlign(),2974        /*constant*/ false, llvm::GlobalValue::PrivateLinkage);2975    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");2976 2977    Protocols[PD->getIdentifier()] = Entry;2978  }2979  CGM.addCompilerUsedGlobal(Entry);2980 2981  return Entry;2982}2983 2984llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {2985  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];2986 2987  if (!Entry) {2988    // We use the initializer as a marker of whether this is a forward2989    // reference or not. At module finalization we add the empty2990    // contents for protocols which were referenced but never defined.2991    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,2992                                     false, llvm::GlobalValue::PrivateLinkage,2993                                     nullptr, "OBJC_PROTOCOL_" + PD->getName());2994    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");2995    // FIXME: Is this necessary? Why only for protocol?2996    Entry->setAlignment(llvm::Align(4));2997  }2998 2999  return Entry;3000}3001 3002/*3003  struct _objc_protocol_extension {3004  uint32_t size;3005  struct objc_method_description_list *optional_instance_methods;3006  struct objc_method_description_list *optional_class_methods;3007  struct objc_property_list *instance_properties;3008  const char ** extendedMethodTypes;3009  struct objc_property_list *class_properties;3010  };3011*/3012llvm::Constant *3013CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,3014                                 const ProtocolMethodLists &methodLists) {3015  auto optInstanceMethods = methodLists.emitMethodList(3016      this, PD, ProtocolMethodLists::OptionalInstanceMethods);3017  auto optClassMethods = methodLists.emitMethodList(3018      this, PD, ProtocolMethodLists::OptionalClassMethods);3019 3020  auto extendedMethodTypes = EmitProtocolMethodTypes(3021      "OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),3022      methodLists.emitExtendedTypesArray(this), ObjCTypes);3023 3024  auto instanceProperties = EmitPropertyList(3025      "OBJC_$_PROP_PROTO_LIST_" + PD->getName(), nullptr, PD, ObjCTypes, false);3026  auto classProperties =3027      EmitPropertyList("OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->getName(), nullptr,3028                       PD, ObjCTypes, true);3029 3030  // Return null if no extension bits are used.3031  if (optInstanceMethods->isNullValue() && optClassMethods->isNullValue() &&3032      extendedMethodTypes->isNullValue() && instanceProperties->isNullValue() &&3033      classProperties->isNullValue()) {3034    return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);3035  }3036 3037  uint64_t size =3038      CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);3039 3040  ConstantInitBuilder builder(CGM);3041  auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);3042  values.addInt(ObjCTypes.IntTy, size);3043  values.add(optInstanceMethods);3044  values.add(optClassMethods);3045  values.add(instanceProperties);3046  values.add(extendedMethodTypes);3047  values.add(classProperties);3048 3049  // No special section, but goes in llvm.used3050  return CreateMetadataVar("_OBJC_PROTOCOLEXT_" + PD->getName(), values,3051                           StringRef(), CGM.getPointerAlign(), true);3052}3053 3054/*3055  struct objc_protocol_list {3056    struct objc_protocol_list *next;3057    long count;3058    Protocol *list[];3059  };3060*/3061llvm::Constant *3062CGObjCMac::EmitProtocolList(Twine name,3063                            ObjCProtocolDecl::protocol_iterator begin,3064                            ObjCProtocolDecl::protocol_iterator end) {3065  // Just return null for empty protocol lists3066  auto PDs = GetRuntimeProtocolList(begin, end);3067  if (PDs.empty())3068    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);3069 3070  ConstantInitBuilder builder(CGM);3071  auto values = builder.beginStruct();3072 3073  // This field is only used by the runtime.3074  values.addNullPointer(ObjCTypes.ProtocolListPtrTy);3075 3076  // Reserve a slot for the count.3077  auto countSlot = values.addPlaceholder();3078 3079  auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);3080  for (const auto *Proto : PDs)3081    refsArray.add(GetProtocolRef(Proto));3082 3083  auto count = refsArray.size();3084 3085  // This list is null terminated.3086  refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);3087 3088  refsArray.finishAndAddTo(values);3089  values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);3090 3091  StringRef section;3092  if (CGM.getTriple().isOSBinFormatMachO())3093    section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";3094 3095  llvm::GlobalVariable *GV =3096      CreateMetadataVar(name, values, section, CGM.getPointerAlign(), false);3097  return GV;3098}3099 3100static void PushProtocolProperties(3101    llvm::SmallPtrSet<const IdentifierInfo *, 16> &PropertySet,3102    SmallVectorImpl<const ObjCPropertyDecl *> &Properties,3103    const ObjCProtocolDecl *Proto, bool IsClassProperty) {3104  for (const auto *PD : Proto->properties()) {3105    if (IsClassProperty != PD->isClassProperty())3106      continue;3107    if (!PropertySet.insert(PD->getIdentifier()).second)3108      continue;3109    Properties.push_back(PD);3110  }3111 3112  for (const auto *P : Proto->protocols())3113    PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);3114}3115 3116/*3117  struct _objc_property {3118    const char * const name;3119    const char * const attributes;3120  };3121 3122  struct _objc_property_list {3123    uint32_t entsize; // sizeof (struct _objc_property)3124    uint32_t prop_count;3125    struct _objc_property[prop_count];3126  };3127*/3128llvm::Constant *CGObjCCommonMac::EmitPropertyList(3129    Twine Name, const Decl *Container, const ObjCContainerDecl *OCD,3130    const ObjCCommonTypesHelper &ObjCTypes, bool IsClassProperty) {3131  if (IsClassProperty) {3132    // Make this entry NULL for OS X with deployment target < 10.11, for iOS3133    // with deployment target < 9.0.3134    const llvm::Triple &Triple = CGM.getTarget().getTriple();3135    if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||3136        (Triple.isiOS() && Triple.isOSVersionLT(9)))3137      return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);3138  }3139 3140  SmallVector<const ObjCPropertyDecl *, 16> Properties;3141  llvm::SmallPtrSet<const IdentifierInfo *, 16> PropertySet;3142 3143  if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))3144    for (const ObjCCategoryDecl *ClassExt : OID->known_extensions())3145      for (auto *PD : ClassExt->properties()) {3146        if (IsClassProperty != PD->isClassProperty())3147          continue;3148        if (PD->isDirectProperty())3149          continue;3150        PropertySet.insert(PD->getIdentifier());3151        Properties.push_back(PD);3152      }3153 3154  for (const auto *PD : OCD->properties()) {3155    if (IsClassProperty != PD->isClassProperty())3156      continue;3157    // Don't emit duplicate metadata for properties that were already in a3158    // class extension.3159    if (!PropertySet.insert(PD->getIdentifier()).second)3160      continue;3161    if (PD->isDirectProperty())3162      continue;3163    Properties.push_back(PD);3164  }3165 3166  if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {3167    for (const auto *P : OID->all_referenced_protocols())3168      PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);3169  } else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {3170    for (const auto *P : CD->protocols())3171      PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);3172  }3173 3174  // Return null for empty list.3175  if (Properties.empty())3176    return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);3177 3178  unsigned propertySize =3179      CGM.getDataLayout().getTypeAllocSize(ObjCTypes.PropertyTy);3180 3181  ConstantInitBuilder builder(CGM);3182  auto values = builder.beginStruct();3183  values.addInt(ObjCTypes.IntTy, propertySize);3184  values.addInt(ObjCTypes.IntTy, Properties.size());3185  auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);3186  for (auto PD : Properties) {3187    auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);3188    property.add(GetPropertyName(PD->getIdentifier()));3189    property.add(GetPropertyTypeString(PD, Container));3190    property.finishAndAddTo(propertiesArray);3191  }3192  propertiesArray.finishAndAddTo(values);3193 3194  StringRef Section;3195  if (CGM.getTriple().isOSBinFormatMachO())3196    Section = (ObjCABI == 2) ? "__DATA, __objc_const"3197                             : "__OBJC,__property,regular,no_dead_strip";3198 3199  llvm::GlobalVariable *GV =3200      CreateMetadataVar(Name, values, Section, CGM.getPointerAlign(), true);3201  return GV;3202}3203 3204llvm::Constant *CGObjCCommonMac::EmitProtocolMethodTypes(3205    Twine Name, ArrayRef<llvm::Constant *> MethodTypes,3206    const ObjCCommonTypesHelper &ObjCTypes) {3207  // Return null for empty list.3208  if (MethodTypes.empty())3209    return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);3210 3211  llvm::ArrayType *AT =3212      llvm::ArrayType::get(ObjCTypes.Int8PtrTy, MethodTypes.size());3213  llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);3214 3215  StringRef Section;3216  if (CGM.getTriple().isOSBinFormatMachO() && ObjCABI == 2)3217    Section = "__DATA, __objc_const";3218 3219  llvm::GlobalVariable *GV =3220      CreateMetadataVar(Name, Init, Section, CGM.getPointerAlign(), true);3221  return GV;3222}3223 3224/*3225  struct _objc_category {3226  char *category_name;3227  char *class_name;3228  struct _objc_method_list *instance_methods;3229  struct _objc_method_list *class_methods;3230  struct _objc_protocol_list *protocols;3231  uint32_t size; // sizeof(struct _objc_category)3232  struct _objc_property_list *instance_properties;3233  struct _objc_property_list *class_properties;3234  };3235*/3236void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {3237  unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);3238 3239  // FIXME: This is poor design, the OCD should have a pointer to the category3240  // decl. Additionally, note that Category can be null for the @implementation3241  // w/o an @interface case. Sema should just create one for us as it does for3242  // @implementation so everyone else can live life under a clear blue sky.3243  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();3244  const ObjCCategoryDecl *Category =3245      Interface->FindCategoryDeclaration(OCD->getIdentifier());3246 3247  SmallString<256> ExtName;3248  llvm::raw_svector_ostream(ExtName)3249      << Interface->getName() << '_' << OCD->getName();3250 3251  ConstantInitBuilder Builder(CGM);3252  auto Values = Builder.beginStruct(ObjCTypes.CategoryTy);3253 3254  enum { InstanceMethods, ClassMethods, NumMethodLists };3255  SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];3256  for (const auto *MD : OCD->methods()) {3257    if (!MD->isDirectMethod())3258      Methods[unsigned(MD->isClassMethod())].push_back(MD);3259  }3260 3261  Values.add(GetClassName(OCD->getName()));3262  Values.add(GetClassName(Interface->getObjCRuntimeNameAsString()));3263  LazySymbols.insert(Interface->getIdentifier());3264 3265  Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,3266                            Methods[InstanceMethods]));3267  Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,3268                            Methods[ClassMethods]));3269  if (Category) {3270    Values.add(EmitProtocolList("OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),3271                                Category->protocol_begin(),3272                                Category->protocol_end()));3273  } else {3274    Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);3275  }3276  Values.addInt(ObjCTypes.IntTy, Size);3277 3278  // If there is no category @interface then there can be no properties.3279  if (Category) {3280    Values.add(EmitPropertyList("_OBJC_$_PROP_LIST_" + ExtName.str(), OCD,3281                                Category, ObjCTypes, false));3282    Values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), OCD,3283                                Category, ObjCTypes, true));3284  } else {3285    Values.addNullPointer(ObjCTypes.PropertyListPtrTy);3286    Values.addNullPointer(ObjCTypes.PropertyListPtrTy);3287  }3288 3289  llvm::GlobalVariable *GV = CreateMetadataVar(3290      "OBJC_CATEGORY_" + ExtName.str(), Values,3291      "__OBJC,__category,regular,no_dead_strip", CGM.getPointerAlign(), true);3292  DefinedCategories.push_back(GV);3293  DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));3294  // method definition entries must be clear for next implementation.3295  MethodDefinitions.clear();3296}3297 3298// clang-format off3299enum FragileClassFlags {3300  /// Apparently: is not a meta-class.3301  FragileABI_Class_Factory                 = 0x00001,3302 3303  /// Is a meta-class.3304  FragileABI_Class_Meta                    = 0x00002,3305 3306  /// Has a non-trivial constructor or destructor.3307  FragileABI_Class_HasCXXStructors         = 0x02000,3308 3309  /// Has hidden visibility.3310  FragileABI_Class_Hidden                  = 0x20000,3311 3312  /// Class implementation was compiled under ARC.3313  FragileABI_Class_CompiledByARC           = 0x04000000,3314 3315  /// Class implementation was compiled under MRC and has MRC weak ivars.3316  /// Exclusive with CompiledByARC.3317  FragileABI_Class_HasMRCWeakIvars         = 0x08000000,3318};3319 3320enum NonFragileClassFlags {3321  /// Is a meta-class.3322  NonFragileABI_Class_Meta                 = 0x00001,3323 3324  /// Is a root class.3325  NonFragileABI_Class_Root                 = 0x00002,3326 3327  /// Has a non-trivial constructor or destructor.3328  NonFragileABI_Class_HasCXXStructors      = 0x00004,3329 3330  /// Has hidden visibility.3331  NonFragileABI_Class_Hidden               = 0x00010,3332 3333  /// Has the exception attribute.3334  NonFragileABI_Class_Exception            = 0x00020,3335 3336  /// (Obsolete) ARC-specific: this class has a .release_ivars method3337  NonFragileABI_Class_HasIvarReleaser      = 0x00040,3338 3339  /// Class implementation was compiled under ARC.3340  NonFragileABI_Class_CompiledByARC        = 0x00080,3341 3342  /// Class has non-trivial destructors, but zero-initialization is okay.3343  NonFragileABI_Class_HasCXXDestructorOnly = 0x00100,3344 3345  /// Class implementation was compiled under MRC and has MRC weak ivars.3346  /// Exclusive with CompiledByARC.3347  NonFragileABI_Class_HasMRCWeakIvars      = 0x00200,3348};3349// clang-format on3350 3351static bool hasWeakMember(QualType type) {3352  if (type.getObjCLifetime() == Qualifiers::OCL_Weak) {3353    return true;3354  }3355 3356  if (auto *RD = type->getAsRecordDecl()) {3357    for (auto *field : RD->fields()) {3358      if (hasWeakMember(field->getType()))3359        return true;3360    }3361  }3362 3363  return false;3364}3365 3366/// For compatibility, we only want to set the "HasMRCWeakIvars" flag3367/// (and actually fill in a layout string) if we really do have any3368/// __weak ivars.3369static bool hasMRCWeakIvars(CodeGenModule &CGM,3370                            const ObjCImplementationDecl *ID) {3371  if (!CGM.getLangOpts().ObjCWeak)3372    return false;3373  assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);3374 3375  for (const ObjCIvarDecl *ivar =3376           ID->getClassInterface()->all_declared_ivar_begin();3377       ivar; ivar = ivar->getNextIvar()) {3378    if (hasWeakMember(ivar->getType()))3379      return true;3380  }3381 3382  return false;3383}3384 3385/*3386  struct _objc_class {3387  Class isa;3388  Class super_class;3389  const char *name;3390  long version;3391  long info;3392  long instance_size;3393  struct _objc_ivar_list *ivars;3394  struct _objc_method_list *methods;3395  struct _objc_cache *cache;3396  struct _objc_protocol_list *protocols;3397  // Objective-C 1.0 extensions (<rdr://4585769>)3398  const char *ivar_layout;3399  struct _objc_class_ext *ext;3400  };3401 3402  See EmitClassExtension();3403*/3404void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {3405  IdentifierInfo *RuntimeName =3406      &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());3407  DefinedSymbols.insert(RuntimeName);3408 3409  std::string ClassName = ID->getNameAsString();3410  // FIXME: Gross3411  ObjCInterfaceDecl *Interface =3412      const_cast<ObjCInterfaceDecl *>(ID->getClassInterface());3413  llvm::Constant *Protocols =3414      EmitProtocolList("OBJC_CLASS_PROTOCOLS_" + ID->getName(),3415                       Interface->all_referenced_protocol_begin(),3416                       Interface->all_referenced_protocol_end());3417  unsigned Flags = FragileABI_Class_Factory;3418  if (ID->hasNonZeroConstructors() || ID->hasDestructors())3419    Flags |= FragileABI_Class_HasCXXStructors;3420 3421  bool hasMRCWeak = false;3422 3423  if (CGM.getLangOpts().ObjCAutoRefCount)3424    Flags |= FragileABI_Class_CompiledByARC;3425  else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))3426    Flags |= FragileABI_Class_HasMRCWeakIvars;3427 3428  CharUnits Size = CGM.getContext()3429                       .getASTObjCInterfaceLayout(ID->getClassInterface())3430                       .getSize();3431 3432  // FIXME: Set CXX-structors flag.3433  if (ID->getClassInterface()->getVisibility() == HiddenVisibility)3434    Flags |= FragileABI_Class_Hidden;3435 3436  enum { InstanceMethods, ClassMethods, NumMethodLists };3437  SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];3438  for (const auto *MD : ID->methods()) {3439    if (!MD->isDirectMethod())3440      Methods[unsigned(MD->isClassMethod())].push_back(MD);3441  }3442 3443  for (const auto *PID : ID->property_impls()) {3444    if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {3445      if (PID->getPropertyDecl()->isDirectProperty())3446        continue;3447      if (ObjCMethodDecl *MD = PID->getGetterMethodDecl())3448        if (GetMethodDefinition(MD))3449          Methods[InstanceMethods].push_back(MD);3450      if (ObjCMethodDecl *MD = PID->getSetterMethodDecl())3451        if (GetMethodDefinition(MD))3452          Methods[InstanceMethods].push_back(MD);3453    }3454  }3455 3456  ConstantInitBuilder builder(CGM);3457  auto values = builder.beginStruct(ObjCTypes.ClassTy);3458  values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));3459  if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {3460    // Record a reference to the super class.3461    LazySymbols.insert(Super->getIdentifier());3462 3463    values.add(GetClassName(Super->getObjCRuntimeNameAsString()));3464  } else {3465    values.addNullPointer(ObjCTypes.ClassPtrTy);3466  }3467  values.add(GetClassName(ID->getObjCRuntimeNameAsString()));3468  // Version is always 0.3469  values.addInt(ObjCTypes.LongTy, 0);3470  values.addInt(ObjCTypes.LongTy, Flags);3471  values.addInt(ObjCTypes.LongTy, Size.getQuantity());3472  values.add(EmitIvarList(ID, false));3473  values.add(emitMethodList(ID->getName(), MethodListType::InstanceMethods,3474                            Methods[InstanceMethods]));3475  // cache is always NULL.3476  values.addNullPointer(ObjCTypes.CachePtrTy);3477  values.add(Protocols);3478  values.add(BuildStrongIvarLayout(ID, CharUnits::Zero(), Size));3479  values.add(EmitClassExtension(ID, Size, hasMRCWeak,3480                                /*isMetaclass*/ false));3481 3482  std::string Name("OBJC_CLASS_");3483  Name += ClassName;3484  const char *Section = "__OBJC,__class,regular,no_dead_strip";3485  // Check for a forward reference.3486  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);3487  if (GV) {3488    assert(GV->getValueType() == ObjCTypes.ClassTy &&3489           "Forward metaclass reference has incorrect type.");3490    values.finishAndSetAsInitializer(GV);3491    GV->setSection(Section);3492    GV->setAlignment(CGM.getPointerAlign().getAsAlign());3493    CGM.addCompilerUsedGlobal(GV);3494  } else3495    GV = CreateMetadataVar(Name, values, Section, CGM.getPointerAlign(), true);3496  DefinedClasses.push_back(GV);3497  ImplementedClasses.push_back(Interface);3498  // method definition entries must be clear for next implementation.3499  MethodDefinitions.clear();3500}3501 3502llvm::Constant *3503CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,3504                         llvm::Constant *Protocols,3505                         ArrayRef<const ObjCMethodDecl *> Methods) {3506  unsigned Flags = FragileABI_Class_Meta;3507  unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);3508 3509  if (ID->getClassInterface()->getVisibility() == HiddenVisibility)3510    Flags |= FragileABI_Class_Hidden;3511 3512  ConstantInitBuilder builder(CGM);3513  auto values = builder.beginStruct(ObjCTypes.ClassTy);3514  // The isa for the metaclass is the root of the hierarchy.3515  const ObjCInterfaceDecl *Root = ID->getClassInterface();3516  while (const ObjCInterfaceDecl *Super = Root->getSuperClass())3517    Root = Super;3518  values.add(GetClassName(Root->getObjCRuntimeNameAsString()));3519  // The super class for the metaclass is emitted as the name of the3520  // super class. The runtime fixes this up to point to the3521  // *metaclass* for the super class.3522  if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {3523    values.add(GetClassName(Super->getObjCRuntimeNameAsString()));3524  } else {3525    values.addNullPointer(ObjCTypes.ClassPtrTy);3526  }3527  values.add(GetClassName(ID->getObjCRuntimeNameAsString()));3528  // Version is always 0.3529  values.addInt(ObjCTypes.LongTy, 0);3530  values.addInt(ObjCTypes.LongTy, Flags);3531  values.addInt(ObjCTypes.LongTy, Size);3532  values.add(EmitIvarList(ID, true));3533  values.add(3534      emitMethodList(ID->getName(), MethodListType::ClassMethods, Methods));3535  // cache is always NULL.3536  values.addNullPointer(ObjCTypes.CachePtrTy);3537  values.add(Protocols);3538  // ivar_layout for metaclass is always NULL.3539  values.addNullPointer(ObjCTypes.Int8PtrTy);3540  // The class extension is used to store class properties for metaclasses.3541  values.add(EmitClassExtension(ID, CharUnits::Zero(), false /*hasMRCWeak*/,3542                                /*isMetaclass*/ true));3543 3544  std::string Name("OBJC_METACLASS_");3545  Name += ID->getName();3546 3547  // Check for a forward reference.3548  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);3549  if (GV) {3550    assert(GV->getValueType() == ObjCTypes.ClassTy &&3551           "Forward metaclass reference has incorrect type.");3552    values.finishAndSetAsInitializer(GV);3553  } else {3554    GV = values.finishAndCreateGlobal(Name, CGM.getPointerAlign(),3555                                      /*constant*/ false,3556                                      llvm::GlobalValue::PrivateLinkage);3557  }3558  GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");3559  CGM.addCompilerUsedGlobal(GV);3560 3561  return GV;3562}3563 3564llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {3565  std::string Name = "OBJC_METACLASS_" + ID->getNameAsString();3566 3567  // FIXME: Should we look these up somewhere other than the module. Its a bit3568  // silly since we only generate these while processing an implementation, so3569  // exactly one pointer would work if know when we entered/exitted an3570  // implementation block.3571 3572  // Check for an existing forward reference.3573  // Previously, metaclass with internal linkage may have been defined.3574  // pass 'true' as 2nd argument so it is returned.3575  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);3576  if (!GV)3577    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,3578                                  llvm::GlobalValue::PrivateLinkage, nullptr,3579                                  Name);3580 3581  assert(GV->getValueType() == ObjCTypes.ClassTy &&3582         "Forward metaclass reference has incorrect type.");3583  return GV;3584}3585 3586llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {3587  std::string Name = "OBJC_CLASS_" + ID->getNameAsString();3588  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);3589 3590  if (!GV)3591    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,3592                                  llvm::GlobalValue::PrivateLinkage, nullptr,3593                                  Name);3594 3595  assert(GV->getValueType() == ObjCTypes.ClassTy &&3596         "Forward class metadata reference has incorrect type.");3597  return GV;3598}3599 3600/*3601  Emit a "class extension", which in this specific context means extra3602  data that doesn't fit in the normal fragile-ABI class structure, and3603  has nothing to do with the language concept of a class extension.3604 3605  struct objc_class_ext {3606  uint32_t size;3607  const char *weak_ivar_layout;3608  struct _objc_property_list *properties;3609  };3610*/3611llvm::Constant *CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID,3612                                              CharUnits InstanceSize,3613                                              bool hasMRCWeakIvars,3614                                              bool isMetaclass) {3615  // Weak ivar layout.3616  llvm::Constant *layout;3617  if (isMetaclass) {3618    layout = llvm::ConstantPointerNull::get(CGM.Int8PtrTy);3619  } else {3620    layout = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize,3621                                 hasMRCWeakIvars);3622  }3623 3624  // Properties.3625  llvm::Constant *propertyList =3626      EmitPropertyList((isMetaclass ? Twine("_OBJC_$_CLASS_PROP_LIST_")3627                                    : Twine("_OBJC_$_PROP_LIST_")) +3628                           ID->getName(),3629                       ID, ID->getClassInterface(), ObjCTypes, isMetaclass);3630 3631  // Return null if no extension bits are used.3632  if (layout->isNullValue() && propertyList->isNullValue()) {3633    return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);3634  }3635 3636  uint64_t size =3637      CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);3638 3639  ConstantInitBuilder builder(CGM);3640  auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);3641  values.addInt(ObjCTypes.IntTy, size);3642  values.add(layout);3643  values.add(propertyList);3644 3645  return CreateMetadataVar("OBJC_CLASSEXT_" + ID->getName(), values,3646                           "__OBJC,__class_ext,regular,no_dead_strip",3647                           CGM.getPointerAlign(), true);3648}3649 3650/*3651  struct objc_ivar {3652    char *ivar_name;3653    char *ivar_type;3654    int ivar_offset;3655  };3656 3657  struct objc_ivar_list {3658    int ivar_count;3659    struct objc_ivar list[count];3660  };3661*/3662llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,3663                                        bool ForClass) {3664  // When emitting the root class GCC emits ivar entries for the3665  // actual class structure. It is not clear if we need to follow this3666  // behavior; for now lets try and get away with not doing it. If so,3667  // the cleanest solution would be to make up an ObjCInterfaceDecl3668  // for the class.3669  if (ForClass)3670    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);3671 3672  const ObjCInterfaceDecl *OID = ID->getClassInterface();3673 3674  ConstantInitBuilder builder(CGM);3675  auto ivarList = builder.beginStruct();3676  auto countSlot = ivarList.addPlaceholder();3677  auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);3678 3679  for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;3680       IVD = IVD->getNextIvar()) {3681    // Ignore unnamed bit-fields.3682    if (!IVD->getDeclName())3683      continue;3684 3685    auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);3686    ivar.add(GetMethodVarName(IVD->getIdentifier()));3687    ivar.add(GetMethodVarType(IVD));3688    ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));3689    ivar.finishAndAddTo(ivars);3690  }3691 3692  // Return null for empty list.3693  auto count = ivars.size();3694  if (count == 0) {3695    ivars.abandon();3696    ivarList.abandon();3697    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);3698  }3699 3700  ivars.finishAndAddTo(ivarList);3701  ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);3702 3703  llvm::GlobalVariable *GV;3704  GV = CreateMetadataVar("OBJC_INSTANCE_VARIABLES_" + ID->getName(), ivarList,3705                         "__OBJC,__instance_vars,regular,no_dead_strip",3706                         CGM.getPointerAlign(), true);3707  return GV;3708}3709 3710/// Build a struct objc_method_description constant for the given method.3711///3712/// struct objc_method_description {3713///   SEL method_name;3714///   char *method_types;3715/// };3716void CGObjCMac::emitMethodDescriptionConstant(ConstantArrayBuilder &builder,3717                                              const ObjCMethodDecl *MD) {3718  auto description = builder.beginStruct(ObjCTypes.MethodDescriptionTy);3719  description.add(GetMethodVarName(MD->getSelector()));3720  description.add(GetMethodVarType(MD));3721  description.finishAndAddTo(builder);3722}3723 3724/// Build a struct objc_method constant for the given method.3725///3726/// struct objc_method {3727///   SEL method_name;3728///   char *method_types;3729///   void *method;3730/// };3731void CGObjCMac::emitMethodConstant(ConstantArrayBuilder &builder,3732                                   const ObjCMethodDecl *MD) {3733  llvm::Function *fn = GetMethodDefinition(MD);3734  assert(fn && "no definition registered for method");3735 3736  auto method = builder.beginStruct(ObjCTypes.MethodTy);3737  method.add(GetMethodVarName(MD->getSelector()));3738  method.add(GetMethodVarType(MD));3739  method.add(fn);3740  method.finishAndAddTo(builder);3741}3742 3743/// Build a struct objc_method_list or struct objc_method_description_list,3744/// as appropriate.3745///3746/// struct objc_method_list {3747///   struct objc_method_list *obsolete;3748///   int count;3749///   struct objc_method methods_list[count];3750/// };3751///3752/// struct objc_method_description_list {3753///   int count;3754///   struct objc_method_description list[count];3755/// };3756llvm::Constant *3757CGObjCMac::emitMethodList(Twine name, MethodListType MLT,3758                          ArrayRef<const ObjCMethodDecl *> methods) {3759  StringRef prefix;3760  StringRef section;3761  bool forProtocol = false;3762  switch (MLT) {3763  case MethodListType::CategoryInstanceMethods:3764    prefix = "OBJC_CATEGORY_INSTANCE_METHODS_";3765    section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";3766    forProtocol = false;3767    break;3768  case MethodListType::CategoryClassMethods:3769    prefix = "OBJC_CATEGORY_CLASS_METHODS_";3770    section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";3771    forProtocol = false;3772    break;3773  case MethodListType::InstanceMethods:3774    prefix = "OBJC_INSTANCE_METHODS_";3775    section = "__OBJC,__inst_meth,regular,no_dead_strip";3776    forProtocol = false;3777    break;3778  case MethodListType::ClassMethods:3779    prefix = "OBJC_CLASS_METHODS_";3780    section = "__OBJC,__cls_meth,regular,no_dead_strip";3781    forProtocol = false;3782    break;3783  case MethodListType::ProtocolInstanceMethods:3784    prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_";3785    section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";3786    forProtocol = true;3787    break;3788  case MethodListType::ProtocolClassMethods:3789    prefix = "OBJC_PROTOCOL_CLASS_METHODS_";3790    section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";3791    forProtocol = true;3792    break;3793  case MethodListType::OptionalProtocolInstanceMethods:3794    prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";3795    section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";3796    forProtocol = true;3797    break;3798  case MethodListType::OptionalProtocolClassMethods:3799    prefix = "OBJC_PROTOCOL_CLASS_METHODS_OPT_";3800    section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";3801    forProtocol = true;3802    break;3803  }3804 3805  // Return null for empty list.3806  if (methods.empty())3807    return llvm::Constant::getNullValue(3808        forProtocol ? ObjCTypes.MethodDescriptionListPtrTy3809                    : ObjCTypes.MethodListPtrTy);3810 3811  // For protocols, this is an objc_method_description_list, which has3812  // a slightly different structure.3813  if (forProtocol) {3814    ConstantInitBuilder builder(CGM);3815    auto values = builder.beginStruct();3816    values.addInt(ObjCTypes.IntTy, methods.size());3817    auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);3818    for (auto MD : methods) {3819      emitMethodDescriptionConstant(methodArray, MD);3820    }3821    methodArray.finishAndAddTo(values);3822 3823    llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,3824                                                 CGM.getPointerAlign(), true);3825    return GV;3826  }3827 3828  // Otherwise, it's an objc_method_list.3829  ConstantInitBuilder builder(CGM);3830  auto values = builder.beginStruct();3831  values.addNullPointer(ObjCTypes.Int8PtrTy);3832  values.addInt(ObjCTypes.IntTy, methods.size());3833  auto methodArray = values.beginArray(ObjCTypes.MethodTy);3834  for (auto MD : methods) {3835    if (!MD->isDirectMethod())3836      emitMethodConstant(methodArray, MD);3837  }3838  methodArray.finishAndAddTo(values);3839 3840  llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,3841                                               CGM.getPointerAlign(), true);3842  return GV;3843}3844 3845llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,3846                                                const ObjCContainerDecl *CD) {3847  llvm::Function *Method;3848 3849  if (OMD->isDirectMethod()) {3850    Method = GenerateDirectMethod(OMD, CD);3851  } else {3852    auto Name = getSymbolNameForMethod(OMD);3853 3854    CodeGenTypes &Types = CGM.getTypes();3855    llvm::FunctionType *MethodTy =3856        Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));3857    Method = llvm::Function::Create(3858        MethodTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.getModule());3859  }3860 3861  MethodDefinitions.insert(std::make_pair(OMD, Method));3862 3863  return Method;3864}3865 3866llvm::Function *3867CGObjCCommonMac::GenerateDirectMethod(const ObjCMethodDecl *OMD,3868                                      const ObjCContainerDecl *CD) {3869  auto *COMD = OMD->getCanonicalDecl();3870  auto I = DirectMethodDefinitions.find(COMD);3871  llvm::Function *OldFn = nullptr, *Fn = nullptr;3872 3873  if (I != DirectMethodDefinitions.end()) {3874    // Objective-C allows for the declaration and implementation types3875    // to differ slightly.3876    //3877    // If we're being asked for the Function associated for a method3878    // implementation, a previous value might have been cached3879    // based on the type of the canonical declaration.3880    //3881    // If these do not match, then we'll replace this function with3882    // a new one that has the proper type below.3883    if (!OMD->getBody() || COMD->getReturnType() == OMD->getReturnType())3884      return I->second;3885    OldFn = I->second;3886  }3887 3888  CodeGenTypes &Types = CGM.getTypes();3889  llvm::FunctionType *MethodTy =3890      Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));3891 3892  if (OldFn) {3893    Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,3894                                "", &CGM.getModule());3895    Fn->takeName(OldFn);3896    OldFn->replaceAllUsesWith(Fn);3897    OldFn->eraseFromParent();3898 3899    // Replace the cached function in the map.3900    I->second = Fn;3901  } else {3902    auto Name = getSymbolNameForMethod(OMD, /*include category*/ false);3903 3904    Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,3905                                Name, &CGM.getModule());3906    DirectMethodDefinitions.insert(std::make_pair(COMD, Fn));3907  }3908 3909  return Fn;3910}3911 3912void CGObjCCommonMac::GenerateDirectMethodPrologue(3913    CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD,3914    const ObjCContainerDecl *CD) {3915  auto &Builder = CGF.Builder;3916  bool ReceiverCanBeNull = true;3917  auto selfAddr = CGF.GetAddrOfLocalVar(OMD->getSelfDecl());3918  auto selfValue = Builder.CreateLoad(selfAddr);3919 3920  // Generate:3921  //3922  // /* for class methods only to force class lazy initialization */3923  // self = [self self];3924  //3925  // /* unless the receiver is never NULL */3926  // if (self == nil) {3927  //     return (ReturnType){ };3928  // }3929  //3930  // _cmd = @selector(...)3931  // ...3932 3933  if (OMD->isClassMethod()) {3934    const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(CD);3935    assert(OID &&3936           "GenerateDirectMethod() should be called with the Class Interface");3937    Selector SelfSel = GetNullarySelector("self", CGM.getContext());3938    auto ResultType = CGF.getContext().getObjCIdType();3939    RValue result;3940    CallArgList Args;3941 3942    // TODO: If this method is inlined, the caller might know that `self` is3943    // already initialized; for example, it might be an ordinary Objective-C3944    // method which always receives an initialized `self`, or it might have just3945    // forced initialization on its own.3946    //3947    // We should find a way to eliminate this unnecessary initialization in such3948    // cases in LLVM.3949    result = GeneratePossiblySpecializedMessageSend(3950        CGF, ReturnValueSlot(), ResultType, SelfSel, selfValue, Args, OID,3951        nullptr, true);3952    Builder.CreateStore(result.getScalarVal(), selfAddr);3953 3954    // Nullable `Class` expressions cannot be messaged with a direct method3955    // so the only reason why the receive can be null would be because3956    // of weak linking.3957    ReceiverCanBeNull = isWeakLinkedClass(OID);3958  }3959 3960  if (ReceiverCanBeNull) {3961    llvm::BasicBlock *SelfIsNilBlock =3962        CGF.createBasicBlock("objc_direct_method.self_is_nil");3963    llvm::BasicBlock *ContBlock =3964        CGF.createBasicBlock("objc_direct_method.cont");3965 3966    // if (self == nil) {3967    auto selfTy = cast<llvm::PointerType>(selfValue->getType());3968    auto Zero = llvm::ConstantPointerNull::get(selfTy);3969 3970    llvm::MDBuilder MDHelper(CGM.getLLVMContext());3971    Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero), SelfIsNilBlock,3972                         ContBlock, MDHelper.createUnlikelyBranchWeights());3973 3974    CGF.EmitBlock(SelfIsNilBlock);3975 3976    //   return (ReturnType){ };3977    auto retTy = OMD->getReturnType();3978    Builder.SetInsertPoint(SelfIsNilBlock);3979    if (!retTy->isVoidType()) {3980      CGF.EmitNullInitialization(CGF.ReturnValue, retTy);3981    }3982    CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);3983    // }3984 3985    // rest of the body3986    CGF.EmitBlock(ContBlock);3987    Builder.SetInsertPoint(ContBlock);3988  }3989 3990  // only synthesize _cmd if it's referenced3991  if (OMD->getCmdDecl()->isUsed()) {3992    // `_cmd` is not a parameter to direct methods, so storage must be3993    // explicitly declared for it.3994    CGF.EmitVarDecl(*OMD->getCmdDecl());3995    Builder.CreateStore(GetSelector(CGF, OMD),3996                        CGF.GetAddrOfLocalVar(OMD->getCmdDecl()));3997  }3998}3999 4000llvm::GlobalVariable *4001CGObjCCommonMac::CreateMetadataVar(Twine Name, ConstantStructBuilder &Init,4002                                   StringRef Section, CharUnits Align,4003                                   bool AddToUsed) {4004  llvm::GlobalValue::LinkageTypes LT =4005      getLinkageTypeForObjCMetadata(CGM, Section);4006  llvm::GlobalVariable *GV =4007      Init.finishAndCreateGlobal(Name, Align, /*constant*/ false, LT);4008  if (!Section.empty())4009    GV->setSection(Section);4010  if (AddToUsed)4011    CGM.addCompilerUsedGlobal(GV);4012  return GV;4013}4014 4015llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,4016                                                         llvm::Constant *Init,4017                                                         StringRef Section,4018                                                         CharUnits Align,4019                                                         bool AddToUsed) {4020  llvm::Type *Ty = Init->getType();4021  llvm::GlobalValue::LinkageTypes LT =4022      getLinkageTypeForObjCMetadata(CGM, Section);4023  llvm::GlobalVariable *GV =4024      new llvm::GlobalVariable(CGM.getModule(), Ty, false, LT, Init, Name);4025  if (!Section.empty())4026    GV->setSection(Section);4027  GV->setAlignment(Align.getAsAlign());4028  if (AddToUsed)4029    CGM.addCompilerUsedGlobal(GV);4030  return GV;4031}4032 4033llvm::GlobalVariable *4034CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType Type,4035                                      bool ForceNonFragileABI,4036                                      bool NullTerminate) {4037  StringRef Label;4038  switch (Type) {4039  case ObjCLabelType::ClassName:4040    Label = "OBJC_CLASS_NAME_";4041    break;4042  case ObjCLabelType::MethodVarName:4043    Label = "OBJC_METH_VAR_NAME_";4044    break;4045  case ObjCLabelType::MethodVarType:4046    Label = "OBJC_METH_VAR_TYPE_";4047    break;4048  case ObjCLabelType::PropertyName:4049    Label = "OBJC_PROP_NAME_ATTR_";4050    break;4051  }4052 4053  bool NonFragile = ForceNonFragileABI || isNonFragileABI();4054 4055  StringRef Section;4056  switch (Type) {4057  case ObjCLabelType::ClassName:4058    Section = NonFragile ? "__TEXT,__objc_classname,cstring_literals"4059                         : "__TEXT,__cstring,cstring_literals";4060    break;4061  case ObjCLabelType::MethodVarName:4062    Section = NonFragile ? "__TEXT,__objc_methname,cstring_literals"4063                         : "__TEXT,__cstring,cstring_literals";4064    break;4065  case ObjCLabelType::MethodVarType:4066    Section = NonFragile ? "__TEXT,__objc_methtype,cstring_literals"4067                         : "__TEXT,__cstring,cstring_literals";4068    break;4069  case ObjCLabelType::PropertyName:4070    Section = NonFragile ? "__TEXT,__objc_methname,cstring_literals"4071                         : "__TEXT,__cstring,cstring_literals";4072    break;4073  }4074 4075  llvm::Constant *Value =4076      llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);4077  llvm::GlobalVariable *GV = new llvm::GlobalVariable(4078      CGM.getModule(), Value->getType(),4079      /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, Value, Label);4080  if (CGM.getTriple().isOSBinFormatMachO())4081    GV->setSection(Section);4082  GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);4083  GV->setAlignment(CharUnits::One().getAsAlign());4084  CGM.addCompilerUsedGlobal(GV);4085 4086  return GV;4087}4088 4089llvm::Function *CGObjCMac::ModuleInitFunction() {4090  // Abuse this interface function as a place to finalize.4091  FinishModule();4092  return nullptr;4093}4094 4095llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {4096  return ObjCTypes.getGetPropertyFn();4097}4098 4099llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {4100  return ObjCTypes.getSetPropertyFn();4101}4102 4103llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,4104                                                                bool copy) {4105  return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);4106}4107 4108llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {4109  return ObjCTypes.getCopyStructFn();4110}4111 4112llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {4113  return ObjCTypes.getCopyStructFn();4114}4115 4116llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {4117  return ObjCTypes.getCppAtomicObjectFunction();4118}4119 4120llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {4121  return ObjCTypes.getCppAtomicObjectFunction();4122}4123 4124llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {4125  return ObjCTypes.getEnumerationMutationFn();4126}4127 4128void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {4129  return EmitTryOrSynchronizedStmt(CGF, S);4130}4131 4132void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,4133                                     const ObjCAtSynchronizedStmt &S) {4134  return EmitTryOrSynchronizedStmt(CGF, S);4135}4136 4137namespace {4138struct PerformFragileFinally final : EHScopeStack::Cleanup {4139  const Stmt &S;4140  Address SyncArgSlot;4141  Address CallTryExitVar;4142  Address ExceptionData;4143  ObjCTypesHelper &ObjCTypes;4144  PerformFragileFinally(const Stmt *S, Address SyncArgSlot,4145                        Address CallTryExitVar, Address ExceptionData,4146                        ObjCTypesHelper *ObjCTypes)4147      : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),4148        ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}4149 4150  void Emit(CodeGenFunction &CGF, Flags flags) override {4151    // Check whether we need to call objc_exception_try_exit.4152    // In optimized code, this branch will always be folded.4153    llvm::BasicBlock *FinallyCallExit =4154        CGF.createBasicBlock("finally.call_exit");4155    llvm::BasicBlock *FinallyNoCallExit =4156        CGF.createBasicBlock("finally.no_call_exit");4157    CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),4158                             FinallyCallExit, FinallyNoCallExit);4159 4160    CGF.EmitBlock(FinallyCallExit);4161    CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(),4162                                ExceptionData.emitRawPointer(CGF));4163 4164    CGF.EmitBlock(FinallyNoCallExit);4165 4166    if (isa<ObjCAtTryStmt>(S)) {4167      if (const ObjCAtFinallyStmt *FinallyStmt =4168              cast<ObjCAtTryStmt>(S).getFinallyStmt()) {4169        // Don't try to do the @finally if this is an EH cleanup.4170        if (flags.isForEHCleanup())4171          return;4172 4173        // Save the current cleanup destination in case there's4174        // control flow inside the finally statement.4175        llvm::Value *CurCleanupDest =4176            CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());4177 4178        CGF.EmitStmt(FinallyStmt->getFinallyBody());4179 4180        if (CGF.HaveInsertPoint()) {4181          CGF.Builder.CreateStore(CurCleanupDest,4182                                  CGF.getNormalCleanupDestSlot());4183        } else {4184          // Currently, the end of the cleanup must always exist.4185          CGF.EnsureInsertPoint();4186        }4187      }4188    } else {4189      // Emit objc_sync_exit(expr); as finally's sole statement for4190      // @synchronized.4191      llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);4192      CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncExitFn(), SyncArg);4193    }4194  }4195};4196 4197class FragileHazards {4198  CodeGenFunction &CGF;4199  SmallVector<llvm::Value *, 20> Locals;4200  llvm::DenseSet<llvm::BasicBlock *> BlocksBeforeTry;4201 4202  llvm::InlineAsm *ReadHazard;4203  llvm::InlineAsm *WriteHazard;4204 4205  llvm::FunctionType *GetAsmFnType();4206 4207  void collectLocals();4208  void emitReadHazard(CGBuilderTy &Builder);4209 4210public:4211  FragileHazards(CodeGenFunction &CGF);4212 4213  void emitWriteHazard();4214  void emitHazardsInNewBlocks();4215};4216} // end anonymous namespace4217 4218/// Create the fragile-ABI read and write hazards based on the current4219/// state of the function, which is presumed to be immediately prior4220/// to a @try block.  These hazards are used to maintain correct4221/// semantics in the face of optimization and the fragile ABI's4222/// cavalier use of setjmp/longjmp.4223FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {4224  collectLocals();4225 4226  if (Locals.empty())4227    return;4228 4229  // Collect all the blocks in the function.4230  for (llvm::BasicBlock &BB : *CGF.CurFn)4231    BlocksBeforeTry.insert(&BB);4232 4233  llvm::FunctionType *AsmFnTy = GetAsmFnType();4234 4235  // Create a read hazard for the allocas.  This inhibits dead-store4236  // optimizations and forces the values to memory.  This hazard is4237  // inserted before any 'throwing' calls in the protected scope to4238  // reflect the possibility that the variables might be read from the4239  // catch block if the call throws.4240  {4241    std::string Constraint;4242    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {4243      if (I)4244        Constraint += ',';4245      Constraint += "*m";4246    }4247 4248    ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);4249  }4250 4251  // Create a write hazard for the allocas.  This inhibits folding4252  // loads across the hazard.  This hazard is inserted at the4253  // beginning of the catch path to reflect the possibility that the4254  // variables might have been written within the protected scope.4255  {4256    std::string Constraint;4257    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {4258      if (I)4259        Constraint += ',';4260      Constraint += "=*m";4261    }4262 4263    WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);4264  }4265}4266 4267/// Emit a write hazard at the current location.4268void FragileHazards::emitWriteHazard() {4269  if (Locals.empty())4270    return;4271 4272  llvm::CallInst *Call = CGF.EmitNounwindRuntimeCall(WriteHazard, Locals);4273  for (auto Pair : llvm::enumerate(Locals))4274    Call->addParamAttr(4275        Pair.index(),4276        llvm::Attribute::get(4277            CGF.getLLVMContext(), llvm::Attribute::ElementType,4278            cast<llvm::AllocaInst>(Pair.value())->getAllocatedType()));4279}4280 4281void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {4282  assert(!Locals.empty());4283  llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);4284  call->setDoesNotThrow();4285  call->setCallingConv(CGF.getRuntimeCC());4286  for (auto Pair : llvm::enumerate(Locals))4287    call->addParamAttr(4288        Pair.index(),4289        llvm::Attribute::get(4290            Builder.getContext(), llvm::Attribute::ElementType,4291            cast<llvm::AllocaInst>(Pair.value())->getAllocatedType()));4292}4293 4294/// Emit read hazards in all the protected blocks, i.e. all the blocks4295/// which have been inserted since the beginning of the try.4296void FragileHazards::emitHazardsInNewBlocks() {4297  if (Locals.empty())4298    return;4299 4300  CGBuilderTy Builder(CGF, CGF.getLLVMContext());4301 4302  // Iterate through all blocks, skipping those prior to the try.4303  for (llvm::BasicBlock &BB : *CGF.CurFn) {4304    if (BlocksBeforeTry.count(&BB))4305      continue;4306 4307    // Walk through all the calls in the block.4308    for (llvm::BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;4309         ++BI) {4310      llvm::Instruction &I = *BI;4311 4312      // Ignore instructions that aren't non-intrinsic calls.4313      // These are the only calls that can possibly call longjmp.4314      if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))4315        continue;4316      if (isa<llvm::IntrinsicInst>(I))4317        continue;4318 4319      // Ignore call sites marked nounwind.  This may be questionable,4320      // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.4321      if (cast<llvm::CallBase>(I).doesNotThrow())4322        continue;4323 4324      // Insert a read hazard before the call.  This will ensure that4325      // any writes to the locals are performed before making the4326      // call.  If the call throws, then this is sufficient to4327      // guarantee correctness as long as it doesn't also write to any4328      // locals.4329      Builder.SetInsertPoint(&BB, BI);4330      emitReadHazard(Builder);4331    }4332  }4333}4334 4335static void addIfPresent(llvm::DenseSet<llvm::Value *> &S, Address V) {4336  if (V.isValid())4337    if (llvm::Value *Ptr = V.getBasePointer())4338      S.insert(Ptr);4339}4340 4341void FragileHazards::collectLocals() {4342  // Compute a set of allocas to ignore.4343  llvm::DenseSet<llvm::Value *> AllocasToIgnore;4344  addIfPresent(AllocasToIgnore, CGF.ReturnValue);4345  addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);4346 4347  // Collect all the allocas currently in the function.  This is4348  // probably way too aggressive.4349  llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();4350  for (llvm::Instruction &I : Entry)4351    if (isa<llvm::AllocaInst>(I) && !AllocasToIgnore.count(&I))4352      Locals.push_back(&I);4353}4354 4355llvm::FunctionType *FragileHazards::GetAsmFnType() {4356  SmallVector<llvm::Type *, 16> tys(Locals.size());4357  for (unsigned i = 0, e = Locals.size(); i != e; ++i)4358    tys[i] = Locals[i]->getType();4359  return llvm::FunctionType::get(CGF.VoidTy, tys, false);4360}4361 4362/*4363 4364  Objective-C setjmp-longjmp (sjlj) Exception Handling4365  --4366 4367  A catch buffer is a setjmp buffer plus:4368    - a pointer to the exception that was caught4369    - a pointer to the previous exception data buffer4370    - two pointers of reserved storage4371  Therefore catch buffers form a stack, with a pointer to the top4372  of the stack kept in thread-local storage.4373 4374  objc_exception_try_enter pushes a catch buffer onto the EH stack.4375  objc_exception_try_exit pops the given catch buffer, which is4376    required to be the top of the EH stack.4377  objc_exception_throw pops the top of the EH stack, writes the4378    thrown exception into the appropriate field, and longjmps4379    to the setjmp buffer.  It crashes the process (with a printf4380    and an abort()) if there are no catch buffers on the stack.4381  objc_exception_extract just reads the exception pointer out of the4382    catch buffer.4383 4384  There's no reason an implementation couldn't use a light-weight4385  setjmp here --- something like __builtin_setjmp, but API-compatible4386  with the heavyweight setjmp.  This will be more important if we ever4387  want to implement correct ObjC/C++ exception interactions for the4388  fragile ABI.4389 4390  Note that for this use of setjmp/longjmp to be correct in the presence of4391  optimization, we use inline assembly on the set of local variables to force4392  flushing locals to memory immediately before any protected calls and to4393  inhibit optimizing locals across the setjmp->catch edge.4394 4395  The basic framework for a @try-catch-finally is as follows:4396  {4397  objc_exception_data d;4398  id _rethrow = null;4399  bool _call_try_exit = true;4400 4401  objc_exception_try_enter(&d);4402  if (!setjmp(d.jmp_buf)) {4403  ... try body ...4404  } else {4405  // exception path4406  id _caught = objc_exception_extract(&d);4407 4408  // enter new try scope for handlers4409  if (!setjmp(d.jmp_buf)) {4410  ... match exception and execute catch blocks ...4411 4412  // fell off end, rethrow.4413  _rethrow = _caught;4414  ... jump-through-finally to finally_rethrow ...4415  } else {4416  // exception in catch block4417  _rethrow = objc_exception_extract(&d);4418  _call_try_exit = false;4419  ... jump-through-finally to finally_rethrow ...4420  }4421  }4422  ... jump-through-finally to finally_end ...4423 4424  finally:4425  if (_call_try_exit)4426  objc_exception_try_exit(&d);4427 4428  ... finally block ....4429  ... dispatch to finally destination ...4430 4431  finally_rethrow:4432  objc_exception_throw(_rethrow);4433 4434  finally_end:4435  }4436 4437  This framework differs slightly from the one gcc uses, in that gcc4438  uses _rethrow to determine if objc_exception_try_exit should be called4439  and if the object should be rethrown. This breaks in the face of4440  throwing nil and introduces unnecessary branches.4441 4442  We specialize this framework for a few particular circumstances:4443 4444  - If there are no catch blocks, then we avoid emitting the second4445  exception handling context.4446 4447  - If there is a catch-all catch block (i.e. @catch(...) or @catch(id4448  e)) we avoid emitting the code to rethrow an uncaught exception.4449 4450  - FIXME: If there is no @finally block we can do a few more4451  simplifications.4452 4453  Rethrows and Jumps-Through-Finally4454  --4455 4456  '@throw;' is supported by pushing the currently-caught exception4457  onto ObjCEHStack while the @catch blocks are emitted.4458 4459  Branches through the @finally block are handled with an ordinary4460  normal cleanup.  We do not register an EH cleanup; fragile-ABI ObjC4461  exceptions are not compatible with C++ exceptions, and this is4462  hardly the only place where this will go wrong.4463 4464  @synchronized(expr) { stmt; } is emitted as if it were:4465    id synch_value = expr;4466    objc_sync_enter(synch_value);4467    @try { stmt; } @finally { objc_sync_exit(synch_value); }4468*/4469 4470void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,4471                                          const Stmt &S) {4472  bool isTry = isa<ObjCAtTryStmt>(S);4473 4474  // A destination for the fall-through edges of the catch handlers to4475  // jump to.4476  CodeGenFunction::JumpDest FinallyEnd =4477      CGF.getJumpDestInCurrentScope("finally.end");4478 4479  // A destination for the rethrow edge of the catch handlers to jump4480  // to.4481  CodeGenFunction::JumpDest FinallyRethrow =4482      CGF.getJumpDestInCurrentScope("finally.rethrow");4483 4484  // For @synchronized, call objc_sync_enter(sync.expr). The4485  // evaluation of the expression must occur before we enter the4486  // @synchronized.  We can't avoid a temp here because we need the4487  // value to be preserved.  If the backend ever does liveness4488  // correctly after setjmp, this will be unnecessary.4489  Address SyncArgSlot = Address::invalid();4490  if (!isTry) {4491    llvm::Value *SyncArg =4492        CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());4493    SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);4494    CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncEnterFn(), SyncArg);4495 4496    SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(),4497                                       CGF.getPointerAlign(), "sync.arg");4498    CGF.Builder.CreateStore(SyncArg, SyncArgSlot);4499  }4500 4501  // Allocate memory for the setjmp buffer.  This needs to be kept4502  // live throughout the try and catch blocks.4503  Address ExceptionData = CGF.CreateTempAlloca(4504      ObjCTypes.ExceptionDataTy, CGF.getPointerAlign(), "exceptiondata.ptr");4505 4506  // Create the fragile hazards.  Note that this will not capture any4507  // of the allocas required for exception processing, but will4508  // capture the current basic block (which extends all the way to the4509  // setjmp call) as "before the @try".4510  FragileHazards Hazards(CGF);4511 4512  // Create a flag indicating whether the cleanup needs to call4513  // objc_exception_try_exit.  This is true except when4514  //   - no catches match and we're branching through the cleanup4515  //     just to rethrow the exception, or4516  //   - a catch matched and we're falling out of the catch handler.4517  // The setjmp-safety rule here is that we should always store to this4518  // variable in a place that dominates the branch through the cleanup4519  // without passing through any setjmps.4520  Address CallTryExitVar = CGF.CreateTempAlloca(4521      CGF.Builder.getInt1Ty(), CharUnits::One(), "_call_try_exit");4522 4523  // A slot containing the exception to rethrow.  Only needed when we4524  // have both a @catch and a @finally.4525  Address PropagatingExnVar = Address::invalid();4526 4527  // Push a normal cleanup to leave the try scope.4528  CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalAndEHCleanup, &S,4529                                                 SyncArgSlot, CallTryExitVar,4530                                                 ExceptionData, &ObjCTypes);4531 4532  // Enter a try block:4533  //  - Call objc_exception_try_enter to push ExceptionData on top of4534  //    the EH stack.4535  CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),4536                              ExceptionData.emitRawPointer(CGF));4537 4538  //  - Call setjmp on the exception data buffer.4539  llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);4540  llvm::Value *GEPIndexes[] = {Zero, Zero, Zero};4541  llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP(4542      ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes,4543      "setjmp_buffer");4544  llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(4545      ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");4546  SetJmpResult->setCanReturnTwice();4547 4548  // If setjmp returned 0, enter the protected block; otherwise,4549  // branch to the handler.4550  llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");4551  llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");4552  llvm::Value *DidCatch =4553      CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");4554  CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);4555 4556  // Emit the protected block.4557  CGF.EmitBlock(TryBlock);4558  CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);4559  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()4560                     : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());4561 4562  CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();4563 4564  // Emit the exception handler block.4565  CGF.EmitBlock(TryHandler);4566 4567  // Don't optimize loads of the in-scope locals across this point.4568  Hazards.emitWriteHazard();4569 4570  // For a @synchronized (or a @try with no catches), just branch4571  // through the cleanup to the rethrow block.4572  if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {4573    // Tell the cleanup not to re-pop the exit.4574    CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);4575    CGF.EmitBranchThroughCleanup(FinallyRethrow);4576 4577  // Otherwise, we have to match against the caught exceptions.4578  } else {4579    // Retrieve the exception object.  We may emit multiple blocks but4580    // nothing can cross this so the value is already in SSA form.4581    llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall(4582        ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),4583        "caught");4584 4585    // Push the exception to rethrow onto the EH value stack for the4586    // benefit of any @throws in the handlers.4587    CGF.ObjCEHValueStack.push_back(Caught);4588 4589    const ObjCAtTryStmt *AtTryStmt = cast<ObjCAtTryStmt>(&S);4590 4591    bool HasFinally = (AtTryStmt->getFinallyStmt() != nullptr);4592 4593    llvm::BasicBlock *CatchBlock = nullptr;4594    llvm::BasicBlock *CatchHandler = nullptr;4595    if (HasFinally) {4596      // Save the currently-propagating exception before4597      // objc_exception_try_enter clears the exception slot.4598      PropagatingExnVar = CGF.CreateTempAlloca(4599          Caught->getType(), CGF.getPointerAlign(), "propagating_exception");4600      CGF.Builder.CreateStore(Caught, PropagatingExnVar);4601 4602      // Enter a new exception try block (in case a @catch block4603      // throws an exception).4604      CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),4605                                  ExceptionData.emitRawPointer(CGF));4606 4607      llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(4608          ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp.result");4609      SetJmpResult->setCanReturnTwice();4610 4611      llvm::Value *Threw =4612          CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");4613 4614      CatchBlock = CGF.createBasicBlock("catch");4615      CatchHandler = CGF.createBasicBlock("catch_for_catch");4616      CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);4617 4618      CGF.EmitBlock(CatchBlock);4619    }4620 4621    CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);4622 4623    // Handle catch list. As a special case we check if everything is4624    // matched and avoid generating code for falling off the end if4625    // so.4626    bool AllMatched = false;4627    for (const ObjCAtCatchStmt *CatchStmt : AtTryStmt->catch_stmts()) {4628      const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();4629      const ObjCObjectPointerType *OPT = nullptr;4630 4631      // catch(...) always matches.4632      if (!CatchParam) {4633        AllMatched = true;4634      } else {4635        OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();4636 4637        // catch(id e) always matches under this ABI, since only4638        // ObjC exceptions end up here in the first place.4639        // FIXME: For the time being we also match id<X>; this should4640        // be rejected by Sema instead.4641        if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))4642          AllMatched = true;4643      }4644 4645      // If this is a catch-all, we don't need to test anything.4646      if (AllMatched) {4647        CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);4648 4649        if (CatchParam) {4650          CGF.EmitAutoVarDecl(*CatchParam);4651          assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");4652 4653          // These types work out because ConvertType(id) == i8*.4654          EmitInitOfCatchParam(CGF, Caught, CatchParam);4655        }4656 4657        CGF.EmitStmt(CatchStmt->getCatchBody());4658 4659        // The scope of the catch variable ends right here.4660        CatchVarCleanups.ForceCleanup();4661 4662        CGF.EmitBranchThroughCleanup(FinallyEnd);4663        break;4664      }4665 4666      assert(OPT && "Unexpected non-object pointer type in @catch");4667      const ObjCObjectType *ObjTy = OPT->getObjectType();4668 4669      // FIXME: @catch (Class c) ?4670      ObjCInterfaceDecl *IDecl = ObjTy->getInterface();4671      assert(IDecl && "Catch parameter must have Objective-C type!");4672 4673      // Check if the @catch block matches the exception object.4674      llvm::Value *Class = EmitClassRef(CGF, IDecl);4675 4676      llvm::Value *matchArgs[] = {Class, Caught};4677      llvm::CallInst *Match = CGF.EmitNounwindRuntimeCall(4678          ObjCTypes.getExceptionMatchFn(), matchArgs, "match");4679 4680      llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");4681      llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");4682 4683      CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),4684                               MatchedBlock, NextCatchBlock);4685 4686      // Emit the @catch block.4687      CGF.EmitBlock(MatchedBlock);4688 4689      // Collect any cleanups for the catch variable.  The scope lasts until4690      // the end of the catch body.4691      CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);4692 4693      CGF.EmitAutoVarDecl(*CatchParam);4694      assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");4695 4696      // Initialize the catch variable.4697      llvm::Value *Tmp = CGF.Builder.CreateBitCast(4698          Caught, CGF.ConvertType(CatchParam->getType()));4699      EmitInitOfCatchParam(CGF, Tmp, CatchParam);4700 4701      CGF.EmitStmt(CatchStmt->getCatchBody());4702 4703      // We're done with the catch variable.4704      CatchVarCleanups.ForceCleanup();4705 4706      CGF.EmitBranchThroughCleanup(FinallyEnd);4707 4708      CGF.EmitBlock(NextCatchBlock);4709    }4710 4711    CGF.ObjCEHValueStack.pop_back();4712 4713    // If nothing wanted anything to do with the caught exception,4714    // kill the extract call.4715    if (Caught->use_empty())4716      Caught->eraseFromParent();4717 4718    if (!AllMatched)4719      CGF.EmitBranchThroughCleanup(FinallyRethrow);4720 4721    if (HasFinally) {4722      // Emit the exception handler for the @catch blocks.4723      CGF.EmitBlock(CatchHandler);4724 4725      // In theory we might now need a write hazard, but actually it's4726      // unnecessary because there's no local-accessing code between4727      // the try's write hazard and here.4728      // Hazards.emitWriteHazard();4729 4730      // Extract the new exception and save it to the4731      // propagating-exception slot.4732      assert(PropagatingExnVar.isValid());4733      llvm::CallInst *NewCaught = CGF.EmitNounwindRuntimeCall(4734          ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),4735          "caught");4736      CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);4737 4738      // Don't pop the catch handler; the throw already did.4739      CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);4740      CGF.EmitBranchThroughCleanup(FinallyRethrow);4741    }4742  }4743 4744  // Insert read hazards as required in the new blocks.4745  Hazards.emitHazardsInNewBlocks();4746 4747  // Pop the cleanup.4748  CGF.Builder.restoreIP(TryFallthroughIP);4749  if (CGF.HaveInsertPoint())4750    CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);4751  CGF.PopCleanupBlock();4752  CGF.EmitBlock(FinallyEnd.getBlock(), true);4753 4754  // Emit the rethrow block.4755  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();4756  CGF.EmitBlock(FinallyRethrow.getBlock(), true);4757  if (CGF.HaveInsertPoint()) {4758    // If we have a propagating-exception variable, check it.4759    llvm::Value *PropagatingExn;4760    if (PropagatingExnVar.isValid()) {4761      PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);4762 4763    // Otherwise, just look in the buffer for the exception to throw.4764    } else {4765      llvm::CallInst *Caught = CGF.EmitNounwindRuntimeCall(4766          ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF));4767      PropagatingExn = Caught;4768    }4769 4770    CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionThrowFn(),4771                                PropagatingExn);4772    CGF.Builder.CreateUnreachable();4773  }4774 4775  CGF.Builder.restoreIP(SavedIP);4776}4777 4778void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,4779                              const ObjCAtThrowStmt &S,4780                              bool ClearInsertionPoint) {4781  llvm::Value *ExceptionAsObject;4782 4783  if (const Expr *ThrowExpr = S.getThrowExpr()) {4784    llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);4785    ExceptionAsObject =4786        CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);4787  } else {4788    assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&4789           "Unexpected rethrow outside @catch block.");4790    ExceptionAsObject = CGF.ObjCEHValueStack.back();4791  }4792 4793  CGF.EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)4794      ->setDoesNotReturn();4795  CGF.Builder.CreateUnreachable();4796 4797  // Clear the insertion point to indicate we are in unreachable code.4798  if (ClearInsertionPoint)4799    CGF.Builder.ClearInsertionPoint();4800}4801 4802/// EmitObjCWeakRead - Code gen for loading value of a __weak4803/// object: objc_read_weak (id *src)4804///4805llvm::Value *CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,4806                                         Address AddrWeakObj) {4807  llvm::Type *DestTy = AddrWeakObj.getElementType();4808  llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(4809      AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);4810  llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(4811      ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread");4812  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);4813  return read_weak;4814}4815 4816/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.4817/// objc_assign_weak (id src, id *dst)4818///4819void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,4820                                   llvm::Value *src, Address dst) {4821  llvm::Type *SrcTy = src->getType();4822  if (!isa<llvm::PointerType>(SrcTy)) {4823    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);4824    assert(Size <= 8 && "does not support size > 8");4825    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)4826                      : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);4827    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);4828  }4829  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);4830  llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),4831                                                  ObjCTypes.PtrObjectPtrTy);4832  llvm::Value *args[] = {src, dstVal};4833  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,4834                              "weakassign");4835}4836 4837/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.4838/// objc_assign_global (id src, id *dst)4839///4840void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,4841                                     llvm::Value *src, Address dst,4842                                     bool threadlocal) {4843  llvm::Type *SrcTy = src->getType();4844  if (!isa<llvm::PointerType>(SrcTy)) {4845    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);4846    assert(Size <= 8 && "does not support size > 8");4847    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)4848                      : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);4849    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);4850  }4851  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);4852  llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),4853                                                  ObjCTypes.PtrObjectPtrTy);4854  llvm::Value *args[] = {src, dstVal};4855  if (!threadlocal)4856    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,4857                                "globalassign");4858  else4859    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,4860                                "threadlocalassign");4861}4862 4863/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.4864/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)4865///4866void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,4867                                   llvm::Value *src, Address dst,4868                                   llvm::Value *ivarOffset) {4869  assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");4870  llvm::Type *SrcTy = src->getType();4871  if (!isa<llvm::PointerType>(SrcTy)) {4872    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);4873    assert(Size <= 8 && "does not support size > 8");4874    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)4875                      : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);4876    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);4877  }4878  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);4879  llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),4880                                                  ObjCTypes.PtrObjectPtrTy);4881  llvm::Value *args[] = {src, dstVal, ivarOffset};4882  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);4883}4884 4885/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.4886/// objc_assign_strongCast (id src, id *dst)4887///4888void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,4889                                         llvm::Value *src, Address dst) {4890  llvm::Type *SrcTy = src->getType();4891  if (!isa<llvm::PointerType>(SrcTy)) {4892    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);4893    assert(Size <= 8 && "does not support size > 8");4894    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)4895                      : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);4896    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);4897  }4898  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);4899  llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),4900                                                  ObjCTypes.PtrObjectPtrTy);4901  llvm::Value *args[] = {src, dstVal};4902  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,4903                              "strongassign");4904}4905 4906void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,4907                                         Address DestPtr, Address SrcPtr,4908                                         llvm::Value *size) {4909  llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),4910                         SrcPtr.emitRawPointer(CGF), size};4911  CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);4912}4913 4914/// EmitObjCValueForIvar - Code Gen for ivar reference.4915///4916LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,4917                                       QualType ObjectTy,4918                                       llvm::Value *BaseValue,4919                                       const ObjCIvarDecl *Ivar,4920                                       unsigned CVRQualifiers) {4921  const ObjCInterfaceDecl *ID =4922      ObjectTy->castAs<ObjCObjectType>()->getInterface();4923  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,4924                                  EmitIvarOffset(CGF, ID, Ivar));4925}4926 4927llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,4928                                       const ObjCInterfaceDecl *Interface,4929                                       const ObjCIvarDecl *Ivar) {4930  uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);4931  return llvm::ConstantInt::get(4932      CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);4933}4934 4935/* *** Private Interface *** */4936 4937std::string CGObjCCommonMac::GetSectionName(StringRef Section,4938                                            StringRef MachOAttributes) {4939  switch (CGM.getTriple().getObjectFormat()) {4940  case llvm::Triple::UnknownObjectFormat:4941    llvm_unreachable("unexpected object file format");4942  case llvm::Triple::MachO: {4943    if (MachOAttributes.empty())4944      return ("__DATA," + Section).str();4945    return ("__DATA," + Section + "," + MachOAttributes).str();4946  }4947  case llvm::Triple::ELF:4948    assert(Section.starts_with("__") && "expected the name to begin with __");4949    return Section.substr(2).str();4950  case llvm::Triple::COFF:4951    assert(Section.starts_with("__") && "expected the name to begin with __");4952    return ("." + Section.substr(2) + "$B").str();4953  case llvm::Triple::Wasm:4954  case llvm::Triple::GOFF:4955  case llvm::Triple::SPIRV:4956  case llvm::Triple::XCOFF:4957  case llvm::Triple::DXContainer:4958    llvm::report_fatal_error(4959        "Objective-C support is unimplemented for object file format");4960  }4961 4962  llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType enum");4963}4964 4965// clang-format off4966/// EmitImageInfo - Emit the image info marker used to encode some module4967/// level information.4968///4969/// See: <rdr://4810609&4810587&4810587>4970/// struct IMAGE_INFO {4971///   unsigned version;4972///   unsigned flags;4973/// };4974enum ImageInfoFlags {4975  eImageInfo_FixAndContinue      = (1 << 0), // This flag is no longer set by clang.4976  eImageInfo_GarbageCollected    = (1 << 1),4977  eImageInfo_GCOnly              = (1 << 2),4978  eImageInfo_OptimizedByDyld     = (1 << 3), // This flag is set by the dyld shared cache.4979 4980  eImageInfo_SignedClassRO       = (1 << 4), // Reused (was _CorrectedSynthesize)4981  eImageInfo_ImageIsSimulated    = (1 << 5),4982  eImageInfo_ClassProperties     = (1 << 6)4983};4984// clang-format on4985 4986void CGObjCCommonMac::EmitImageInfo() {4987  unsigned version = 0; // Version is unused?4988  std::string Section =4989      (ObjCABI == 1)4990          ? "__OBJC,__image_info,regular"4991          : GetSectionName("__objc_imageinfo", "regular,no_dead_strip");4992 4993  // Generate module-level named metadata to convey this information to the4994  // linker and code-gen.4995  llvm::Module &Mod = CGM.getModule();4996 4997  // Add the ObjC ABI version to the module flags.4998  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);4999  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",5000                    version);5001  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",5002                    llvm::MDString::get(VMContext, Section));5003 5004  auto Int8Ty = llvm::Type::getInt8Ty(VMContext);5005  if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {5006    // Non-GC overrides those files which specify GC.5007    Mod.addModuleFlag(llvm::Module::Error, "Objective-C Garbage Collection",5008                      llvm::ConstantInt::get(Int8Ty, 0));5009  } else {5010    // Add the ObjC garbage collection value.5011    Mod.addModuleFlag(5012        llvm::Module::Error, "Objective-C Garbage Collection",5013        llvm::ConstantInt::get(Int8Ty, (uint8_t)eImageInfo_GarbageCollected));5014 5015    if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {5016      // Add the ObjC GC Only value.5017      Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",5018                        eImageInfo_GCOnly);5019 5020      // Require that GC be specified and set to eImageInfo_GarbageCollected.5021      llvm::Metadata *Ops[2] = {5022          llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),5023          llvm::ConstantAsMetadata::get(5024              llvm::ConstantInt::get(Int8Ty, eImageInfo_GarbageCollected))};5025      Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",5026                        llvm::MDNode::get(VMContext, Ops));5027    }5028  }5029 5030  // Indicate whether we're compiling this to run on a simulator.5031  if (CGM.getTarget().getTriple().isSimulatorEnvironment())5032    Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated",5033                      eImageInfo_ImageIsSimulated);5034 5035  // Indicate whether we are generating class properties.5036  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties",5037                    eImageInfo_ClassProperties);5038 5039  // Indicate whether we want enforcement of pointer signing for class_ro_t5040  // pointers.5041  if (CGM.getLangOpts().PointerAuthObjcClassROPointers)5042    Mod.addModuleFlag(llvm::Module::Error,5043                      "Objective-C Enforce ClassRO Pointer Signing",5044                      eImageInfo_SignedClassRO);5045  else5046    Mod.addModuleFlag(llvm::Module::Error,5047                      "Objective-C Enforce ClassRO Pointer Signing",5048                      llvm::ConstantInt::get(Int8Ty, 0));5049}5050 5051// struct objc_module {5052//   unsigned long version;5053//   unsigned long size;5054//   const char *name;5055//   Symtab symtab;5056// };5057 5058// FIXME: Get from somewhere5059static const int ModuleVersion = 7;5060 5061void CGObjCMac::EmitModuleInfo() {5062  uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);5063 5064  ConstantInitBuilder builder(CGM);5065  auto values = builder.beginStruct(ObjCTypes.ModuleTy);5066  values.addInt(ObjCTypes.LongTy, ModuleVersion);5067  values.addInt(ObjCTypes.LongTy, Size);5068  // This used to be the filename, now it is unused. <rdr://4327263>5069  values.add(GetClassName(StringRef("")));5070  values.add(EmitModuleSymbols());5071  CreateMetadataVar("OBJC_MODULES", values,5072                    "__OBJC,__module_info,regular,no_dead_strip",5073                    CGM.getPointerAlign(), true);5074}5075 5076llvm::Constant *CGObjCMac::EmitModuleSymbols() {5077  unsigned NumClasses = DefinedClasses.size();5078  unsigned NumCategories = DefinedCategories.size();5079 5080  // Return null if no symbols were defined.5081  if (!NumClasses && !NumCategories)5082    return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);5083 5084  ConstantInitBuilder builder(CGM);5085  auto values = builder.beginStruct();5086  values.addInt(ObjCTypes.LongTy, 0);5087  values.addNullPointer(ObjCTypes.SelectorPtrTy);5088  values.addInt(ObjCTypes.ShortTy, NumClasses);5089  values.addInt(ObjCTypes.ShortTy, NumCategories);5090 5091  // The runtime expects exactly the list of defined classes followed5092  // by the list of defined categories, in a single array.5093  auto array = values.beginArray(ObjCTypes.Int8PtrTy);5094  for (unsigned i = 0; i < NumClasses; i++) {5095    const ObjCInterfaceDecl *ID = ImplementedClasses[i];5096    assert(ID);5097    if (ObjCImplementationDecl *IMP = ID->getImplementation())5098      // We are implementing a weak imported interface. Give it external linkage5099      if (ID->isWeakImported() && !IMP->isWeakImported())5100        DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);5101 5102    array.add(DefinedClasses[i]);5103  }5104  for (unsigned i = 0; i < NumCategories; i++)5105    array.add(DefinedCategories[i]);5106 5107  array.finishAndAddTo(values);5108 5109  llvm::GlobalVariable *GV = CreateMetadataVar(5110      "OBJC_SYMBOLS", values, "__OBJC,__symbols,regular,no_dead_strip",5111      CGM.getPointerAlign(), true);5112  return GV;5113}5114 5115llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,5116                                           IdentifierInfo *II) {5117  LazySymbols.insert(II);5118 5119  llvm::GlobalVariable *&Entry = ClassReferences[II];5120 5121  if (!Entry) {5122    Entry =5123        CreateMetadataVar("OBJC_CLASS_REFERENCES_", GetClassName(II->getName()),5124                          "__OBJC,__cls_refs,literal_pointers,no_dead_strip",5125                          CGM.getPointerAlign(), true);5126  }5127 5128  return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry,5129                                       CGF.getPointerAlign());5130}5131 5132llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,5133                                     const ObjCInterfaceDecl *ID) {5134  // If the class has the objc_runtime_visible attribute, we need to5135  // use the Objective-C runtime to get the class.5136  if (ID->hasAttr<ObjCRuntimeVisibleAttr>())5137    return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);5138 5139  IdentifierInfo *RuntimeName =5140      &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());5141  return EmitClassRefFromId(CGF, RuntimeName);5142}5143 5144llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {5145  IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");5146  return EmitClassRefFromId(CGF, II);5147}5148 5149llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {5150  return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel));5151}5152 5153ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {5154  CharUnits Align = CGM.getPointerAlign();5155 5156  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];5157  if (!Entry) {5158    Entry = CreateMetadataVar(5159        "OBJC_SELECTOR_REFERENCES_", GetMethodVarName(Sel),5160        "__OBJC,__message_refs,literal_pointers,no_dead_strip", Align, true);5161    Entry->setExternallyInitialized(true);5162  }5163 5164  return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);5165}5166 5167llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {5168  llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];5169  if (!Entry)5170    Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);5171  return getConstantGEP(VMContext, Entry, 0, 0);5172}5173 5174llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {5175  return MethodDefinitions.lookup(MD);5176}5177 5178/// GetIvarLayoutName - Returns a unique constant for the given5179/// ivar layout bitmap.5180llvm::Constant *5181CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,5182                                   const ObjCCommonTypesHelper &ObjCTypes) {5183  return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);5184}5185 5186void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {5187  const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();5188 5189  // If this is a union, remember that we had one, because it might mess5190  // up the ordering of layout entries.5191  if (RD->isUnion())5192    IsDisordered = true;5193 5194  const ASTRecordLayout *recLayout = nullptr;5195  visitAggregate(RD->field_begin(), RD->field_end(), offset,5196                 [&](const FieldDecl *field) -> CharUnits {5197                   if (!recLayout)5198                     recLayout = &CGM.getContext().getASTRecordLayout(RD);5199                   auto offsetInBits =5200                       recLayout->getFieldOffset(field->getFieldIndex());5201                   return CGM.getContext().toCharUnitsFromBits(offsetInBits);5202                 });5203}5204 5205template <class Iterator, class GetOffsetFn>5206void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,5207                                       CharUnits aggregateOffset,5208                                       const GetOffsetFn &getOffset) {5209  for (; begin != end; ++begin) {5210    auto field = *begin;5211 5212    // Skip over bitfields.5213    if (field->isBitField()) {5214      continue;5215    }5216 5217    // Compute the offset of the field within the aggregate.5218    CharUnits fieldOffset = aggregateOffset + getOffset(field);5219 5220    visitField(field, fieldOffset);5221  }5222}5223 5224/// Collect layout information for the given fields into IvarsInfo.5225void IvarLayoutBuilder::visitField(const FieldDecl *field,5226                                   CharUnits fieldOffset) {5227  QualType fieldType = field->getType();5228 5229  // Drill down into arrays.5230  uint64_t numElts = 1;5231  if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {5232    numElts = 0;5233    fieldType = arrayType->getElementType();5234  }5235  // Unlike incomplete arrays, constant arrays can be nested.5236  while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {5237    numElts *= arrayType->getZExtSize();5238    fieldType = arrayType->getElementType();5239  }5240 5241  assert(!fieldType->isArrayType() && "ivar of non-constant array type?");5242 5243  // If we ended up with a zero-sized array, we've done what we can do within5244  // the limits of this layout encoding.5245  if (numElts == 0)5246    return;5247 5248  // Recurse if the base element type is a record type.5249  if (const auto *recType = fieldType->getAsCanonical<RecordType>()) {5250    size_t oldEnd = IvarsInfo.size();5251 5252    visitRecord(recType, fieldOffset);5253 5254    // If we have an array, replicate the first entry's layout information.5255    auto numEltEntries = IvarsInfo.size() - oldEnd;5256    if (numElts != 1 && numEltEntries != 0) {5257      CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);5258      for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {5259        // Copy the last numEltEntries onto the end of the array, adjusting5260        // each for the element size.5261        for (size_t i = 0; i != numEltEntries; ++i) {5262          auto firstEntry = IvarsInfo[oldEnd + i];5263          IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,5264                                       firstEntry.SizeInWords));5265        }5266      }5267    }5268 5269    return;5270  }5271 5272  // Classify the element type.5273  Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);5274 5275  // If it matches what we're looking for, add an entry.5276  if ((ForStrongLayout && GCAttr == Qualifiers::Strong) ||5277      (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {5278    assert(CGM.getContext().getTypeSizeInChars(fieldType) ==5279           CGM.getPointerSize());5280    IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));5281  }5282}5283 5284/// buildBitmap - This routine does the horsework of taking the offsets of5285/// strong/weak references and creating a bitmap.  The bitmap is also5286/// returned in the given buffer, suitable for being passed to \c dump().5287llvm::Constant *5288IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,5289                               llvm::SmallVectorImpl<unsigned char> &buffer) {5290  // The bitmap is a series of skip/scan instructions, aligned to word5291  // boundaries.  The skip is performed first.5292  const unsigned char MaxNibble = 0xF;5293  const unsigned char SkipMask = 0xF0, SkipShift = 4;5294  const unsigned char ScanMask = 0x0F, ScanShift = 0;5295 5296  assert(!IvarsInfo.empty() && "generating bitmap for no data");5297 5298  // Sort the ivar info on byte position in case we encounterred a5299  // union nested in the ivar list.5300  if (IsDisordered) {5301    // This isn't a stable sort, but our algorithm should handle it fine.5302    llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());5303  } else {5304    assert(llvm::is_sorted(IvarsInfo));5305  }5306  assert(IvarsInfo.back().Offset < InstanceEnd);5307 5308  assert(buffer.empty());5309 5310  // Skip the next N words.5311  auto skip = [&](unsigned numWords) {5312    assert(numWords > 0);5313 5314    // Try to merge into the previous byte.  Since scans happen second, we5315    // can't do this if it includes a scan.5316    if (!buffer.empty() && !(buffer.back() & ScanMask)) {5317      unsigned lastSkip = buffer.back() >> SkipShift;5318      if (lastSkip < MaxNibble) {5319        unsigned claimed = std::min(MaxNibble - lastSkip, numWords);5320        numWords -= claimed;5321        lastSkip += claimed;5322        buffer.back() = (lastSkip << SkipShift);5323      }5324    }5325 5326    while (numWords >= MaxNibble) {5327      buffer.push_back(MaxNibble << SkipShift);5328      numWords -= MaxNibble;5329    }5330    if (numWords) {5331      buffer.push_back(numWords << SkipShift);5332    }5333  };5334 5335  // Scan the next N words.5336  auto scan = [&](unsigned numWords) {5337    assert(numWords > 0);5338 5339    // Try to merge into the previous byte.  Since scans happen second, we can5340    // do this even if it includes a skip.5341    if (!buffer.empty()) {5342      unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;5343      if (lastScan < MaxNibble) {5344        unsigned claimed = std::min(MaxNibble - lastScan, numWords);5345        numWords -= claimed;5346        lastScan += claimed;5347        buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);5348      }5349    }5350 5351    while (numWords >= MaxNibble) {5352      buffer.push_back(MaxNibble << ScanShift);5353      numWords -= MaxNibble;5354    }5355    if (numWords) {5356      buffer.push_back(numWords << ScanShift);5357    }5358  };5359 5360  // One past the end of the last scan.5361  unsigned endOfLastScanInWords = 0;5362  const CharUnits WordSize = CGM.getPointerSize();5363 5364  // Consider all the scan requests.5365  for (auto &request : IvarsInfo) {5366    CharUnits beginOfScan = request.Offset - InstanceBegin;5367 5368    // Ignore scan requests that don't start at an even multiple of the5369    // word size.  We can't encode them.5370    if (!beginOfScan.isMultipleOf(WordSize))5371      continue;5372 5373    // Ignore scan requests that start before the instance start.5374    // This assumes that scans never span that boundary.  The boundary5375    // isn't the true start of the ivars, because in the fragile-ARC case5376    // it's rounded up to word alignment, but the test above should leave5377    // us ignoring that possibility.5378    if (beginOfScan.isNegative()) {5379      assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);5380      continue;5381    }5382 5383    unsigned beginOfScanInWords = beginOfScan / WordSize;5384    unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;5385 5386    // If the scan starts some number of words after the last one ended,5387    // skip forward.5388    if (beginOfScanInWords > endOfLastScanInWords) {5389      skip(beginOfScanInWords - endOfLastScanInWords);5390 5391    // Otherwise, start scanning where the last left off.5392    } else {5393      beginOfScanInWords = endOfLastScanInWords;5394 5395      // If that leaves us with nothing to scan, ignore this request.5396      if (beginOfScanInWords >= endOfScanInWords)5397        continue;5398    }5399 5400    // Scan to the end of the request.5401    assert(beginOfScanInWords < endOfScanInWords);5402    scan(endOfScanInWords - beginOfScanInWords);5403    endOfLastScanInWords = endOfScanInWords;5404  }5405 5406  if (buffer.empty())5407    return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);5408 5409  // For GC layouts, emit a skip to the end of the allocation so that we5410  // have precise information about the entire thing.  This isn't useful5411  // or necessary for the ARC-style layout strings.5412  if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {5413    unsigned lastOffsetInWords =5414        (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;5415    if (lastOffsetInWords > endOfLastScanInWords) {5416      skip(lastOffsetInWords - endOfLastScanInWords);5417    }5418  }5419 5420  // Null terminate the string.5421  buffer.push_back(0);5422 5423  auto *Entry = CGObjC.CreateCStringLiteral(5424      reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName);5425  return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);5426}5427 5428/// BuildIvarLayout - Builds ivar layout bitmap for the class5429/// implementation for the __strong or __weak case.5430/// The layout map displays which words in ivar list must be skipped5431/// and which must be scanned by GC (see below). String is built of bytes.5432/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count5433/// of words to skip and right nibble is count of words to scan. So, each5434/// nibble represents up to 15 workds to skip or scan. Skipping the rest is5435/// represented by a 0x00 byte which also ends the string.5436/// 1. when ForStrongLayout is true, following ivars are scanned:5437/// - id, Class5438/// - object *5439/// - __strong anything5440///5441/// 2. When ForStrongLayout is false, following ivars are scanned:5442/// - __weak anything5443///5444llvm::Constant *5445CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,5446                                 CharUnits beginOffset, CharUnits endOffset,5447                                 bool ForStrongLayout, bool HasMRCWeakIvars) {5448  // If this is MRC, and we're either building a strong layout or there5449  // are no weak ivars, bail out early.5450  llvm::Type *PtrTy = CGM.Int8PtrTy;5451  if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&5452      !CGM.getLangOpts().ObjCAutoRefCount &&5453      (ForStrongLayout || !HasMRCWeakIvars))5454    return llvm::Constant::getNullValue(PtrTy);5455 5456  const ObjCInterfaceDecl *OI = OMD->getClassInterface();5457  SmallVector<const ObjCIvarDecl *, 32> ivars;5458 5459  // GC layout strings include the complete object layout, possibly5460  // inaccurately in the non-fragile ABI; the runtime knows how to fix this5461  // up.5462  //5463  // ARC layout strings only include the class's ivars.  In non-fragile5464  // runtimes, that means starting at InstanceStart, rounded up to word5465  // alignment.  In fragile runtimes, there's no InstanceStart, so it means5466  // starting at the offset of the first ivar, rounded up to word alignment.5467  //5468  // MRC weak layout strings follow the ARC style.5469  CharUnits baseOffset;5470  if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {5471    for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); IVD;5472         IVD = IVD->getNextIvar())5473      ivars.push_back(IVD);5474 5475    if (isNonFragileABI()) {5476      baseOffset = beginOffset; // InstanceStart5477    } else if (!ivars.empty()) {5478      baseOffset =5479          CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));5480    } else {5481      baseOffset = CharUnits::Zero();5482    }5483 5484    baseOffset = baseOffset.alignTo(CGM.getPointerAlign());5485  } else {5486    CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);5487 5488    baseOffset = CharUnits::Zero();5489  }5490 5491  if (ivars.empty())5492    return llvm::Constant::getNullValue(PtrTy);5493 5494  IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);5495 5496  builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),5497                         [&](const ObjCIvarDecl *ivar) -> CharUnits {5498                           return CharUnits::fromQuantity(5499                               ComputeIvarBaseOffset(CGM, OMD, ivar));5500                         });5501 5502  if (!builder.hasBitmapData())5503    return llvm::Constant::getNullValue(PtrTy);5504 5505  llvm::SmallVector<unsigned char, 4> buffer;5506  llvm::Constant *C = builder.buildBitmap(*this, buffer);5507 5508  if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {5509    printf("\n%s ivar layout for class '%s': ",5510           ForStrongLayout ? "strong" : "weak",5511           OMD->getClassInterface()->getName().str().c_str());5512    builder.dump(buffer);5513  }5514  return C;5515}5516 5517llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {5518  llvm::GlobalVariable *&Entry = MethodVarNames[Sel];5519  // FIXME: Avoid std::string in "Sel.getAsString()"5520  if (!Entry)5521    Entry =5522        CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);5523  return getConstantGEP(VMContext, Entry, 0, 0);5524}5525 5526// FIXME: Merge into a single cstring creation function.5527llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {5528  return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));5529}5530 5531llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {5532  std::string TypeStr;5533  CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);5534 5535  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];5536  if (!Entry)5537    Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);5538  return getConstantGEP(VMContext, Entry, 0, 0);5539}5540 5541llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,5542                                                  bool Extended) {5543  std::string TypeStr =5544      CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);5545 5546  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];5547  if (!Entry)5548    Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);5549  return getConstantGEP(VMContext, Entry, 0, 0);5550}5551 5552// FIXME: Merge into a single cstring creation function.5553llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {5554  llvm::GlobalVariable *&Entry = PropertyNames[Ident];5555  if (!Entry)5556    Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);5557  return getConstantGEP(VMContext, Entry, 0, 0);5558}5559 5560// FIXME: Merge into a single cstring creation function.5561// FIXME: This Decl should be more precise.5562llvm::Constant *5563CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,5564                                       const Decl *Container) {5565  std::string TypeStr =5566      CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);5567  return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));5568}5569 5570void CGObjCMac::FinishModule() {5571  EmitModuleInfo();5572 5573  // Emit the dummy bodies for any protocols which were referenced but5574  // never defined.5575  for (auto &entry : Protocols) {5576    llvm::GlobalVariable *global = entry.second;5577    if (global->hasInitializer())5578      continue;5579 5580    ConstantInitBuilder builder(CGM);5581    auto values = builder.beginStruct(ObjCTypes.ProtocolTy);5582    values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);5583    values.add(GetClassName(entry.first->getName()));5584    values.addNullPointer(ObjCTypes.ProtocolListPtrTy);5585    values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);5586    values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);5587    values.finishAndSetAsInitializer(global);5588    CGM.addCompilerUsedGlobal(global);5589  }5590 5591  // Add assembler directives to add lazy undefined symbol references5592  // for classes which are referenced but not defined. This is5593  // important for correct linker interaction.5594  //5595  // FIXME: It would be nice if we had an LLVM construct for this.5596  if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&5597      CGM.getTriple().isOSBinFormatMachO()) {5598    SmallString<256> Asm;5599    Asm += CGM.getModule().getModuleInlineAsm();5600    if (!Asm.empty() && Asm.back() != '\n')5601      Asm += '\n';5602 5603    llvm::raw_svector_ostream OS(Asm);5604    for (const auto *Sym : DefinedSymbols)5605      OS << "\t.objc_class_name_" << Sym->getName() << "=0\n"5606         << "\t.globl .objc_class_name_" << Sym->getName() << "\n";5607    for (const auto *Sym : LazySymbols)5608      OS << "\t.lazy_reference .objc_class_name_" << Sym->getName() << "\n";5609    for (const auto &Category : DefinedCategoryNames)5610      OS << "\t.objc_category_name_" << Category << "=0\n"5611         << "\t.globl .objc_category_name_" << Category << "\n";5612 5613    CGM.getModule().setModuleInlineAsm(OS.str());5614  }5615}5616 5617CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)5618    : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),5619      ObjCEmptyVtableVar(nullptr) {5620  ObjCABI = 2;5621}5622 5623/* *** */5624 5625ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)5626    : VMContext(cgm.getLLVMContext()), CGM(cgm) {5627  CodeGen::CodeGenTypes &Types = CGM.getTypes();5628  ASTContext &Ctx = CGM.getContext();5629  unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();5630 5631  ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));5632  IntTy = CGM.IntTy;5633  LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));5634  Int8PtrTy = CGM.Int8PtrTy;5635  Int8PtrProgramASTy = llvm::PointerType::get(CGM.getLLVMContext(), ProgramAS);5636  Int8PtrPtrTy = CGM.Int8PtrPtrTy;5637 5638  // arm64 targets use "int" ivar offset variables. All others,5639  // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.5640  if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)5641    IvarOffsetVarTy = IntTy;5642  else5643    IvarOffsetVarTy = LongTy;5644 5645  ObjectPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));5646  PtrObjectPtrTy = llvm::PointerType::getUnqual(VMContext);5647  SelectorPtrTy =5648      cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));5649 5650  // I'm not sure I like this. The implicit coordination is a bit5651  // gross. We should solve this in a reasonable fashion because this5652  // is a pretty common task (match some runtime data structure with5653  // an LLVM data structure).5654 5655  // FIXME: This is leaked.5656  // FIXME: Merge with rewriter code?5657 5658  // struct _objc_super {5659  //   id self;5660  //   Class cls;5661  // }5662  RecordDecl *RD = RecordDecl::Create(5663      Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),5664      SourceLocation(), &Ctx.Idents.get("_objc_super"));5665  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),5666                                nullptr, Ctx.getObjCIdType(), nullptr, nullptr,5667                                false, ICIS_NoInit));5668  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),5669                                nullptr, Ctx.getObjCClassType(), nullptr,5670                                nullptr, false, ICIS_NoInit));5671  RD->completeDefinition();5672 5673  SuperCTy = Ctx.getCanonicalTagType(RD);5674  SuperPtrCTy = Ctx.getPointerType(SuperCTy);5675 5676  SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));5677  SuperPtrTy = llvm::PointerType::getUnqual(VMContext);5678 5679  // struct _prop_t {5680  //   char *name;5681  //   char *attributes;5682  // }5683  PropertyTy = llvm::StructType::create("struct._prop_t", Int8PtrTy, Int8PtrTy);5684 5685  // struct _prop_list_t {5686  //   uint32_t entsize;      // sizeof(struct _prop_t)5687  //   uint32_t count_of_properties;5688  //   struct _prop_t prop_list[count_of_properties];5689  // }5690  PropertyListTy = llvm::StructType::create(5691      "struct._prop_list_t", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));5692  // struct _prop_list_t *5693  PropertyListPtrTy = llvm::PointerType::getUnqual(VMContext);5694 5695  // struct _objc_method {5696  //   SEL _cmd;5697  //   char *method_type;5698  //   char *_imp;5699  // }5700  MethodTy = llvm::StructType::create("struct._objc_method", SelectorPtrTy,5701                                      Int8PtrTy, Int8PtrProgramASTy);5702 5703  // struct _objc_cache *5704  CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");5705  CachePtrTy = llvm::PointerType::getUnqual(VMContext);5706}5707 5708ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)5709    : ObjCCommonTypesHelper(cgm) {5710  // struct _objc_method_description {5711  //   SEL name;5712  //   char *types;5713  // }5714  MethodDescriptionTy = llvm::StructType::create(5715      "struct._objc_method_description", SelectorPtrTy, Int8PtrTy);5716 5717  // struct _objc_method_description_list {5718  //   int count;5719  //   struct _objc_method_description[1];5720  // }5721  MethodDescriptionListTy =5722      llvm::StructType::create("struct._objc_method_description_list", IntTy,5723                               llvm::ArrayType::get(MethodDescriptionTy, 0));5724 5725  // struct _objc_method_description_list *5726  MethodDescriptionListPtrTy = llvm::PointerType::getUnqual(VMContext);5727 5728  // Protocol description structures5729 5730  // struct _objc_protocol_extension {5731  //   uint32_t size;  // sizeof(struct _objc_protocol_extension)5732  //   struct _objc_method_description_list *optional_instance_methods;5733  //   struct _objc_method_description_list *optional_class_methods;5734  //   struct _objc_property_list *instance_properties;5735  //   const char ** extendedMethodTypes;5736  //   struct _objc_property_list *class_properties;5737  // }5738  ProtocolExtensionTy = llvm::StructType::create(5739      "struct._objc_protocol_extension", IntTy, MethodDescriptionListPtrTy,5740      MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,5741      PropertyListPtrTy);5742 5743  // struct _objc_protocol_extension *5744  ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);5745 5746  // Handle construction of Protocol and ProtocolList types5747 5748  // struct _objc_protocol {5749  //   struct _objc_protocol_extension *isa;5750  //   char *protocol_name;5751  //   struct _objc_protocol **_objc_protocol_list;5752  //   struct _objc_method_description_list *instance_methods;5753  //   struct _objc_method_description_list *class_methods;5754  // }5755  ProtocolTy = llvm::StructType::create(5756      {ProtocolExtensionPtrTy, Int8PtrTy,5757       llvm::PointerType::getUnqual(VMContext), MethodDescriptionListPtrTy,5758       MethodDescriptionListPtrTy},5759      "struct._objc_protocol");5760 5761  ProtocolListTy =5762      llvm::StructType::create({llvm::PointerType::getUnqual(VMContext), LongTy,5763                                llvm::ArrayType::get(ProtocolTy, 0)},5764                               "struct._objc_protocol_list");5765 5766  // struct _objc_protocol_list *5767  ProtocolListPtrTy = llvm::PointerType::getUnqual(VMContext);5768 5769  ProtocolPtrTy = llvm::PointerType::getUnqual(VMContext);5770 5771  // Class description structures5772 5773  // struct _objc_ivar {5774  //   char *ivar_name;5775  //   char *ivar_type;5776  //   int  ivar_offset;5777  // }5778  IvarTy = llvm::StructType::create("struct._objc_ivar", Int8PtrTy, Int8PtrTy,5779                                    IntTy);5780 5781  // struct _objc_ivar_list *5782  IvarListTy = llvm::StructType::create(VMContext, "struct._objc_ivar_list");5783  IvarListPtrTy = llvm::PointerType::getUnqual(VMContext);5784 5785  // struct _objc_method_list *5786  MethodListTy =5787      llvm::StructType::create(VMContext, "struct._objc_method_list");5788  MethodListPtrTy = llvm::PointerType::getUnqual(VMContext);5789 5790  // struct _objc_class_extension *5791  ClassExtensionTy = llvm::StructType::create(5792      "struct._objc_class_extension", IntTy, Int8PtrTy, PropertyListPtrTy);5793  ClassExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);5794 5795  // struct _objc_class {5796  //   Class isa;5797  //   Class super_class;5798  //   char *name;5799  //   long version;5800  //   long info;5801  //   long instance_size;5802  //   struct _objc_ivar_list *ivars;5803  //   struct _objc_method_list *methods;5804  //   struct _objc_cache *cache;5805  //   struct _objc_protocol_list *protocols;5806  //   char *ivar_layout;5807  //   struct _objc_class_ext *ext;5808  // };5809  ClassTy = llvm::StructType::create(5810      {llvm::PointerType::getUnqual(VMContext),5811       llvm::PointerType::getUnqual(VMContext), Int8PtrTy, LongTy, LongTy,5812       LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy,5813       Int8PtrTy, ClassExtensionPtrTy},5814      "struct._objc_class");5815 5816  ClassPtrTy = llvm::PointerType::getUnqual(VMContext);5817 5818  // struct _objc_category {5819  //   char *category_name;5820  //   char *class_name;5821  //   struct _objc_method_list *instance_method;5822  //   struct _objc_method_list *class_method;5823  //   struct _objc_protocol_list *protocols;5824  //   uint32_t size;  // sizeof(struct _objc_category)5825  //   struct _objc_property_list *instance_properties;// category's @property5826  //   struct _objc_property_list *class_properties;5827  // }5828  CategoryTy = llvm::StructType::create(5829      "struct._objc_category", Int8PtrTy, Int8PtrTy, MethodListPtrTy,5830      MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,5831      PropertyListPtrTy);5832 5833  // Global metadata structures5834 5835  // struct _objc_symtab {5836  //   long sel_ref_cnt;5837  //   SEL *refs;5838  //   short cls_def_cnt;5839  //   short cat_def_cnt;5840  //   char *defs[cls_def_cnt + cat_def_cnt];5841  // }5842  SymtabTy = llvm::StructType::create("struct._objc_symtab", LongTy,5843                                      SelectorPtrTy, ShortTy, ShortTy,5844                                      llvm::ArrayType::get(Int8PtrTy, 0));5845  SymtabPtrTy = llvm::PointerType::getUnqual(VMContext);5846 5847  // struct _objc_module {5848  //   long version;5849  //   long size;   // sizeof(struct _objc_module)5850  //   char *name;5851  //   struct _objc_symtab* symtab;5852  //  }5853  ModuleTy = llvm::StructType::create("struct._objc_module", LongTy, LongTy,5854                                      Int8PtrTy, SymtabPtrTy);5855 5856  // FIXME: This is the size of the setjmp buffer and should be target5857  // specific. 18 is what's used on 32-bit X86.5858  uint64_t SetJmpBufferSize = 18;5859 5860  // Exceptions5861  llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);5862 5863  ExceptionDataTy = llvm::StructType::create(5864      "struct._objc_exception_data",5865      llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);5866}5867 5868ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(5869    CodeGen::CodeGenModule &cgm)5870    : ObjCCommonTypesHelper(cgm) {5871  // struct _method_list_t {5872  //   uint32_t entsize;  // sizeof(struct _objc_method)5873  //   uint32_t method_count;5874  //   struct _objc_method method_list[method_count];5875  // }5876  MethodListnfABITy =5877      llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,5878                               llvm::ArrayType::get(MethodTy, 0));5879  // struct method_list_t *5880  MethodListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);5881 5882  // struct _protocol_t {5883  //   id isa;  // NULL5884  //   const char * const protocol_name;5885  //   const struct _protocol_list_t * protocol_list; // super protocols5886  //   const struct method_list_t * const instance_methods;5887  //   const struct method_list_t * const class_methods;5888  //   const struct method_list_t *optionalInstanceMethods;5889  //   const struct method_list_t *optionalClassMethods;5890  //   const struct _prop_list_t * properties;5891  //   const uint32_t size;  // sizeof(struct _protocol_t)5892  //   const uint32_t flags;  // = 05893  //   const char ** extendedMethodTypes;5894  //   const char *demangledName;5895  //   const struct _prop_list_t * class_properties;5896  // }5897 5898  ProtocolnfABITy = llvm::StructType::create(5899      "struct._protocol_t", ObjectPtrTy, Int8PtrTy,5900      llvm::PointerType::getUnqual(VMContext), MethodListnfABIPtrTy,5901      MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,5902      PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,5903      PropertyListPtrTy);5904 5905  // struct _protocol_t*5906  ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);5907 5908  // struct _protocol_list_t {5909  //   long protocol_count;   // Note, this is 32/64 bit5910  //   struct _protocol_t *[protocol_count];5911  // }5912  ProtocolListnfABITy = llvm::StructType::create(5913      {LongTy, llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)},5914      "struct._objc_protocol_list");5915 5916  // struct _objc_protocol_list*5917  ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);5918 5919  // struct _ivar_t {5920  //   unsigned [long] int *offset;  // pointer to ivar offset location5921  //   char *name;5922  //   char *type;5923  //   uint32_t alignment;5924  //   uint32_t size;5925  // }5926  IvarnfABITy = llvm::StructType::create(5927      "struct._ivar_t", llvm::PointerType::getUnqual(VMContext), Int8PtrTy,5928      Int8PtrTy, IntTy, IntTy);5929 5930  // struct _ivar_list_t {5931  //   uint32 entsize;  // sizeof(struct _ivar_t)5932  //   uint32 count;5933  //   struct _iver_t list[count];5934  // }5935  IvarListnfABITy =5936      llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,5937                               llvm::ArrayType::get(IvarnfABITy, 0));5938 5939  IvarListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);5940 5941  // struct _class_ro_t {5942  //   uint32_t const flags;5943  //   uint32_t const instanceStart;5944  //   uint32_t const instanceSize;5945  //   uint32_t const reserved;  // only when building for 64bit targets5946  //   const uint8_t * const ivarLayout;5947  //   const char *const name;5948  //   const struct _method_list_t * const baseMethods;5949  //   const struct _objc_protocol_list *const baseProtocols;5950  //   const struct _ivar_list_t *const ivars;5951  //   const uint8_t * const weakIvarLayout;5952  //   const struct _prop_list_t * const properties;5953  // }5954 5955  // FIXME. Add 'reserved' field in 64bit abi mode!5956  ClassRonfABITy = llvm::StructType::create(5957      "struct._class_ro_t", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,5958      MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,5959      Int8PtrTy, PropertyListPtrTy);5960 5961  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)5962  ImpnfABITy = CGM.DefaultPtrTy;5963 5964  // struct _class_t {5965  //   struct _class_t *isa;5966  //   struct _class_t * const superclass;5967  //   void *cache;5968  //   IMP *vtable;5969  //   struct class_ro_t *ro;5970  // }5971 5972  ClassnfABITy = llvm::StructType::create(5973      {llvm::PointerType::getUnqual(VMContext),5974       llvm::PointerType::getUnqual(VMContext), CachePtrTy,5975       llvm::PointerType::getUnqual(VMContext),5976       llvm::PointerType::getUnqual(VMContext)},5977      "struct._class_t");5978 5979  // LLVM for struct _class_t *5980  ClassnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);5981 5982  // struct _category_t {5983  //   const char * const name;5984  //   struct _class_t *const cls;5985  //   const struct _method_list_t * const instance_methods;5986  //   const struct _method_list_t * const class_methods;5987  //   const struct _protocol_list_t * const protocols;5988  //   const struct _prop_list_t * const properties;5989  //   const struct _prop_list_t * const class_properties;5990  //   const uint32_t size;5991  // }5992  CategorynfABITy = llvm::StructType::create(5993      "struct._category_t", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,5994      MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,5995      PropertyListPtrTy, IntTy);5996 5997  // New types for nonfragile abi messaging.5998  CodeGen::CodeGenTypes &Types = CGM.getTypes();5999  ASTContext &Ctx = CGM.getContext();6000 6001  // MessageRefTy - LLVM for:6002  // struct _message_ref_t {6003  //   IMP messenger;6004  //   SEL name;6005  // };6006 6007  // First the clang type for struct _message_ref_t6008  RecordDecl *RD = RecordDecl::Create(6009      Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),6010      SourceLocation(), &Ctx.Idents.get("_message_ref_t"));6011  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),6012                                nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,6013                                ICIS_NoInit));6014  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),6015                                nullptr, Ctx.getObjCSelType(), nullptr, nullptr,6016                                false, ICIS_NoInit));6017  RD->completeDefinition();6018 6019  MessageRefCTy = Ctx.getCanonicalTagType(RD);6020  MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);6021  MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));6022 6023  // MessageRefPtrTy - LLVM for struct _message_ref_t*6024  MessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);6025 6026  // SuperMessageRefTy - LLVM for:6027  // struct _super_message_ref_t {6028  //   SUPER_IMP messenger;6029  //   SEL name;6030  // };6031  SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t",6032                                               ImpnfABITy, SelectorPtrTy);6033 6034  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*6035  SuperMessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);6036 6037  // struct objc_typeinfo {6038  //   const void** vtable; // objc_ehtype_vtable + 26039  //   const char*  name;    // c++ typeinfo string6040  //   Class        cls;6041  // };6042  EHTypeTy = llvm::StructType::create("struct._objc_typeinfo",6043                                      llvm::PointerType::getUnqual(VMContext),6044                                      Int8PtrTy, ClassnfABIPtrTy);6045  EHTypePtrTy = llvm::PointerType::getUnqual(VMContext);6046}6047 6048llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {6049  FinishNonFragileABIModule();6050 6051  return nullptr;6052}6053 6054void CGObjCNonFragileABIMac::AddModuleClassList(6055    ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,6056    StringRef SectionName) {6057  unsigned NumClasses = Container.size();6058 6059  if (!NumClasses)6060    return;6061 6062  SmallVector<llvm::Constant *, 8> Symbols(NumClasses);6063  for (unsigned i = 0; i < NumClasses; i++)6064    Symbols[i] = Container[i];6065 6066  llvm::Constant *Init = llvm::ConstantArray::get(6067      llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Symbols.size()), Symbols);6068 6069  // Section name is obtained by calling GetSectionName, which returns6070  // sections in the __DATA segment on MachO.6071  assert((!CGM.getTriple().isOSBinFormatMachO() ||6072          SectionName.starts_with("__DATA")) &&6073         "SectionName expected to start with __DATA on MachO");6074  llvm::GlobalVariable *GV = new llvm::GlobalVariable(6075      CGM.getModule(), Init->getType(), false,6076      llvm::GlobalValue::PrivateLinkage, Init, SymbolName);6077  GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Init->getType()));6078  GV->setSection(SectionName);6079  CGM.addCompilerUsedGlobal(GV);6080}6081 6082void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {6083  // nonfragile abi has no module definition.6084 6085  // Build list of all implemented class addresses in array6086  // L_OBJC_LABEL_CLASS_$.6087 6088  for (unsigned i = 0, NumClasses = ImplementedClasses.size(); i < NumClasses;6089       i++) {6090    const ObjCInterfaceDecl *ID = ImplementedClasses[i];6091    assert(ID);6092    if (ObjCImplementationDecl *IMP = ID->getImplementation())6093      // We are implementing a weak imported interface. Give it external linkage6094      if (ID->isWeakImported() && !IMP->isWeakImported()) {6095        DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);6096        DefinedMetaClasses[i]->setLinkage(6097            llvm::GlobalVariable::ExternalLinkage);6098      }6099  }6100 6101  AddModuleClassList(6102      DefinedClasses, "OBJC_LABEL_CLASS_$",6103      GetSectionName("__objc_classlist", "regular,no_dead_strip"));6104 6105  AddModuleClassList(6106      DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$",6107      GetSectionName("__objc_nlclslist", "regular,no_dead_strip"));6108 6109  // Build list of all implemented category addresses in array6110  // L_OBJC_LABEL_CATEGORY_$.6111  AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$",6112                     GetSectionName("__objc_catlist", "regular,no_dead_strip"));6113  AddModuleClassList(6114      DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$",6115      GetSectionName("__objc_catlist2", "regular,no_dead_strip"));6116  AddModuleClassList(6117      DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$",6118      GetSectionName("__objc_nlcatlist", "regular,no_dead_strip"));6119 6120  EmitImageInfo();6121}6122 6123/// isVTableDispatchedSelector - Returns true if SEL is not in the list of6124/// VTableDispatchMethods; false otherwise. What this means is that6125/// except for the 19 selectors in the list, we generate 32bit-style6126/// message dispatch call for all the rest.6127bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {6128  // At various points we've experimented with using vtable-based6129  // dispatch for all methods.6130  switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {6131  case CodeGenOptions::Legacy:6132    return false;6133  case CodeGenOptions::NonLegacy:6134    return true;6135  case CodeGenOptions::Mixed:6136    break;6137  }6138 6139  // If so, see whether this selector is in the white-list of things which must6140  // use the new dispatch convention. We lazily build a dense set for this.6141  if (VTableDispatchMethods.empty()) {6142    VTableDispatchMethods.insert(GetNullarySelector("alloc"));6143    VTableDispatchMethods.insert(GetNullarySelector("class"));6144    VTableDispatchMethods.insert(GetNullarySelector("self"));6145    VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));6146    VTableDispatchMethods.insert(GetNullarySelector("length"));6147    VTableDispatchMethods.insert(GetNullarySelector("count"));6148 6149    // These are vtable-based if GC is disabled.6150    // Optimistically use vtable dispatch for hybrid compiles.6151    if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {6152      VTableDispatchMethods.insert(GetNullarySelector("retain"));6153      VTableDispatchMethods.insert(GetNullarySelector("release"));6154      VTableDispatchMethods.insert(GetNullarySelector("autorelease"));6155    }6156 6157    VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));6158    VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));6159    VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));6160    VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));6161    VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));6162    VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));6163    VTableDispatchMethods.insert(GetUnarySelector("isEqual"));6164 6165    // These are vtable-based if GC is enabled.6166    // Optimistically use vtable dispatch for hybrid compiles.6167    if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {6168      VTableDispatchMethods.insert(GetNullarySelector("hash"));6169      VTableDispatchMethods.insert(GetUnarySelector("addObject"));6170 6171      // "countByEnumeratingWithState:objects:count"6172      const IdentifierInfo *KeyIdents[] = {6173          &CGM.getContext().Idents.get("countByEnumeratingWithState"),6174          &CGM.getContext().Idents.get("objects"),6175          &CGM.getContext().Idents.get("count")};6176      VTableDispatchMethods.insert(6177          CGM.getContext().Selectors.getSelector(3, KeyIdents));6178    }6179  }6180 6181  return VTableDispatchMethods.count(Sel);6182}6183 6184/// BuildClassRoTInitializer - generate meta-data for:6185/// struct _class_ro_t {6186///   uint32_t const flags;6187///   uint32_t const instanceStart;6188///   uint32_t const instanceSize;6189///   uint32_t const reserved;  // only when building for 64bit targets6190///   const uint8_t * const ivarLayout;6191///   const char *const name;6192///   const struct _method_list_t * const baseMethods;6193///   const struct _protocol_list_t *const baseProtocols;6194///   const struct _ivar_list_t *const ivars;6195///   const uint8_t * const weakIvarLayout;6196///   const struct _prop_list_t * const properties;6197/// }6198///6199llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassRoTInitializer(6200    unsigned flags, unsigned InstanceStart, unsigned InstanceSize,6201    const ObjCImplementationDecl *ID) {6202  std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());6203 6204  CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);6205  CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);6206 6207  bool hasMRCWeak = false;6208  if (CGM.getLangOpts().ObjCAutoRefCount)6209    flags |= NonFragileABI_Class_CompiledByARC;6210  else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))6211    flags |= NonFragileABI_Class_HasMRCWeakIvars;6212 6213  ConstantInitBuilder builder(CGM);6214  auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);6215 6216  values.addInt(ObjCTypes.IntTy, flags);6217  values.addInt(ObjCTypes.IntTy, InstanceStart);6218  values.addInt(ObjCTypes.IntTy, InstanceSize);6219  values.add((flags & NonFragileABI_Class_Meta)6220                 ? GetIvarLayoutName(nullptr, ObjCTypes)6221                 : BuildStrongIvarLayout(ID, beginInstance, endInstance));6222  values.add(GetClassName(ID->getObjCRuntimeNameAsString()));6223 6224  // const struct _method_list_t * const baseMethods;6225  SmallVector<const ObjCMethodDecl *, 16> methods;6226  if (flags & NonFragileABI_Class_Meta) {6227    for (const auto *MD : ID->class_methods())6228      if (!MD->isDirectMethod())6229        methods.push_back(MD);6230  } else {6231    for (const auto *MD : ID->instance_methods())6232      if (!MD->isDirectMethod())6233        methods.push_back(MD);6234  }6235 6236  llvm::Constant *MethListPtr = emitMethodList(6237      ID->getObjCRuntimeNameAsString(),6238      (flags & NonFragileABI_Class_Meta) ? MethodListType::ClassMethods6239                                         : MethodListType::InstanceMethods,6240      methods);6241 6242  const PointerAuthSchema &MethListSchema =6243      CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;6244  if (!MethListPtr->isNullValue())6245    values.addSignedPointer(MethListPtr, MethListSchema, GlobalDecl(),6246                            QualType());6247  else6248    values.add(MethListPtr);6249 6250  const ObjCInterfaceDecl *OID = ID->getClassInterface();6251  assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");6252  values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_" +6253                                  OID->getObjCRuntimeNameAsString(),6254                              OID->all_referenced_protocol_begin(),6255                              OID->all_referenced_protocol_end()));6256 6257  if (flags & NonFragileABI_Class_Meta) {6258    values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);6259    values.add(GetIvarLayoutName(nullptr, ObjCTypes));6260    values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" +6261                                    ID->getObjCRuntimeNameAsString(),6262                                ID, ID->getClassInterface(), ObjCTypes, true));6263  } else {6264    values.add(EmitIvarList(ID));6265    values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));6266    values.add(EmitPropertyList("_OBJC_$_PROP_LIST_" +6267                                    ID->getObjCRuntimeNameAsString(),6268                                ID, ID->getClassInterface(), ObjCTypes, false));6269  }6270 6271  llvm::SmallString<64> roLabel;6272  llvm::raw_svector_ostream(roLabel)6273      << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_"6274                                             : "_OBJC_CLASS_RO_$_")6275      << ClassName;6276 6277  return finishAndCreateGlobal(values, roLabel, CGM);6278}6279 6280/// Build the metaclass object for a class.6281///6282/// struct _class_t {6283///   struct _class_t *isa;6284///   struct _class_t * const superclass;6285///   void *cache;6286///   IMP *vtable;6287///   struct class_ro_t *ro;6288/// }6289///6290llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassObject(6291    const ObjCInterfaceDecl *CI, bool isMetaclass, llvm::Constant *IsAGV,6292    llvm::Constant *SuperClassGV, llvm::Constant *ClassRoGV,6293    bool HiddenVisibility) {6294  ConstantInitBuilder builder(CGM);6295  auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);6296  const PointerAuthOptions &PointerAuthOpts = CGM.getCodeGenOpts().PointerAuth;6297  values.addSignedPointer(IsAGV, PointerAuthOpts.ObjCIsaPointers, GlobalDecl(),6298                          QualType());6299  if (SuperClassGV)6300    values.addSignedPointer(SuperClassGV, PointerAuthOpts.ObjCSuperPointers,6301                            GlobalDecl(), QualType());6302  else6303    values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);6304 6305  values.add(ObjCEmptyCacheVar);6306  values.add(ObjCEmptyVtableVar);6307 6308  values.addSignedPointer(ClassRoGV, PointerAuthOpts.ObjCClassROPointers,6309                          GlobalDecl(), QualType());6310 6311  llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(6312      GetClassGlobal(CI, isMetaclass, ForDefinition));6313  values.finishAndSetAsInitializer(GV);6314 6315  if (CGM.getTriple().isOSBinFormatMachO())6316    GV->setSection("__DATA, __objc_data");6317  GV->setAlignment(CGM.getDataLayout().getABITypeAlign(ObjCTypes.ClassnfABITy));6318  if (!CGM.getTriple().isOSBinFormatCOFF())6319    if (HiddenVisibility)6320      GV->setVisibility(llvm::GlobalValue::HiddenVisibility);6321  return GV;6322}6323 6324bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(6325    const ObjCImplDecl *OD) const {6326  return OD->getClassMethod(GetNullarySelector("load")) != nullptr ||6327         OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||6328         OD->hasAttr<ObjCNonLazyClassAttr>();6329}6330 6331void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,6332                                              uint32_t &InstanceStart,6333                                              uint32_t &InstanceSize) {6334  const ASTRecordLayout &RL =6335      CGM.getContext().getASTObjCInterfaceLayout(OID->getClassInterface());6336 6337  // InstanceSize is really instance end.6338  InstanceSize = RL.getDataSize().getQuantity();6339 6340  // If there are no fields, the start is the same as the end.6341  if (!RL.getFieldCount())6342    InstanceStart = InstanceSize;6343  else6344    InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();6345}6346 6347static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,6348                                                          StringRef Name) {6349  IdentifierInfo &II = CGM.getContext().Idents.get(Name);6350  TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();6351  DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);6352 6353  const VarDecl *VD = nullptr;6354  for (const auto *Result : DC->lookup(&II))6355    if ((VD = dyn_cast<VarDecl>(Result)))6356      break;6357 6358  if (!VD)6359    return llvm::GlobalValue::DLLImportStorageClass;6360  if (VD->hasAttr<DLLExportAttr>())6361    return llvm::GlobalValue::DLLExportStorageClass;6362  if (VD->hasAttr<DLLImportAttr>())6363    return llvm::GlobalValue::DLLImportStorageClass;6364  return llvm::GlobalValue::DefaultStorageClass;6365}6366 6367void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {6368  if (!ObjCEmptyCacheVar) {6369    ObjCEmptyCacheVar = new llvm::GlobalVariable(6370        CGM.getModule(), ObjCTypes.CacheTy, false,6371        llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache");6372    if (CGM.getTriple().isOSBinFormatCOFF())6373      ObjCEmptyCacheVar->setDLLStorageClass(6374          getStorage(CGM, "_objc_empty_cache"));6375 6376    // Only OS X with deployment version <10.9 use the empty vtable symbol6377    const llvm::Triple &Triple = CGM.getTarget().getTriple();6378    if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))6379      ObjCEmptyVtableVar = new llvm::GlobalVariable(6380          CGM.getModule(), ObjCTypes.ImpnfABITy, false,6381          llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_vtable");6382    else6383      ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(CGM.DefaultPtrTy);6384  }6385 6386  // FIXME: Is this correct (that meta class size is never computed)?6387  uint32_t InstanceStart =6388      CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);6389  uint32_t InstanceSize = InstanceStart;6390  uint32_t flags = NonFragileABI_Class_Meta;6391 6392  llvm::Constant *SuperClassGV, *IsAGV;6393 6394  const auto *CI = ID->getClassInterface();6395  assert(CI && "CGObjCNonFragileABIMac::GenerateClass - class is 0");6396 6397  // Build the flags for the metaclass.6398  bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())6399                           ? !CI->hasAttr<DLLExportAttr>()6400                           : CI->getVisibility() == HiddenVisibility;6401  if (classIsHidden)6402    flags |= NonFragileABI_Class_Hidden;6403 6404  // FIXME: why is this flag set on the metaclass?6405  // ObjC metaclasses have no fields and don't really get constructed.6406  if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {6407    flags |= NonFragileABI_Class_HasCXXStructors;6408    if (!ID->hasNonZeroConstructors())6409      flags |= NonFragileABI_Class_HasCXXDestructorOnly;6410  }6411 6412  if (!CI->getSuperClass()) {6413    // class is root6414    flags |= NonFragileABI_Class_Root;6415 6416    SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);6417    IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);6418  } else {6419    // Has a root. Current class is not a root.6420    const ObjCInterfaceDecl *Root = ID->getClassInterface();6421    while (const ObjCInterfaceDecl *Super = Root->getSuperClass())6422      Root = Super;6423 6424    const auto *Super = CI->getSuperClass();6425    IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);6426    SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);6427  }6428 6429  llvm::GlobalVariable *CLASS_RO_GV =6430      BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);6431 6432  llvm::GlobalVariable *MetaTClass = BuildClassObject(6433      CI, /*metaclass*/ true, IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);6434  CGM.setGVProperties(MetaTClass, CI);6435  DefinedMetaClasses.push_back(MetaTClass);6436 6437  // Metadata for the class6438  flags = 0;6439  if (classIsHidden)6440    flags |= NonFragileABI_Class_Hidden;6441 6442  if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {6443    flags |= NonFragileABI_Class_HasCXXStructors;6444 6445    // Set a flag to enable a runtime optimization when a class has6446    // fields that require destruction but which don't require6447    // anything except zero-initialization during construction.  This6448    // is most notably true of __strong and __weak types, but you can6449    // also imagine there being C++ types with non-trivial default6450    // constructors that merely set all fields to null.6451    if (!ID->hasNonZeroConstructors())6452      flags |= NonFragileABI_Class_HasCXXDestructorOnly;6453  }6454 6455  if (hasObjCExceptionAttribute(CGM.getContext(), CI))6456    flags |= NonFragileABI_Class_Exception;6457 6458  if (!CI->getSuperClass()) {6459    flags |= NonFragileABI_Class_Root;6460    SuperClassGV = nullptr;6461  } else {6462    // Has a root. Current class is not a root.6463    const auto *Super = CI->getSuperClass();6464    SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);6465  }6466 6467  GetClassSizeInfo(ID, InstanceStart, InstanceSize);6468  CLASS_RO_GV =6469      BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);6470 6471  llvm::GlobalVariable *ClassMD =6472      BuildClassObject(CI, /*metaclass*/ false, MetaTClass, SuperClassGV,6473                       CLASS_RO_GV, classIsHidden);6474  CGM.setGVProperties(ClassMD, CI);6475  DefinedClasses.push_back(ClassMD);6476  ImplementedClasses.push_back(CI);6477 6478  // Determine if this class is also "non-lazy".6479  if (ImplementationIsNonLazy(ID))6480    DefinedNonLazyClasses.push_back(ClassMD);6481 6482  // Force the definition of the EHType if necessary.6483  if (flags & NonFragileABI_Class_Exception)6484    (void)GetInterfaceEHType(CI, ForDefinition);6485  // Make sure method definition entries are all clear for next implementation.6486  MethodDefinitions.clear();6487}6488 6489/// GenerateProtocolRef - This routine is called to generate code for6490/// a protocol reference expression; as in:6491/// @code6492///   @protocol(Proto1);6493/// @endcode6494/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto16495/// which will hold address of the protocol meta-data.6496///6497llvm::Value *6498CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,6499                                            const ObjCProtocolDecl *PD) {6500 6501  // This routine is called for @protocol only. So, we must build definition6502  // of protocol's meta-data (not a reference to it!)6503  assert(!PD->isNonRuntimeProtocol() &&6504         "attempting to get a protocol ref to a static protocol.");6505  llvm::Constant *Init = GetOrEmitProtocol(PD);6506 6507  std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_");6508  ProtocolName += PD->getObjCRuntimeNameAsString();6509 6510  CharUnits Align = CGF.getPointerAlign();6511 6512  llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);6513  if (PTGV)6514    return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);6515  PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,6516                                  llvm::GlobalValue::WeakAnyLinkage, Init,6517                                  ProtocolName);6518  PTGV->setSection(6519      GetSectionName("__objc_protorefs", "coalesced,no_dead_strip"));6520  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);6521  PTGV->setAlignment(Align.getAsAlign());6522  if (!CGM.getTriple().isOSBinFormatMachO())6523    PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));6524  CGM.addUsedGlobal(PTGV);6525  return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);6526}6527 6528/// GenerateCategory - Build metadata for a category implementation.6529/// struct _category_t {6530///   const char * const name;6531///   struct _class_t *const cls;6532///   const struct _method_list_t * const instance_methods;6533///   const struct _method_list_t * const class_methods;6534///   const struct _protocol_list_t * const protocols;6535///   const struct _prop_list_t * const properties;6536///   const struct _prop_list_t * const class_properties;6537///   const uint32_t size;6538/// }6539///6540void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {6541  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();6542  const char *Prefix = "_OBJC_$_CATEGORY_";6543 6544  llvm::SmallString<64> ExtCatName(Prefix);6545  ExtCatName += Interface->getObjCRuntimeNameAsString();6546  ExtCatName += "_$_";6547  ExtCatName += OCD->getNameAsString();6548 6549  ConstantInitBuilder builder(CGM);6550  auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);6551  values.add(GetClassName(OCD->getIdentifier()->getName()));6552  // meta-class entry symbol6553  values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));6554  std::string listName =6555      (Interface->getObjCRuntimeNameAsString() + "_$_" + OCD->getName()).str();6556 6557  SmallVector<const ObjCMethodDecl *, 16> instanceMethods;6558  SmallVector<const ObjCMethodDecl *, 8> classMethods;6559  for (const auto *MD : OCD->methods()) {6560    if (MD->isDirectMethod())6561      continue;6562    if (MD->isInstanceMethod()) {6563      instanceMethods.push_back(MD);6564    } else {6565      classMethods.push_back(MD);6566    }6567  }6568 6569  llvm::Constant *InstanceMethodList = emitMethodList(6570      listName, MethodListType::CategoryInstanceMethods, instanceMethods);6571  const PointerAuthSchema &MethListSchema =6572      CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;6573  if (!InstanceMethodList->isNullValue())6574    values.addSignedPointer(InstanceMethodList, MethListSchema, GlobalDecl(),6575                            QualType());6576  else6577    values.add(InstanceMethodList);6578 6579  llvm::Constant *ClassMethodList = emitMethodList(6580      listName, MethodListType::CategoryClassMethods, classMethods);6581  if (!ClassMethodList->isNullValue())6582    values.addSignedPointer(ClassMethodList, MethListSchema, GlobalDecl(),6583                            QualType());6584  else6585    values.add(ClassMethodList);6586 6587  // Keep track of whether we have actual metadata to emit.6588  bool isEmptyCategory =6589      InstanceMethodList->isNullValue() && ClassMethodList->isNullValue();6590 6591  const ObjCCategoryDecl *Category =6592      Interface->FindCategoryDeclaration(OCD->getIdentifier());6593  if (Category) {6594    SmallString<256> ExtName;6595    llvm::raw_svector_ostream(ExtName)6596        << Interface->getObjCRuntimeNameAsString() << "_$_" << OCD->getName();6597    auto protocolList =6598        EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_" +6599                             Interface->getObjCRuntimeNameAsString() + "_$_" +6600                             Category->getName(),6601                         Category->protocol_begin(), Category->protocol_end());6602    auto propertyList = EmitPropertyList("_OBJC_$_PROP_LIST_" + ExtName.str(),6603                                         OCD, Category, ObjCTypes, false);6604    auto classPropertyList =6605        EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), OCD,6606                         Category, ObjCTypes, true);6607    values.add(protocolList);6608    values.add(propertyList);6609    values.add(classPropertyList);6610    isEmptyCategory &= protocolList->isNullValue() &&6611                       propertyList->isNullValue() &&6612                       classPropertyList->isNullValue();6613  } else {6614    values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);6615    values.addNullPointer(ObjCTypes.PropertyListPtrTy);6616    values.addNullPointer(ObjCTypes.PropertyListPtrTy);6617  }6618 6619  if (isEmptyCategory) {6620    // Empty category, don't emit any metadata.6621    values.abandon();6622    MethodDefinitions.clear();6623    return;6624  }6625 6626  unsigned Size =6627      CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);6628  values.addInt(ObjCTypes.IntTy, Size);6629 6630  llvm::GlobalVariable *GCATV =6631      finishAndCreateGlobal(values, ExtCatName.str(), CGM);6632  CGM.addCompilerUsedGlobal(GCATV);6633  if (Interface->hasAttr<ObjCClassStubAttr>())6634    DefinedStubCategories.push_back(GCATV);6635  else6636    DefinedCategories.push_back(GCATV);6637 6638  // Determine if this category is also "non-lazy".6639  if (ImplementationIsNonLazy(OCD))6640    DefinedNonLazyCategories.push_back(GCATV);6641  // method definition entries must be clear for next implementation.6642  MethodDefinitions.clear();6643}6644 6645/// emitMethodConstant - Return a struct objc_method constant.  If6646/// forProtocol is true, the implementation will be null; otherwise,6647/// the method must have a definition registered with the runtime.6648///6649/// struct _objc_method {6650///   SEL _cmd;6651///   char *method_type;6652///   char *_imp;6653/// }6654void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,6655                                                const ObjCMethodDecl *MD,6656                                                bool forProtocol) {6657  auto method = builder.beginStruct(ObjCTypes.MethodTy);6658  method.add(GetMethodVarName(MD->getSelector()));6659  method.add(GetMethodVarType(MD));6660 6661  if (forProtocol) {6662    // Protocol methods have no implementation. So, this entry is always NULL.6663    method.addNullPointer(ObjCTypes.Int8PtrProgramASTy);6664  } else {6665    llvm::Function *fn = GetMethodDefinition(MD);6666    assert(fn && "no definition for method?");6667    if (const PointerAuthSchema &Schema =6668            CGM.getCodeGenOpts().PointerAuth.ObjCMethodListFunctionPointers) {6669      llvm::Constant *Bitcast =6670          llvm::ConstantExpr::getBitCast(fn, ObjCTypes.Int8PtrProgramASTy);6671      method.addSignedPointer(Bitcast, Schema, GlobalDecl(), QualType());6672    } else6673      method.add(fn);6674  }6675 6676  method.finishAndAddTo(builder);6677}6678 6679/// Build meta-data for method declarations.6680///6681/// struct _method_list_t {6682///   uint32_t entsize;  // sizeof(struct _objc_method)6683///   uint32_t method_count;6684///   struct _objc_method method_list[method_count];6685/// }6686///6687llvm::Constant *CGObjCNonFragileABIMac::emitMethodList(6688    Twine name, MethodListType kind, ArrayRef<const ObjCMethodDecl *> methods) {6689  // Return null for empty list.6690  if (methods.empty())6691    return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);6692 6693  StringRef prefix;6694  bool forProtocol;6695  switch (kind) {6696  case MethodListType::CategoryInstanceMethods:6697    prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_";6698    forProtocol = false;6699    break;6700  case MethodListType::CategoryClassMethods:6701    prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_";6702    forProtocol = false;6703    break;6704  case MethodListType::InstanceMethods:6705    prefix = "_OBJC_$_INSTANCE_METHODS_";6706    forProtocol = false;6707    break;6708  case MethodListType::ClassMethods:6709    prefix = "_OBJC_$_CLASS_METHODS_";6710    forProtocol = false;6711    break;6712 6713  case MethodListType::ProtocolInstanceMethods:6714    prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_";6715    forProtocol = true;6716    break;6717  case MethodListType::ProtocolClassMethods:6718    prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_";6719    forProtocol = true;6720    break;6721  case MethodListType::OptionalProtocolInstanceMethods:6722    prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";6723    forProtocol = true;6724    break;6725  case MethodListType::OptionalProtocolClassMethods:6726    prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";6727    forProtocol = true;6728    break;6729  }6730 6731  ConstantInitBuilder builder(CGM);6732  auto values = builder.beginStruct();6733 6734  // sizeof(struct _objc_method)6735  unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);6736  values.addInt(ObjCTypes.IntTy, Size);6737  // method_count6738  values.addInt(ObjCTypes.IntTy, methods.size());6739  auto methodArray = values.beginArray(ObjCTypes.MethodTy);6740  for (auto MD : methods)6741    emitMethodConstant(methodArray, MD, forProtocol);6742  methodArray.finishAndAddTo(values);6743 6744  llvm::GlobalVariable *GV = finishAndCreateGlobal(values, prefix + name, CGM);6745  CGM.addCompilerUsedGlobal(GV);6746  return GV;6747}6748 6749/// ObjCIvarOffsetVariable - Returns the ivar offset variable for6750/// the given ivar.6751llvm::GlobalVariable *6752CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,6753                                               const ObjCIvarDecl *Ivar) {6754  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();6755  llvm::SmallString<64> Name("OBJC_IVAR_$_");6756  Name += Container->getObjCRuntimeNameAsString();6757  Name += ".";6758  Name += Ivar->getName();6759  llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);6760  if (!IvarOffsetGV) {6761    IvarOffsetGV = new llvm::GlobalVariable(6762        CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,6763        llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());6764    if (CGM.getTriple().isOSBinFormatCOFF()) {6765      bool IsPrivateOrPackage =6766          Ivar->getAccessControl() == ObjCIvarDecl::Private ||6767          Ivar->getAccessControl() == ObjCIvarDecl::Package;6768 6769      const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();6770 6771      if (ContainingID->hasAttr<DLLImportAttr>())6772        IvarOffsetGV->setDLLStorageClass(6773            llvm::GlobalValue::DLLImportStorageClass);6774      else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)6775        IvarOffsetGV->setDLLStorageClass(6776            llvm::GlobalValue::DLLExportStorageClass);6777    }6778  }6779  return IvarOffsetGV;6780}6781 6782llvm::Constant *6783CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,6784                                          const ObjCIvarDecl *Ivar,6785                                          unsigned long int Offset) {6786  llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);6787  IvarOffsetGV->setInitializer(6788      llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));6789  IvarOffsetGV->setAlignment(6790      CGM.getDataLayout().getABITypeAlign(ObjCTypes.IvarOffsetVarTy));6791 6792  if (!CGM.getTriple().isOSBinFormatCOFF()) {6793    // FIXME: This matches gcc, but shouldn't the visibility be set on the use6794    // as well (i.e., in ObjCIvarOffsetVariable).6795    if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||6796        Ivar->getAccessControl() == ObjCIvarDecl::Package ||6797        ID->getVisibility() == HiddenVisibility)6798      IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);6799    else6800      IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);6801  }6802 6803  // If ID's layout is known, then make the global constant. This serves as a6804  // useful assertion: we'll never use this variable to calculate ivar offsets,6805  // so if the runtime tries to patch it then we should crash.6806  if (isClassLayoutKnownStatically(ID))6807    IvarOffsetGV->setConstant(true);6808 6809  if (CGM.getTriple().isOSBinFormatMachO())6810    IvarOffsetGV->setSection("__DATA, __objc_ivar");6811  return IvarOffsetGV;6812}6813 6814/// EmitIvarList - Emit the ivar list for the given6815/// implementation. The return value has type6816/// IvarListnfABIPtrTy.6817///  struct _ivar_t {6818///   unsigned [long] int *offset;  // pointer to ivar offset location6819///   char *name;6820///   char *type;6821///   uint32_t alignment;6822///   uint32_t size;6823/// }6824/// struct _ivar_list_t {6825///   uint32 entsize;  // sizeof(struct _ivar_t)6826///   uint32 count;6827///   struct _iver_t list[count];6828/// }6829///6830 6831llvm::Constant *6832CGObjCNonFragileABIMac::EmitIvarList(const ObjCImplementationDecl *ID) {6833 6834  ConstantInitBuilder builder(CGM);6835  auto ivarList = builder.beginStruct();6836  ivarList.addInt(ObjCTypes.IntTy,6837                  CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));6838  auto ivarCountSlot = ivarList.addPlaceholder();6839  auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);6840 6841  const ObjCInterfaceDecl *OID = ID->getClassInterface();6842  assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");6843 6844  // FIXME. Consolidate this with similar code in GenerateClass.6845 6846  for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;6847       IVD = IVD->getNextIvar()) {6848    // Ignore unnamed bit-fields.6849    if (!IVD->getDeclName())6850      continue;6851 6852    auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);6853    ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD,6854                               ComputeIvarBaseOffset(CGM, ID, IVD)));6855    ivar.add(GetMethodVarName(IVD->getIdentifier()));6856    ivar.add(GetMethodVarType(IVD));6857    llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(IVD->getType());6858    unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);6859    unsigned Align =6860        CGM.getContext().getPreferredTypeAlign(IVD->getType().getTypePtr()) >>6861        3;6862    Align = llvm::Log2_32(Align);6863    ivar.addInt(ObjCTypes.IntTy, Align);6864    // NOTE. Size of a bitfield does not match gcc's, because of the6865    // way bitfields are treated special in each. But I am told that6866    // 'size' for bitfield ivars is ignored by the runtime so it does6867    // not matter.  If it matters, there is enough info to get the6868    // bitfield right!6869    ivar.addInt(ObjCTypes.IntTy, Size);6870    ivar.finishAndAddTo(ivars);6871  }6872  // Return null for empty list.6873  if (ivars.empty()) {6874    ivars.abandon();6875    ivarList.abandon();6876    return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);6877  }6878 6879  auto ivarCount = ivars.size();6880  ivars.finishAndAddTo(ivarList);6881  ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);6882 6883  const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_";6884  llvm::GlobalVariable *GV = finishAndCreateGlobal(6885      ivarList, Prefix + OID->getObjCRuntimeNameAsString(), CGM);6886  CGM.addCompilerUsedGlobal(GV);6887  return GV;6888}6889 6890llvm::Constant *6891CGObjCNonFragileABIMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {6892  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];6893 6894  assert(!PD->isNonRuntimeProtocol() &&6895         "attempting to GetOrEmit a non-runtime protocol");6896  if (!Entry) {6897    // We use the initializer as a marker of whether this is a forward6898    // reference or not. At module finalization we add the empty6899    // contents for protocols which were referenced but never defined.6900    llvm::SmallString<64> Protocol;6901    llvm::raw_svector_ostream(Protocol)6902        << "_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();6903 6904    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,6905                                     false, llvm::GlobalValue::ExternalLinkage,6906                                     nullptr, Protocol);6907    if (!CGM.getTriple().isOSBinFormatMachO())6908      Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));6909  }6910 6911  return Entry;6912}6913 6914/// GetOrEmitProtocol - Generate the protocol meta-data:6915/// @code6916/// struct _protocol_t {6917///   id isa;  // NULL6918///   const char * const protocol_name;6919///   const struct _protocol_list_t * protocol_list; // super protocols6920///   const struct method_list_t * const instance_methods;6921///   const struct method_list_t * const class_methods;6922///   const struct method_list_t *optionalInstanceMethods;6923///   const struct method_list_t *optionalClassMethods;6924///   const struct _prop_list_t * properties;6925///   const uint32_t size;  // sizeof(struct _protocol_t)6926///   const uint32_t flags;  // = 06927///   const char ** extendedMethodTypes;6928///   const char *demangledName;6929///   const struct _prop_list_t * class_properties;6930/// }6931/// @endcode6932///6933 6934llvm::Constant *6935CGObjCNonFragileABIMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {6936  llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];6937 6938  // Early exit if a defining object has already been generated.6939  if (Entry && Entry->hasInitializer())6940    return Entry;6941 6942  // Use the protocol definition, if there is one.6943  assert(PD->hasDefinition() &&6944         "emitting protocol metadata without definition");6945  PD = PD->getDefinition();6946 6947  auto methodLists = ProtocolMethodLists::get(PD);6948 6949  ConstantInitBuilder builder(CGM);6950  auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy);6951 6952  // isa is NULL6953  values.addNullPointer(ObjCTypes.ObjectPtrTy);6954  values.add(GetClassName(PD->getObjCRuntimeNameAsString()));6955  values.add(EmitProtocolList("_OBJC_$_PROTOCOL_REFS_" +6956                                  PD->getObjCRuntimeNameAsString(),6957                              PD->protocol_begin(), PD->protocol_end()));6958  values.add(methodLists.emitMethodList(6959      this, PD, ProtocolMethodLists::RequiredInstanceMethods));6960  values.add(methodLists.emitMethodList(6961      this, PD, ProtocolMethodLists::RequiredClassMethods));6962  values.add(methodLists.emitMethodList(6963      this, PD, ProtocolMethodLists::OptionalInstanceMethods));6964  values.add(methodLists.emitMethodList(6965      this, PD, ProtocolMethodLists::OptionalClassMethods));6966  values.add(6967      EmitPropertyList("_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),6968                       nullptr, PD, ObjCTypes, false));6969  uint32_t Size =6970      CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);6971  values.addInt(ObjCTypes.IntTy, Size);6972  values.addInt(ObjCTypes.IntTy, 0);6973  values.add(EmitProtocolMethodTypes(6974      "_OBJC_$_PROTOCOL_METHOD_TYPES_" + PD->getObjCRuntimeNameAsString(),6975      methodLists.emitExtendedTypesArray(this), ObjCTypes));6976 6977  // const char *demangledName;6978  values.addNullPointer(ObjCTypes.Int8PtrTy);6979 6980  values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" +6981                                  PD->getObjCRuntimeNameAsString(),6982                              nullptr, PD, ObjCTypes, true));6983 6984  if (Entry) {6985    // Already created, fix the linkage and update the initializer.6986    Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);6987    values.finishAndSetAsInitializer(Entry);6988  } else {6989    llvm::SmallString<64> symbolName;6990    llvm::raw_svector_ostream(symbolName)6991        << "_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();6992 6993    Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),6994                                         /*constant*/ false,6995                                         llvm::GlobalValue::WeakAnyLinkage);6996    if (!CGM.getTriple().isOSBinFormatMachO())6997      Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName));6998 6999    Protocols[PD->getIdentifier()] = Entry;7000  }7001  Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);7002  CGM.addUsedGlobal(Entry);7003 7004  // Use this protocol meta-data to build protocol list table in section7005  // __DATA, __objc_protolist7006  llvm::SmallString<64> ProtocolRef;7007  llvm::raw_svector_ostream(ProtocolRef)7008      << "_OBJC_LABEL_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();7009 7010  llvm::GlobalVariable *PTGV = new llvm::GlobalVariable(7011      CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, false,7012      llvm::GlobalValue::WeakAnyLinkage, Entry, ProtocolRef);7013  if (!CGM.getTriple().isOSBinFormatMachO())7014    PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));7015  PTGV->setAlignment(7016      CGM.getDataLayout().getABITypeAlign(ObjCTypes.ProtocolnfABIPtrTy));7017  PTGV->setSection(7018      GetSectionName("__objc_protolist", "coalesced,no_dead_strip"));7019  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);7020  CGM.addUsedGlobal(PTGV);7021  return Entry;7022}7023 7024/// EmitProtocolList - Generate protocol list meta-data:7025/// @code7026/// struct _protocol_list_t {7027///   long protocol_count;   // Note, this is 32/64 bit7028///   struct _protocol_t[protocol_count];7029/// }7030/// @endcode7031///7032llvm::Constant *CGObjCNonFragileABIMac::EmitProtocolList(7033    Twine Name, ObjCProtocolDecl::protocol_iterator begin,7034    ObjCProtocolDecl::protocol_iterator end) {7035  // Just return null for empty protocol lists7036  auto Protocols = GetRuntimeProtocolList(begin, end);7037  if (Protocols.empty())7038    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);7039 7040  SmallVector<llvm::Constant *, 16> ProtocolRefs;7041  ProtocolRefs.reserve(Protocols.size());7042 7043  for (const auto *PD : Protocols)7044    ProtocolRefs.push_back(GetProtocolRef(PD));7045 7046  // If all of the protocols in the protocol list are objc_non_runtime_protocol7047  // just return null7048  if (ProtocolRefs.size() == 0)7049    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);7050 7051  // FIXME: We shouldn't need to do this lookup here, should we?7052  SmallString<256> TmpName;7053  Name.toVector(TmpName);7054  llvm::GlobalVariable *GV =7055      CGM.getModule().getGlobalVariable(TmpName.str(), true);7056  if (GV)7057    return GV;7058 7059  ConstantInitBuilder builder(CGM);7060  auto values = builder.beginStruct();7061  auto countSlot = values.addPlaceholder();7062 7063  // A null-terminated array of protocols.7064  auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);7065  for (auto const &proto : ProtocolRefs)7066    array.add(proto);7067  auto count = array.size();7068  array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);7069 7070  array.finishAndAddTo(values);7071  values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);7072 7073  GV = finishAndCreateGlobal(values, Name, CGM);7074  CGM.addCompilerUsedGlobal(GV);7075  return GV;7076}7077 7078/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.7079/// This code gen. amounts to generating code for:7080/// @code7081/// (type *)((char *)base + _OBJC_IVAR_$_.ivar;7082/// @encode7083///7084LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(7085    CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue,7086    const ObjCIvarDecl *Ivar, unsigned CVRQualifiers) {7087  ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();7088  llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);7089  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,7090                                  Offset);7091}7092 7093llvm::Value *7094CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,7095                                       const ObjCInterfaceDecl *Interface,7096                                       const ObjCIvarDecl *Ivar) {7097  llvm::Value *IvarOffsetValue;7098  if (isClassLayoutKnownStatically(Interface)) {7099    IvarOffsetValue = llvm::ConstantInt::get(7100        ObjCTypes.IvarOffsetVarTy,7101        ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));7102  } else {7103    llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);7104    IvarOffsetValue = CGF.Builder.CreateAlignedLoad(GV->getValueType(), GV,7105                                                    CGF.getSizeAlign(), "ivar");7106    if (IsIvarOffsetKnownIdempotent(CGF, Ivar))7107      cast<llvm::LoadInst>(IvarOffsetValue)7108          ->setMetadata(llvm::LLVMContext::MD_invariant_load,7109                        llvm::MDNode::get(VMContext, {}));7110  }7111 7112  // This could be 32bit int or 64bit integer depending on the architecture.7113  // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value7114  //  as this is what caller always expects.7115  if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)7116    IvarOffsetValue = CGF.Builder.CreateIntCast(7117        IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv");7118  return IvarOffsetValue;7119}7120 7121static void appendSelectorForMessageRefTable(std::string &buffer,7122                                             Selector selector) {7123  if (selector.isUnarySelector()) {7124    buffer += selector.getNameForSlot(0);7125    return;7126  }7127 7128  for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {7129    buffer += selector.getNameForSlot(i);7130    buffer += '_';7131  }7132}7133 7134/// Emit a "vtable" message send.  We emit a weak hidden-visibility7135/// struct, initially containing the selector pointer and a pointer to7136/// a "fixup" variant of the appropriate objc_msgSend.  To call, we7137/// load and call the function pointer, passing the address of the7138/// struct as the second parameter.  The runtime determines whether7139/// the selector is currently emitted using vtable dispatch; if so, it7140/// substitutes a stub function which simply tail-calls through the7141/// appropriate vtable slot, and if not, it substitues a stub function7142/// which tail-calls objc_msgSend.  Both stubs adjust the selector7143/// argument to correctly point to the selector.7144RValue CGObjCNonFragileABIMac::EmitVTableMessageSend(7145    CodeGenFunction &CGF, ReturnValueSlot returnSlot, QualType resultType,7146    Selector selector, llvm::Value *arg0, QualType arg0Type, bool isSuper,7147    const CallArgList &formalArgs, const ObjCMethodDecl *method) {7148  // Compute the actual arguments.7149  CallArgList args;7150 7151  // First argument: the receiver / super-call structure.7152  if (!isSuper)7153    arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);7154  args.add(RValue::get(arg0), arg0Type);7155 7156  // Second argument: a pointer to the message ref structure.  Leave7157  // the actual argument value blank for now.7158  args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);7159 7160  llvm::append_range(args, formalArgs);7161 7162  MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);7163 7164  NullReturnState nullReturn;7165 7166  // Find the function to call and the mangled name for the message7167  // ref structure.  Using a different mangled name wouldn't actually7168  // be a problem; it would just be a waste.7169  //7170  // The runtime currently never uses vtable dispatch for anything7171  // except normal, non-super message-sends.7172  // FIXME: don't use this for that.7173  llvm::FunctionCallee fn = nullptr;7174  std::string messageRefName("_");7175  if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {7176    if (isSuper) {7177      fn = ObjCTypes.getMessageSendSuper2StretFixupFn();7178      messageRefName += "objc_msgSendSuper2_stret_fixup";7179    } else {7180      nullReturn.init(CGF, arg0);7181      fn = ObjCTypes.getMessageSendStretFixupFn();7182      messageRefName += "objc_msgSend_stret_fixup";7183    }7184  } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {7185    fn = ObjCTypes.getMessageSendFpretFixupFn();7186    messageRefName += "objc_msgSend_fpret_fixup";7187  } else {7188    if (isSuper) {7189      fn = ObjCTypes.getMessageSendSuper2FixupFn();7190      messageRefName += "objc_msgSendSuper2_fixup";7191    } else {7192      fn = ObjCTypes.getMessageSendFixupFn();7193      messageRefName += "objc_msgSend_fixup";7194    }7195  }7196  assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");7197  messageRefName += '_';7198 7199  // Append the selector name, except use underscores anywhere we7200  // would have used colons.7201  appendSelectorForMessageRefTable(messageRefName, selector);7202 7203  llvm::GlobalVariable *messageRef =7204      CGM.getModule().getGlobalVariable(messageRefName);7205  if (!messageRef) {7206    // Build the message ref structure.7207    ConstantInitBuilder builder(CGM);7208    auto values = builder.beginStruct();7209    values.add(cast<llvm::Constant>(fn.getCallee()));7210    values.add(GetMethodVarName(selector));7211    messageRef = values.finishAndCreateGlobal(7212        messageRefName, CharUnits::fromQuantity(16),7213        /*constant*/ false, llvm::GlobalValue::WeakAnyLinkage);7214    messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);7215    messageRef->setSection(GetSectionName("__objc_msgrefs", "coalesced"));7216  }7217 7218  bool requiresnullCheck = false;7219  if (CGM.getLangOpts().ObjCAutoRefCount && method)7220    for (const auto *ParamDecl : method->parameters()) {7221      if (ParamDecl->isDestroyedInCallee()) {7222        if (!nullReturn.NullBB)7223          nullReturn.init(CGF, arg0);7224        requiresnullCheck = true;7225        break;7226      }7227    }7228 7229  Address mref =7230      Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),7231              ObjCTypes.MessageRefTy, CGF.getPointerAlign());7232 7233  // Update the message ref argument.7234  args[1].setRValue(RValue::get(mref, CGF));7235 7236  // Load the function to call from the message ref table.7237  Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0);7238  llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn");7239 7240  calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);7241  CGCallee callee(CGCalleeInfo(), calleePtr);7242 7243  RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);7244  return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,7245                             requiresnullCheck ? method : nullptr);7246}7247 7248/// Generate code for a message send expression in the nonfragile abi.7249CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend(7250    CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,7251    Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,7252    const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {7253  return isVTableDispatchedSelector(Sel)7254             ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, Receiver,7255                                     CGF.getContext().getObjCIdType(), false,7256                                     CallArgs, Method)7257             : EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,7258                               CGF.getContext().getObjCIdType(), false,7259                               CallArgs, Method, Class, ObjCTypes);7260}7261 7262llvm::Constant *7263CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,7264                                       bool metaclass,7265                                       ForDefinition_t isForDefinition) {7266  auto prefix =7267      (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());7268  return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),7269                        isForDefinition, ID->isWeakImported(),7270                        !isForDefinition &&7271                            CGM.getTriple().isOSBinFormatCOFF() &&7272                            ID->hasAttr<DLLImportAttr>());7273}7274 7275llvm::Constant *7276CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,7277                                       ForDefinition_t IsForDefinition,7278                                       bool Weak, bool DLLImport) {7279  llvm::GlobalValue::LinkageTypes L =7280      Weak ? llvm::GlobalValue::ExternalWeakLinkage7281           : llvm::GlobalValue::ExternalLinkage;7282 7283  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);7284  if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {7285    auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,7286                                           nullptr, Name);7287 7288    if (DLLImport)7289      NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);7290 7291    if (GV) {7292      GV->replaceAllUsesWith(NewGV);7293      GV->eraseFromParent();7294    }7295    GV = NewGV;7296    CGM.getModule().insertGlobalVariable(GV);7297  }7298 7299  assert(GV->getLinkage() == L);7300  return GV;7301}7302 7303llvm::Constant *7304CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {7305  llvm::Constant *ClassGV =7306      GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);7307 7308  if (!ID->hasAttr<ObjCClassStubAttr>())7309    return ClassGV;7310 7311  ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);7312 7313  // Stub classes are pointer-aligned. Classrefs pointing at stub classes7314  // must set the least significant bit set to 1.7315  auto *Idx = llvm::ConstantInt::get(CGM.Int32Ty, 1);7316  return llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, ClassGV, Idx);7317}7318 7319llvm::Value *7320CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,7321                                           const ObjCInterfaceDecl *ID,7322                                           llvm::GlobalVariable *Entry) {7323  if (ID && ID->hasAttr<ObjCClassStubAttr>()) {7324    // Classrefs pointing at Objective-C stub classes must be loaded by calling7325    // a special runtime function.7326    return CGF.EmitRuntimeCall(ObjCTypes.getLoadClassrefFn(), Entry,7327                               "load_classref_result");7328  }7329 7330  CharUnits Align = CGF.getPointerAlign();7331  return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, Align);7332}7333 7334llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(7335    CodeGenFunction &CGF, IdentifierInfo *II, const ObjCInterfaceDecl *ID) {7336  llvm::GlobalVariable *&Entry = ClassReferences[II];7337 7338  if (!Entry) {7339    llvm::Constant *ClassGV;7340    if (ID) {7341      ClassGV = GetClassGlobalForClassRef(ID);7342    } else {7343      ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),7344                               NotForDefinition);7345      assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&7346             "classref was emitted with the wrong type?");7347    }7348 7349    std::string SectionName =7350        GetSectionName("__objc_classrefs", "regular,no_dead_strip");7351    Entry = new llvm::GlobalVariable(7352        CGM.getModule(), ClassGV->getType(), false,7353        getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV,7354        "OBJC_CLASSLIST_REFERENCES_$_");7355    Entry->setAlignment(CGF.getPointerAlign().getAsAlign());7356    if (!ID || !ID->hasAttr<ObjCClassStubAttr>())7357      Entry->setSection(SectionName);7358 7359    CGM.addCompilerUsedGlobal(Entry);7360  }7361 7362  return EmitLoadOfClassRef(CGF, ID, Entry);7363}7364 7365llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,7366                                                  const ObjCInterfaceDecl *ID) {7367  // If the class has the objc_runtime_visible attribute, we need to7368  // use the Objective-C runtime to get the class.7369  if (ID->hasAttr<ObjCRuntimeVisibleAttr>())7370    return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);7371 7372  return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);7373}7374 7375llvm::Value *7376CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {7377  IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");7378  return EmitClassRefFromId(CGF, II, nullptr);7379}7380 7381llvm::Value *7382CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,7383                                          const ObjCInterfaceDecl *ID) {7384  llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];7385 7386  if (!Entry) {7387    llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);7388    std::string SectionName =7389        GetSectionName("__objc_superrefs", "regular,no_dead_strip");7390    Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false,7391                                     llvm::GlobalValue::PrivateLinkage, ClassGV,7392                                     "OBJC_CLASSLIST_SUP_REFS_$_");7393    Entry->setAlignment(CGF.getPointerAlign().getAsAlign());7394    Entry->setSection(SectionName);7395    CGM.addCompilerUsedGlobal(Entry);7396  }7397 7398  return EmitLoadOfClassRef(CGF, ID, Entry);7399}7400 7401/// EmitMetaClassRef - Return a Value * of the address of _class_t7402/// meta-data7403///7404llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(7405    CodeGenFunction &CGF, const ObjCInterfaceDecl *ID, bool Weak) {7406  CharUnits Align = CGF.getPointerAlign();7407  llvm::GlobalVariable *&Entry = MetaClassReferences[ID->getIdentifier()];7408  if (!Entry) {7409    auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);7410    std::string SectionName =7411        GetSectionName("__objc_superrefs", "regular,no_dead_strip");7412    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,7413                                     false, llvm::GlobalValue::PrivateLinkage,7414                                     MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");7415    Entry->setAlignment(Align.getAsAlign());7416    Entry->setSection(SectionName);7417    CGM.addCompilerUsedGlobal(Entry);7418  }7419 7420  return CGF.Builder.CreateAlignedLoad(ObjCTypes.ClassnfABIPtrTy, Entry, Align);7421}7422 7423/// GetClass - Return a reference to the class for the given interface7424/// decl.7425llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,7426                                              const ObjCInterfaceDecl *ID) {7427  if (ID->isWeakImported()) {7428    auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);7429    (void)ClassGV;7430    assert(!isa<llvm::GlobalVariable>(ClassGV) ||7431           cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());7432  }7433 7434  return EmitClassRef(CGF, ID);7435}7436 7437/// Generates a message send where the super is the receiver.  This is7438/// a message send to self with special delivery semantics indicating7439/// which class's method should be called.7440CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSendSuper(7441    CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,7442    Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,7443    llvm::Value *Receiver, bool IsClassMessage,7444    const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {7445  // ...7446  // Create and init a super structure; this is a (receiver, class)7447  // pair we will pass to objc_msgSendSuper.7448  RawAddress ObjCSuper = CGF.CreateTempAlloca(7449      ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super");7450 7451  llvm::Value *ReceiverAsObject =7452      CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);7453  CGF.Builder.CreateStore(ReceiverAsObject,7454                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));7455 7456  // If this is a class message the metaclass is passed as the target.7457  llvm::Value *Target;7458  if (IsClassMessage)7459    Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());7460  else7461    Target = EmitSuperClassRef(CGF, Class);7462 7463  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and7464  // ObjCTypes types.7465  llvm::Type *ClassTy =7466      CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());7467  Target = CGF.Builder.CreateBitCast(Target, ClassTy);7468  CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));7469 7470  return (isVTableDispatchedSelector(Sel))7471             ? EmitVTableMessageSend(7472                   CGF, Return, ResultType, Sel, ObjCSuper.getPointer(),7473                   ObjCTypes.SuperPtrCTy, true, CallArgs, Method)7474             : EmitMessageSend(CGF, Return, ResultType, Sel,7475                               ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,7476                               true, CallArgs, Method, Class, ObjCTypes);7477}7478 7479llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,7480                                                  Selector Sel) {7481  Address Addr = EmitSelectorAddr(Sel);7482 7483  llvm::LoadInst *LI = CGF.Builder.CreateLoad(Addr);7484  LI->setMetadata(llvm::LLVMContext::MD_invariant_load,7485                  llvm::MDNode::get(VMContext, {}));7486  return LI;7487}7488 7489ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {7490  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];7491  CharUnits Align = CGM.getPointerAlign();7492  if (!Entry) {7493    std::string SectionName =7494        GetSectionName("__objc_selrefs", "literal_pointers,no_dead_strip");7495    Entry = new llvm::GlobalVariable(7496        CGM.getModule(), ObjCTypes.SelectorPtrTy, false,7497        getLinkageTypeForObjCMetadata(CGM, SectionName), GetMethodVarName(Sel),7498        "OBJC_SELECTOR_REFERENCES_");7499    Entry->setExternallyInitialized(true);7500    Entry->setSection(SectionName);7501    Entry->setAlignment(Align.getAsAlign());7502    CGM.addCompilerUsedGlobal(Entry);7503  }7504 7505  return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);7506}7507 7508/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.7509/// objc_assign_ivar (id src, id *dst, ptrdiff_t)7510///7511void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,7512                                                llvm::Value *src, Address dst,7513                                                llvm::Value *ivarOffset) {7514  llvm::Type *SrcTy = src->getType();7515  if (!isa<llvm::PointerType>(SrcTy)) {7516    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);7517    assert(Size <= 8 && "does not support size > 8");7518    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)7519                     : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));7520    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);7521  }7522  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);7523  llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),7524                                                  ObjCTypes.PtrObjectPtrTy);7525  llvm::Value *args[] = {src, dstVal, ivarOffset};7526  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);7527}7528 7529/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.7530/// objc_assign_strongCast (id src, id *dst)7531///7532void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(7533    CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dst) {7534  llvm::Type *SrcTy = src->getType();7535  if (!isa<llvm::PointerType>(SrcTy)) {7536    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);7537    assert(Size <= 8 && "does not support size > 8");7538    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)7539                     : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));7540    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);7541  }7542  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);7543  llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),7544                                                  ObjCTypes.PtrObjectPtrTy);7545  llvm::Value *args[] = {src, dstVal};7546  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,7547                              "weakassign");7548}7549 7550void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(7551    CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr,7552    llvm::Value *Size) {7553  llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),7554                         SrcPtr.emitRawPointer(CGF), Size};7555  CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);7556}7557 7558/// EmitObjCWeakRead - Code gen for loading value of a __weak7559/// object: objc_read_weak (id *src)7560///7561llvm::Value *7562CGObjCNonFragileABIMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,7563                                         Address AddrWeakObj) {7564  llvm::Type *DestTy = AddrWeakObj.getElementType();7565  llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(7566      AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);7567  llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(7568      ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread");7569  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);7570  return read_weak;7571}7572 7573/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.7574/// objc_assign_weak (id src, id *dst)7575///7576void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,7577                                                llvm::Value *src, Address dst) {7578  llvm::Type *SrcTy = src->getType();7579  if (!isa<llvm::PointerType>(SrcTy)) {7580    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);7581    assert(Size <= 8 && "does not support size > 8");7582    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)7583                     : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));7584    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);7585  }7586  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);7587  llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),7588                                                  ObjCTypes.PtrObjectPtrTy);7589  llvm::Value *args[] = {src, dstVal};7590  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,7591                              "weakassign");7592}7593 7594/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.7595/// objc_assign_global (id src, id *dst)7596///7597void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,7598                                                  llvm::Value *src, Address dst,7599                                                  bool threadlocal) {7600  llvm::Type *SrcTy = src->getType();7601  if (!isa<llvm::PointerType>(SrcTy)) {7602    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);7603    assert(Size <= 8 && "does not support size > 8");7604    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)7605                     : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));7606    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);7607  }7608  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);7609  llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),7610                                                  ObjCTypes.PtrObjectPtrTy);7611  llvm::Value *args[] = {src, dstVal};7612  if (!threadlocal)7613    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,7614                                "globalassign");7615  else7616    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,7617                                "threadlocalassign");7618}7619 7620void CGObjCNonFragileABIMac::EmitSynchronizedStmt(7621    CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S) {7622  EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(),7623                         ObjCTypes.getSyncExitFn());7624}7625 7626llvm::Constant *CGObjCNonFragileABIMac::GetEHType(QualType T) {7627  // There's a particular fixed type info for 'id'.7628  if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {7629    auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");7630    if (!IDEHType) {7631      IDEHType = new llvm::GlobalVariable(7632          CGM.getModule(), ObjCTypes.EHTypeTy, false,7633          llvm::GlobalValue::ExternalLinkage, nullptr, "OBJC_EHTYPE_id");7634      if (CGM.getTriple().isOSBinFormatCOFF())7635        IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id"));7636    }7637    return IDEHType;7638  }7639 7640  // All other types should be Objective-C interface pointer types.7641  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();7642  assert(PT && "Invalid @catch type.");7643 7644  const ObjCInterfaceType *IT = PT->getInterfaceType();7645  assert(IT && "Invalid @catch type.");7646 7647  return GetInterfaceEHType(IT->getDecl(), NotForDefinition);7648}7649 7650void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,7651                                         const ObjCAtTryStmt &S) {7652  EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(),7653                   ObjCTypes.getObjCEndCatchFn(),7654                   ObjCTypes.getExceptionRethrowFn());7655}7656 7657/// EmitThrowStmt - Generate code for a throw statement.7658void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,7659                                           const ObjCAtThrowStmt &S,7660                                           bool ClearInsertionPoint) {7661  if (const Expr *ThrowExpr = S.getThrowExpr()) {7662    llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);7663    Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);7664    llvm::CallBase *Call =7665        CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);7666    Call->setDoesNotReturn();7667  } else {7668    llvm::CallBase *Call =7669        CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());7670    Call->setDoesNotReturn();7671  }7672 7673  CGF.Builder.CreateUnreachable();7674  if (ClearInsertionPoint)7675    CGF.Builder.ClearInsertionPoint();7676}7677 7678llvm::Constant *7679CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,7680                                           ForDefinition_t IsForDefinition) {7681  llvm::GlobalVariable *&Entry = EHTypeReferences[ID->getIdentifier()];7682  StringRef ClassName = ID->getObjCRuntimeNameAsString();7683 7684  // If we don't need a definition, return the entry if found or check7685  // if we use an external reference.7686  if (!IsForDefinition) {7687    if (Entry)7688      return Entry;7689 7690    // If this type (or a super class) has the __objc_exception__7691    // attribute, emit an external reference.7692    if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {7693      std::string EHTypeName = ("OBJC_EHTYPE_$_" + ClassName).str();7694      Entry = new llvm::GlobalVariable(7695          CGM.getModule(), ObjCTypes.EHTypeTy, false,7696          llvm::GlobalValue::ExternalLinkage, nullptr, EHTypeName);7697      CGM.setGVProperties(Entry, ID);7698      return Entry;7699    }7700  }7701 7702  // Otherwise we need to either make a new entry or fill in the initializer.7703  assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");7704 7705  std::string VTableName = "objc_ehtype_vtable";7706  auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);7707  if (!VTableGV) {7708    VTableGV = new llvm::GlobalVariable(7709        CGM.getModule(), ObjCTypes.Int8PtrTy, false,7710        llvm::GlobalValue::ExternalLinkage, nullptr, VTableName);7711    if (CGM.getTriple().isOSBinFormatCOFF())7712      VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));7713  }7714 7715  llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);7716  llvm::Constant *VTablePtr = llvm::ConstantExpr::getInBoundsGetElementPtr(7717      VTableGV->getValueType(), VTableGV, VTableIdx);7718 7719  ConstantInitBuilder builder(CGM);7720  auto values = builder.beginStruct(ObjCTypes.EHTypeTy);7721  const PointerAuthSchema &TypeInfoSchema =7722      CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer;7723  values.addSignedPointer(VTablePtr, TypeInfoSchema, GlobalDecl(), QualType());7724 7725  values.add(GetClassName(ClassName));7726  values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));7727 7728  llvm::GlobalValue::LinkageTypes L = IsForDefinition7729                                          ? llvm::GlobalValue::ExternalLinkage7730                                          : llvm::GlobalValue::WeakAnyLinkage;7731  if (Entry) {7732    values.finishAndSetAsInitializer(Entry);7733    Entry->setAlignment(CGM.getPointerAlign().getAsAlign());7734  } else {7735    Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_" + ClassName,7736                                         CGM.getPointerAlign(),7737                                         /*constant*/ false, L);7738    if (hasObjCExceptionAttribute(CGM.getContext(), ID))7739      CGM.setGVProperties(Entry, ID);7740  }7741  assert(Entry->getLinkage() == L);7742 7743  if (!CGM.getTriple().isOSBinFormatCOFF())7744    if (ID->getVisibility() == HiddenVisibility)7745      Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);7746 7747  if (IsForDefinition)7748    if (CGM.getTriple().isOSBinFormatMachO())7749      Entry->setSection("__DATA,__objc_const");7750 7751  return Entry;7752}7753 7754/* *** */7755 7756CodeGen::CGObjCRuntime *7757CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {7758  switch (CGM.getLangOpts().ObjCRuntime.getKind()) {7759  case ObjCRuntime::FragileMacOSX:7760    return new CGObjCMac(CGM);7761 7762  case ObjCRuntime::MacOSX:7763  case ObjCRuntime::iOS:7764  case ObjCRuntime::WatchOS:7765    return new CGObjCNonFragileABIMac(CGM);7766 7767  case ObjCRuntime::GNUstep:7768  case ObjCRuntime::GCC:7769  case ObjCRuntime::ObjFW:7770    llvm_unreachable("these runtimes are not Mac runtimes");7771  }7772  llvm_unreachable("bad runtime");7773}7774