A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/CGObjCMac_8cpp_source.html below:

clang: lib/CodeGen/CGObjCMac.cpp Source File

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" 43using namespace clang

;

44using namespace

CodeGen;

51class

ObjCCommonTypesHelper {

53

llvm::LLVMContext &VMContext;

63

llvm::FunctionCallee getMessageSendFn()

const

{

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));

79

llvm::FunctionCallee getMessageSendStretFn()

const

{

80

llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };

81 return

CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,

83 "objc_msgSend_stret"

);

91

llvm::FunctionCallee getMessageSendFpretFn()

const

{

92

llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };

93 return

CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,

95 "objc_msgSend_fpret"

);

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);

109 return

CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,

111 "objc_msgSend_fp2ret"

);

119

llvm::FunctionCallee getMessageSendSuperFn()

const

{

120

llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };

121 return

CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,

123 "objc_msgSendSuper"

);

130

llvm::FunctionCallee getMessageSendSuperFn2()

const

{

131

llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };

132 return

CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,

134 "objc_msgSendSuper2"

);

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"

);

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"

);

159

llvm::FunctionCallee getMessageSendSuperFpretFn()

const

{

161 return

getMessageSendSuperFn();

164

llvm::FunctionCallee getMessageSendSuperFpretFn2()

const

{

166 return

getMessageSendSuperFn2();

173

llvm::IntegerType *ShortTy, *IntTy, *LongTy;

174

llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;

175

llvm::PointerType *Int8PtrProgramASTy;

176

llvm::Type *IvarOffsetVarTy;

179

llvm::PointerType *ObjectPtrTy;

182

llvm::PointerType *PtrObjectPtrTy;

185

llvm::PointerType *SelectorPtrTy;

190

llvm::Type *ExternalProtocolPtrTy;

193

llvm::Type *getExternalProtocolPtrTy() {

194 if

(!ExternalProtocolPtrTy) {

200

ExternalProtocolPtrTy = llvm::PointerType::getUnqual(

T

);

203 return

ExternalProtocolPtrTy;

212

llvm::StructType *SuperTy;

214

llvm::PointerType *SuperPtrTy;

218

llvm::StructType *PropertyTy;

222

llvm::StructType *PropertyListTy;

224

llvm::PointerType *PropertyListPtrTy;

227

llvm::StructType *MethodTy;

232

llvm::PointerType *CachePtrTy;

234

llvm::FunctionCallee getGetPropertyFn() {

243

llvm::FunctionType *FTy =

244

Types.GetFunctionType(

245

Types.arrangeBuiltinFunctionDeclaration(IdType, Params));

249

llvm::FunctionCallee getSetPropertyFn() {

262

llvm::FunctionType *FTy =

263

Types.GetFunctionType(

264

Types.arrangeBuiltinFunctionDeclaration(Ctx.

VoidTy

, Params));

268

llvm::FunctionCallee getOptimizedSetPropertyFn(

bool

atomic,

bool

copy) {

283

Params.push_back(IdType);

284

Params.push_back(SelType);

285

Params.push_back(IdType);

287

llvm::FunctionType *FTy =

288

Types.GetFunctionType(

289

Types.arrangeBuiltinFunctionDeclaration(Ctx.

VoidTy

, Params));

292 name

=

"objc_setProperty_atomic_copy"

;

293 else if

(atomic && !copy)

294 name

=

"objc_setProperty_atomic"

;

295 else if

(!atomic && copy)

296 name

=

"objc_setProperty_nonatomic_copy"

;

298 name

=

"objc_setProperty_nonatomic"

;

303

llvm::FunctionCallee getCopyStructFn() {

311

Params.push_back(Ctx.

BoolTy

);

312

Params.push_back(Ctx.

BoolTy

);

313

llvm::FunctionType *FTy =

314

Types.GetFunctionType(

315

Types.arrangeBuiltinFunctionDeclaration(Ctx.

VoidTy

, Params));

323

llvm::FunctionCallee getCppAtomicObjectFunction() {

331

llvm::FunctionType *FTy =

332

Types.GetFunctionType(

333

Types.arrangeBuiltinFunctionDeclaration(Ctx.

VoidTy

, Params));

337

llvm::FunctionCallee getEnumerationMutationFn() {

343

llvm::FunctionType *FTy =

344

Types.GetFunctionType(

345

Types.arrangeBuiltinFunctionDeclaration(Ctx.

VoidTy

, Params));

349

llvm::FunctionCallee getLookUpClassFn() {

356

llvm::FunctionType *FTy =

357

Types.GetFunctionType(Types.arrangeBuiltinFunctionDeclaration(

364

llvm::FunctionCallee getGcReadWeakFn() {

367

llvm::FunctionType *FTy =

368

llvm::FunctionType::get(ObjectPtrTy, args,

false

);

373

llvm::FunctionCallee getGcAssignWeakFn() {

375

llvm::Type *args[] = {ObjectPtrTy, CGM.

UnqualPtrTy

};

376

llvm::FunctionType *FTy =

377

llvm::FunctionType::get(ObjectPtrTy, args,

false

);

382

llvm::FunctionCallee getGcAssignGlobalFn() {

384

llvm::Type *args[] = {ObjectPtrTy, CGM.

UnqualPtrTy

};

385

llvm::FunctionType *FTy =

386

llvm::FunctionType::get(ObjectPtrTy, args,

false

);

391

llvm::FunctionCallee getGcAssignThreadLocalFn() {

393

llvm::Type *args[] = {ObjectPtrTy, CGM.

UnqualPtrTy

};

394

llvm::FunctionType *FTy =

395

llvm::FunctionType::get(ObjectPtrTy, args,

false

);

400

llvm::FunctionCallee getGcAssignIvarFn() {

403

llvm::FunctionType *FTy =

404

llvm::FunctionType::get(ObjectPtrTy, args,

false

);

409

llvm::FunctionCallee GcMemmoveCollectableFn() {

411

llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };

412

llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args,

false

);

417

llvm::FunctionCallee getGcAssignStrongCastFn() {

419

llvm::Type *args[] = {ObjectPtrTy, CGM.

UnqualPtrTy

};

420

llvm::FunctionType *FTy =

421

llvm::FunctionType::get(ObjectPtrTy, args,

false

);

426

llvm::FunctionCallee getExceptionThrowFn() {

428

llvm::Type *args[] = { ObjectPtrTy };

429

llvm::FunctionType *FTy =

430

llvm::FunctionType::get(CGM.

VoidTy

, args,

false

);

435

llvm::FunctionCallee getExceptionRethrowFn() {

437

llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.

VoidTy

,

false

);

442

llvm::FunctionCallee getSyncEnterFn() {

444

llvm::Type *args[] = { ObjectPtrTy };

445

llvm::FunctionType *FTy =

446

llvm::FunctionType::get(CGM.

IntTy

, args,

false

);

451

llvm::FunctionCallee getSyncExitFn() {

453

llvm::Type *args[] = { ObjectPtrTy };

454

llvm::FunctionType *FTy =

455

llvm::FunctionType::get(CGM.

IntTy

, args,

false

);

459

llvm::FunctionCallee getSendFn(

bool

IsSuper)

const

{

460 return

IsSuper ? getMessageSendSuperFn() : getMessageSendFn();

463

llvm::FunctionCallee getSendFn2(

bool

IsSuper)

const

{

464 return

IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();

467

llvm::FunctionCallee getSendStretFn(

bool

IsSuper)

const

{

468 return

IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();

471

llvm::FunctionCallee getSendStretFn2(

bool

IsSuper)

const

{

472 return

IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();

475

llvm::FunctionCallee getSendFpretFn(

bool

IsSuper)

const

{

476 return

IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();

479

llvm::FunctionCallee getSendFpretFn2(

bool

IsSuper)

const

{

480 return

IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();

483

llvm::FunctionCallee getSendFp2retFn(

bool

IsSuper)

const

{

484 return

IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();

487

llvm::FunctionCallee getSendFp2RetFn2(

bool

IsSuper)

const

{

488 return

IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();

496class

ObjCTypesHelper :

public

ObjCCommonTypesHelper {

499

llvm::StructType *SymtabTy;

501

llvm::PointerType *SymtabPtrTy;

503

llvm::StructType *ModuleTy;

506

llvm::StructType *ProtocolTy;

508

llvm::PointerType *ProtocolPtrTy;

511

llvm::StructType *ProtocolExtensionTy;

514

llvm::PointerType *ProtocolExtensionPtrTy;

517

llvm::StructType *MethodDescriptionTy;

520

llvm::StructType *MethodDescriptionListTy;

523

llvm::PointerType *MethodDescriptionListPtrTy;

525

llvm::StructType *ProtocolListTy;

527

llvm::PointerType *ProtocolListPtrTy;

529

llvm::StructType *CategoryTy;

531

llvm::StructType *ClassTy;

533

llvm::PointerType *ClassPtrTy;

535

llvm::StructType *ClassExtensionTy;

537

llvm::PointerType *ClassExtensionPtrTy;

539

llvm::StructType *IvarTy;

541

llvm::StructType *IvarListTy;

543

llvm::PointerType *IvarListPtrTy;

545

llvm::StructType *MethodListTy;

547

llvm::PointerType *MethodListPtrTy;

550

llvm::StructType *ExceptionDataTy;

553

llvm::FunctionCallee getExceptionTryEnterFn() {

556

llvm::FunctionType::get(CGM.

VoidTy

, params,

false

),

557 "objc_exception_try_enter"

);

561

llvm::FunctionCallee getExceptionTryExitFn() {

564

llvm::FunctionType::get(CGM.

VoidTy

, params,

false

),

565 "objc_exception_try_exit"

);

569

llvm::FunctionCallee getExceptionExtractFn() {

573 "objc_exception_extract"

);

577

llvm::FunctionCallee getExceptionMatchFn() {

578

llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };

580

llvm::FunctionType::get(CGM.

Int32Ty

, params,

false

),

581 "objc_exception_match"

);

585

llvm::FunctionCallee getSetJmpFn() {

589

llvm::FunctionType::get(CGM.

Int32Ty

, params,

false

),

"_setjmp"

,

591

llvm::AttributeList::FunctionIndex,

592

llvm::Attribute::NonLazyBind));

601class

ObjCNonFragileABITypesHelper :

public

ObjCCommonTypesHelper {

604

llvm::StructType *MethodListnfABITy;

607

llvm::PointerType *MethodListnfABIPtrTy;

610

llvm::StructType *ProtocolnfABITy;

613

llvm::PointerType *ProtocolnfABIPtrTy;

616

llvm::StructType *ProtocolListnfABITy;

619

llvm::PointerType *ProtocolListnfABIPtrTy;

622

llvm::StructType *ClassnfABITy;

625

llvm::PointerType *ClassnfABIPtrTy;

628

llvm::StructType *IvarnfABITy;

631

llvm::StructType *IvarListnfABITy;

634

llvm::PointerType *IvarListnfABIPtrTy;

637

llvm::StructType *ClassRonfABITy;

640

llvm::PointerType *ImpnfABITy;

643

llvm::StructType *CategorynfABITy;

652

llvm::StructType *MessageRefTy;

657

llvm::Type *MessageRefPtrTy;

666

llvm::StructType *SuperMessageRefTy;

669

llvm::PointerType *SuperMessageRefPtrTy;

671

llvm::FunctionCallee getMessageSendFixupFn() {

673

llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };

676 "objc_msgSend_fixup"

);

679

llvm::FunctionCallee getMessageSendFpretFixupFn() {

681

llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };

684 "objc_msgSend_fpret_fixup"

);

687

llvm::FunctionCallee getMessageSendStretFixupFn() {

689

llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };

692 "objc_msgSend_stret_fixup"

);

695

llvm::FunctionCallee getMessageSendSuper2FixupFn() {

698

llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };

701 "objc_msgSendSuper2_fixup"

);

704

llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {

707

llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };

710 "objc_msgSendSuper2_stret_fixup"

);

713

llvm::FunctionCallee getObjCEndCatchFn() {

718

llvm::FunctionCallee getObjCBeginCatchFn() {

719

llvm::Type *params[] = { Int8PtrTy };

722 "objc_begin_catch"

);

730

llvm::FunctionCallee getLoadClassrefFn()

const

{

736

llvm::Type *params[] = { Int8PtrPtrTy };

738

llvm::AttributeSet AS = llvm::AttributeSet::get(

C

, {

739

llvm::Attribute::get(

C

, llvm::Attribute::NonLazyBind),

740

llvm::Attribute::getWithMemoryEffects(

C

, llvm::MemoryEffects::none()),

741

llvm::Attribute::get(

C

, llvm::Attribute::NoUnwind),

744

llvm::FunctionType::get(ClassnfABIPtrTy, params,

false

),

745 "objc_loadClassref"

,

747

llvm::AttributeList::FunctionIndex, AS));

748 if

(!CGM.

getTriple

().isOSBinFormatCOFF())

749

cast<llvm::Function>(F.getCallee())->setLinkage(

750

llvm::Function::ExternalWeakLinkage);

755

llvm::StructType *EHTypeTy;

756

llvm::Type *EHTypePtrTy;

761enum class

ObjCLabelType {

774

SKIP_SCAN(

unsigned

_skip = 0,

unsigned

_scan = 0)

775

: skip(_skip), scan(_scan) {}

782 enum

BLOCK_LAYOUT_OPCODE {

789

BLOCK_LAYOUT_OPERATOR = 0,

795

BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,

800

BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,

804

BLOCK_LAYOUT_STRONG = 3,

807

BLOCK_LAYOUT_BYREF = 4,

811

BLOCK_LAYOUT_WEAK = 5,

815

BLOCK_LAYOUT_UNRETAINED = 6

832 enum

BLOCK_LAYOUT_OPCODE opcode;

835

RUN_SKIP(

enum

BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,

838

: opcode(

Opcode

), block_var_bytepos(BytePos), block_var_size(

Size

) {}

842 return

block_var_bytepos <

b

.block_var_bytepos;

847

llvm::LLVMContext &VMContext;

856

llvm::SetVector<IdentifierInfo*> LazySymbols;

862

llvm::SetVector<IdentifierInfo*> DefinedSymbols;

865

llvm::StringMap<llvm::GlobalVariable*> ClassNames;

868

llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;

875

llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;

879

llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;

883

llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> DirectMethodDefinitions;

886

llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;

889

llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;

892

llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;

897

llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;

901

llvm::DenseSet<IdentifierInfo*> DefinedProtocols;

923

llvm::WeakTrackingVH ConstantStringClassRef;

926

llvm::StructType *NSConstantStringType =

nullptr

;

928

llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;

932

llvm::Constant *GetMethodVarName(

Selector

Sel);

940 bool

Extended =

false

);

941

llvm::Constant *GetMethodVarType(

const FieldDecl

*

D

);

949 const Decl

*Container);

954

llvm::Constant *GetClassName(StringRef RuntimeName);

968 bool

forStrongLayout,

974 return

BuildIvarLayout(OI, beginOffset, endOffset,

true

,

false

);

981 return

BuildIvarLayout(OI, beginOffset, endOffset,

false

,

hasMRCWeakIvars

);

986 void

UpdateRunSkipBlockVars(

bool

IsByref,

991 void

BuildRCBlockVarRecordLayout(

const RecordType

*RT,

993 bool

ByrefLayout=

false

);

995 void

BuildRCRecordLayout(

const

llvm::StructLayout *RecLayout,

1003

llvm::Constant *getBitmapBlockLayout(

bool

ComputeByrefLayout);

1008 const

ObjCCommonTypesHelper &ObjCTypes);

1012

llvm::Constant *EmitPropertyList(Twine Name,

1013 const Decl

*Container,

1015 const

ObjCCommonTypesHelper &ObjCTypes,

1016 bool

IsClassProperty);

1020

llvm::Constant *EmitProtocolMethodTypes(Twine Name,

1022 const

ObjCCommonTypesHelper &ObjCTypes);

1033

ObjCCommonTypesHelper &ObjCTypes);

1035

std::string GetSectionName(StringRef Section, StringRef MachOAttributes);

1052

llvm::GlobalVariable *CreateMetadataVar(Twine Name,

1056

llvm::GlobalVariable *CreateMetadataVar(Twine Name,

1057

llvm::Constant *

Init

,

1061

llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,

1062

ObjCLabelType LabelType,

1063 bool

ForceNonFragileABI =

false

,

1064 bool

NullTerminate =

true

);

1077 const

ObjCCommonTypesHelper &ObjCTypes);

1081 void

EmitImageInfo();

1087 bool

isNonFragileABI()

const

{

1088 return

ObjCABI == 2;

1110 virtual

llvm::Constant *GetOrEmitProtocolRef(

const ObjCProtocolDecl

*PD)=0;

1112 virtual

llvm::Constant *getNSConstantStringClassRef() = 0;

1130enum class

MethodListType {

1131

CategoryInstanceMethods,

1132

CategoryClassMethods,

1135

ProtocolInstanceMethods,

1136

ProtocolClassMethods,

1137

OptionalProtocolInstanceMethods,

1138

OptionalProtocolClassMethods,

1143class

ProtocolMethodLists {

1146

RequiredInstanceMethods,

1147

RequiredClassMethods,

1148

OptionalInstanceMethods,

1149

OptionalClassMethods

1152

NumProtocolMethodLists = 4

1155 static

MethodListType getMethodListKind(Kind kind) {

1157 case

RequiredInstanceMethods:

1158 return

MethodListType::ProtocolInstanceMethods;

1159 case

RequiredClassMethods:

1160 return

MethodListType::ProtocolClassMethods;

1161 case

OptionalInstanceMethods:

1162 return

MethodListType::OptionalProtocolInstanceMethods;

1163 case

OptionalClassMethods:

1164 return

MethodListType::OptionalProtocolClassMethods;

1166

llvm_unreachable(

"bad kind"

);

1172

ProtocolMethodLists result;

1174 for

(

auto

*MD : PD->

methods

()) {

1175 size_t

index = (2 *

size_t

(MD->isOptional()))

1176

+ (

size_t

(MD->isClassMethod()));

1177

result.Methods[index].push_back(MD);

1183 template

<

class

Self>

1194 for

(

auto

&list : Methods) {

1195 for

(

auto

MD : list) {

1196

result.push_back(self->GetMethodVarType(MD,

true

));

1203 template

<

class

Self>

1207

getMethodListKind(kind), Methods[kind]);

1213class

CGObjCMac :

public

CGObjCCommonMac {

1215 friend

ProtocolMethodLists;

1217

ObjCTypesHelper ObjCTypes;

1221 void

EmitModuleInfo();

1225

llvm::Constant *EmitModuleSymbols();

1229 void

FinishModule();

1247

llvm::Value *EmitNSAutoreleasePoolClassRef(

CodeGenFunction

&CGF)

override

;

1268

llvm::Constant *Protocols,

1279

llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,

1291

llvm::Constant *GetOrEmitProtocolRef(

const ObjCProtocolDecl

*PD)

override

;

1299 const

ProtocolMethodLists &methodLists);

1303

llvm::Constant *EmitProtocolList(Twine Name,

1315

llvm::Constant *getNSConstantStringClassRef()

override

;

1317

llvm::Function *ModuleInitFunction()

override

;

1322 Selector

Sel, llvm::Value *Receiver,

1331 bool

isCategoryImpl, llvm::Value *Receiver,

1346

llvm::Constant *GetEHType(

QualType T

)

override

;

1357

llvm::FunctionCallee GetPropertyGetFunction()

override

;

1358

llvm::FunctionCallee GetPropertySetFunction()

override

;

1359

llvm::FunctionCallee GetOptimizedPropertySetFunction(

bool

atomic,

1360 bool

copy)

override

;

1361

llvm::FunctionCallee GetGetStructFunction()

override

;

1362

llvm::FunctionCallee GetSetStructFunction()

override

;

1363

llvm::FunctionCallee GetCppAtomicObjectGetFunction()

override

;

1364

llvm::FunctionCallee GetCppAtomicObjectSetFunction()

override

;

1365

llvm::FunctionCallee EnumerationMutationFunction()

override

;

1373 bool

ClearInsertionPoint=

true

)

override

;

1375 Address

AddrWeakObj)

override

;

1377

llvm::Value *src,

Address

dst)

override

;

1379

llvm::Value *src,

Address

dest,

1380 bool

threadlocal =

false

)

override

;

1382

llvm::Value *src,

Address

dest,

1383

llvm::Value *ivarOffset)

override

;

1385

llvm::Value *src,

Address

dest)

override

;

1388

llvm::Value *size)

override

;

1392 unsigned

CVRQualifiers)

override

;

1398class

CGObjCNonFragileABIMac :

public

CGObjCCommonMac {

1400 friend

ProtocolMethodLists;

1401

ObjCNonFragileABITypesHelper ObjCTypes;

1402

llvm::GlobalVariable* ObjCEmptyCacheVar;

1403

llvm::Constant* ObjCEmptyVtableVar;

1406

llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;

1409

llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;

1412

llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;

1416

llvm::DenseSet<Selector> VTableDispatchMethods;

1419

std::vector<llvm::GlobalValue*> DefinedMetaClasses;

1423 bool

isVTableDispatchedSelector(

Selector

Sel);

1427 void

FinishNonFragileABIModule();

1432

StringRef SymbolName, StringRef SectionName);

1434

llvm::GlobalVariable * BuildClassRoTInitializer(

unsigned

flags,

1435 unsigned

InstanceStart,

1436 unsigned

InstanceSize,

1440

llvm::Constant *IsAGV,

1441

llvm::Constant *SuperClassGV,

1442

llvm::Constant *ClassRoGV,

1451

llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,

1463 unsigned long int

offset);

1474

llvm::Constant *GetOrEmitProtocolRef(

const ObjCProtocolDecl

*PD)

override

;

1478

llvm::Constant *EmitProtocolList(Twine Name,

1486

llvm::Value *Receiver,

1494

llvm::Constant *GetClassGlobal(StringRef Name,

1496 bool

Weak =

false

,

bool

DLLImport =

false

);

1505

llvm::GlobalVariable *Entry);

1516

llvm::Value *EmitNSAutoreleasePoolClassRef(

CodeGenFunction

&CGF)

override

;

1531

llvm::GlobalVariable * ObjCIvarOffsetVariable(

1545

StringRef getMetaclassSymbolPrefix()

const

{

return "OBJC_METACLASS_$_"

; }

1547

StringRef getClassSymbolPrefix()

const

{

return "OBJC_CLASS_$_"

; }

1550

uint32_t &InstanceStart,

1551

uint32_t &InstanceSize);

1566 bool

ImplementationIsNonLazy(

const ObjCImplDecl

*OD)

const

;

1585

dyn_cast_or_null<ObjCMethodDecl>(CGF.

CurFuncDecl

))

1586 if

(MD->isInstanceMethod() && !MD->isDirectMethod())

1595 for

(;

ID

;

ID

=

ID

->getSuperClass()) {

1598 if

(

ID

->getIdentifier()->getName() ==

"NSObject"

)

1603 if

(!

ID

->getImplementation())

1612

llvm::Constant *getNSConstantStringClassRef()

override

;

1614

llvm::Function *ModuleInitFunction()

override

;

1619

llvm::Value *Receiver,

1628 bool

isCategoryImpl, llvm::Value *Receiver,

1636

{

return

EmitSelector(CGF, Sel); }

1638

{

return

EmitSelectorAddr(Sel); }

1644

{

return

EmitSelector(CGF, Method->

getSelector

()); }

1655

llvm::Constant *GetEHType(

QualType T

)

override

;

1657

llvm::FunctionCallee GetPropertyGetFunction()

override

{

1658 return

ObjCTypes.getGetPropertyFn();

1660

llvm::FunctionCallee GetPropertySetFunction()

override

{

1661 return

ObjCTypes.getSetPropertyFn();

1664

llvm::FunctionCallee GetOptimizedPropertySetFunction(

bool

atomic,

1665 bool

copy)

override

{

1666 return

ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);

1669

llvm::FunctionCallee GetSetStructFunction()

override

{

1670 return

ObjCTypes.getCopyStructFn();

1673

llvm::FunctionCallee GetGetStructFunction()

override

{

1674 return

ObjCTypes.getCopyStructFn();

1677

llvm::FunctionCallee GetCppAtomicObjectSetFunction()

override

{

1678 return

ObjCTypes.getCppAtomicObjectFunction();

1681

llvm::FunctionCallee GetCppAtomicObjectGetFunction()

override

{

1682 return

ObjCTypes.getCppAtomicObjectFunction();

1685

llvm::FunctionCallee EnumerationMutationFunction()

override

{

1686 return

ObjCTypes.getEnumerationMutationFn();

1694 bool

ClearInsertionPoint=

true

)

override

;

1696 Address

AddrWeakObj)

override

;

1698

llvm::Value *src,

Address

edst)

override

;

1700

llvm::Value *src,

Address

dest,

1701 bool

threadlocal =

false

)

override

;

1703

llvm::Value *src,

Address

dest,

1704

llvm::Value *ivarOffset)

override

;

1706

llvm::Value *src,

Address

dest)

override

;

1709

llvm::Value *size)

override

;

1712 unsigned

CVRQualifiers)

override

;

1720struct

NullReturnState {

1721

llvm::BasicBlock *NullBB =

nullptr

;

1722

NullReturnState() =

default

;

1735

CGF.

Builder

.CreateCondBr(isNull, NullBB, callBB);

1750 if

(!NullBB)

return

result;

1754

llvm::BasicBlock *contBB =

nullptr

;

1757

llvm::BasicBlock *callBB = CGF.

Builder

.GetInsertBlock();

1760

CGF.

Builder

.CreateBr(contBB);

1772

assert(CGF.

Builder

.GetInsertBlock() == NullBB);

1792

llvm::PHINode *phi = CGF.

Builder

.CreatePHI(null->getType(), 2);

1794

phi->addIncoming(null, NullBB);

1803

assert(result.

isAggregate

() &&

"null init of non-aggregate result?"

);

1812

CodeGenFunction::ComplexPairTy callResult = result.

getComplexVal

();

1815

llvm::Type *scalarTy = callResult.first->getType();

1816

llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);

1819

llvm::PHINode *real = CGF.

Builder

.CreatePHI(scalarTy, 2);

1820

real->addIncoming(callResult.first, callBB);

1821

real->addIncoming(scalarZero, NullBB);

1822

llvm::PHINode *imag = CGF.

Builder

.CreatePHI(scalarTy, 2);

1823

imag->addIncoming(callResult.second, callBB);

1824

imag->addIncoming(scalarZero, NullBB);

1835

llvm::GlobalVariable *

C

,

unsigned

idx0,

1837

llvm::Value *Idxs[] = {

1838

llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),

1839

llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)

1841 return

llvm::ConstantExpr::getGetElementPtr(

C

->getValueType(),

C

, Idxs);

1848 if

(OID->

hasAttr

<ObjCExceptionAttr>())

1855static

llvm::GlobalValue::LinkageTypes

1857 if

(CGM.

getTriple

().isOSBinFormatMachO() &&

1858

(Section.empty() || Section.starts_with(

"__DATA"

)))

1859 return

llvm::GlobalValue::InternalLinkage;

1860 return

llvm::GlobalValue::PrivateLinkage;

1864static

llvm::GlobalVariable *

1867

std::string SectionName;

1868 if

(CGM.

getTriple

().isOSBinFormatMachO())

1869

SectionName =

"__DATA, __objc_const"

;

1870 auto

*GV = Builder.finishAndCreateGlobal(

1873

GV->setSection(SectionName);

1889 return

EmitClassRef(CGF, ID);

1894 return

EmitSelector(CGF, Sel);

1897 return

EmitSelectorAddr(Sel);

1901 return

EmitSelector(CGF, Method->

getSelector

());

1904

llvm::Constant *CGObjCMac::GetEHType(

QualType T

) {

1918

llvm_unreachable(

"asking for catch type for ObjC type in fragile runtime"

);

1941

CGObjCCommonMac::GenerateConstantString(

const StringLiteral

*SL) {

1944

: GenerateConstantNSString(SL));

1947static

llvm::StringMapEntry<llvm::GlobalVariable *> &

1950

StringRef String = Literal->getString();

1951

StringLength = String.size();

1952 return

*Map.insert(std::make_pair(String,

nullptr

)).first;

1955

llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {

1956 if

(llvm::Value *

V

= ConstantStringClassRef)

1957 return

cast<llvm::Constant>(

V

);

1961

StringClass.empty() ?

"_NSConstantStringClassReference" 1962

:

"_"

+ StringClass +

"ClassReference"

;

1964

llvm::Type *PTy = llvm::ArrayType::get(CGM.

IntTy

, 0);

1966

ConstantStringClassRef = GV;

1970

llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {

1971 if

(llvm::Value *

V

= ConstantStringClassRef)

1972 return

cast<llvm::Constant>(

V

);

1976

StringClass.empty() ?

"OBJC_CLASS_$_NSConstantString" 1977

:

"OBJC_CLASS_$_"

+ StringClass;

1979

ConstantStringClassRef = GV;

1984

CGObjCCommonMac::GenerateConstantNSString(

const StringLiteral

*Literal) {

1985 unsigned

StringLength = 0;

1986

llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =

1989 if

(

auto

*

C

= Entry.second)

1994

llvm::Constant *

Class

= getNSConstantStringClassRef();

1997 if

(!NSConstantStringType) {

1998

NSConstantStringType =

2000 "struct.__builtin_NSString"

);

2004 auto

Fields = Builder.beginStruct(NSConstantStringType);

2010

llvm::Constant *

C

=

2011

llvm::ConstantDataArray::getString(VMContext, Entry.first());

2013

llvm::GlobalValue::LinkageTypes

Linkage

= llvm::GlobalValue::PrivateLinkage;

2014 bool

isConstant = !CGM.

getLangOpts

().WritableStrings;

2016 auto

*GV =

new

llvm::GlobalVariable(CGM.

getModule

(),

C

->getType(), isConstant,

2018

GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

2021

GV->setAlignment(llvm::Align(1));

2025

Fields.addInt(CGM.

IntTy

, StringLength);

2029

GV = Fields.finishAndCreateGlobal(

"_unnamed_nsstring_"

, Alignment,

2031

llvm::GlobalVariable::PrivateLinkage);

2032 const char

*NSStringSection =

"__OBJC,__cstring_object,regular,no_dead_strip"

;

2033 const char

*NSStringNonFragileABISection =

2034 "__DATA,__objc_stringobj,regular,no_dead_strip"

;

2037

? NSStringNonFragileABISection

2057 bool

isCategoryImpl,

2058

llvm::Value *Receiver,

2059 bool

IsClassMessage,

2066

llvm::Value *ReceiverAsObject =

2067

CGF.

Builder

.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);

2072

llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(ObjCTypes.ClassTy);

2074 if

(IsClassMessage) {

2075 if

(isCategoryImpl) {

2082 Target

= EmitClassRef(CGF,

Class

->getSuperClass());

2087

llvm::Constant *MetaClassPtr = EmitMetaClassRef(

Class

);

2088

llvm::Value *SuperPtr =

2094

}

else if

(isCategoryImpl)

2095 Target

= EmitClassRef(CGF,

Class

->getSuperClass());

2097

llvm::Value *ClassPtr = EmitSuperClassRef(Class);

2104

llvm::Type *ClassTy =

2108 return

EmitMessageSend(CGF, Return, ResultType, Sel, ObjCSuper.

getPointer

(),

2109

ObjCTypes.SuperPtrCTy,

true

, CallArgs, Method, Class,

2118

llvm::Value *Receiver,

2122 return

EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,

2124

Method, Class, ObjCTypes);

2138 const

ObjCCommonTypesHelper &ObjCTypes) {

2141

llvm::Value *SelValue = llvm::UndefValue::get(Types.ConvertType(selTy));

2145

Arg0 = CGF.

Builder

.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);

2149

ActualArgs.

addFrom

(CallArgs);

2152

MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);

2157 "Result type mismatch!"

);

2159 bool

ReceiverCanBeNull =

2160

canMessageReceiverBeNull(CGF, Method, IsSuper, ClassReceiver, Arg0);

2162 bool

RequiresNullCheck =

false

;

2163 bool

RequiresSelValue =

true

;

2165

llvm::FunctionCallee

Fn

=

nullptr

;

2171

RequiresSelValue =

false

;

2173 if

(ReceiverCanBeNull) RequiresNullCheck =

true

;

2174 Fn

= (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)

2175

: ObjCTypes.getSendStretFn(IsSuper);

2177 Fn

= (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)

2178

: ObjCTypes.getSendFpretFn(IsSuper);

2180 Fn

= (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)

2181

: ObjCTypes.getSendFp2retFn(IsSuper);

2186

RequiresNullCheck =

true

;

2187 Fn

= (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)

2188

: ObjCTypes.getSendFn(IsSuper);

2192

llvm::Constant *BitcastFn = cast<llvm::Constant>(

2193

CGF.

Builder

.CreateBitCast(

Fn

.getCallee(), MSI.MessengerType));

2198

RequiresNullCheck =

false

;

2202

RequiresNullCheck =

true

;

2204

NullReturnState nullReturn;

2205 if

(RequiresNullCheck) {

2206

nullReturn.init(CGF, Arg0);

2210 if

(RequiresSelValue) {

2211

SelValue = GetSelector(CGF, Sel);

2215

llvm::CallBase *CallSite;

2217 RValue

rvalue = CGF.

EmitCall

(MSI.CallInfo, Callee, Return, ActualArgs,

2222 if

(Method && Method->

hasAttr

<NoReturnAttr>() && !ReceiverCanBeNull) {

2223

CallSite->setDoesNotReturn();

2226 return

nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,

2227

RequiresNullCheck ? Method :

nullptr

);

2231 bool

pointee =

false

) {

2244 switch

(ownership) {

2251

llvm_unreachable(

"bad objc ownership"

);

2259 if

(Ctx.

getLangOpts

().getGC() != LangOptions::NonGC) {

2271

IvarInfo(

CharUnits

offset, uint64_t sizeInWords)

2272

: Offset(offset), SizeInWords(sizeInWords) {}

2275 bool operator<

(

const

IvarInfo &other)

const

{

2276 return

Offset < other.Offset;

2281 class

IvarLayoutBuilder {

2292 bool

ForStrongLayout;

2295 bool

IsDisordered =

false

;

2301 CharUnits

instanceEnd,

bool

forStrongLayout)

2302

: CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),

2303

ForStrongLayout(forStrongLayout) {

2308 template

<

class

Iterator,

class

GetOffsetFn>

2309 void

visitAggregate(Iterator begin, Iterator end,

2311 const

GetOffsetFn &getOffset);

2319 bool

hasBitmapData()

const

{

return

!IvarsInfo.empty(); }

2321

llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,

2325 const unsigned char

*

s

= buffer.data();

2326 for

(

unsigned

i = 0, e = buffer.size(); i < e; i++)

2327 if

(!(

s

[i] & 0xf0))

2328 printf

(

"0x0%x%s"

,

s

[i],

s

[i] != 0 ?

", "

:

""

);

2330 printf

(

"0x%x%s"

,

s

[i],

s

[i] != 0 ?

", "

:

""

);

2336

llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(

CodeGenModule

&CGM,

2339

llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.

Int8PtrTy

);

2340 if

(CGM.

getLangOpts

().getGC() == LangOptions::NonGC)

2346

builder.visitBlock(blockInfo);

2348 if

(!builder.hasBitmapData())

2352

llvm::Constant *

C

= builder.buildBitmap(*

this

, buffer);

2353 if

(CGM.

getLangOpts

().ObjCGCBitmapPrint && !buffer.empty()) {

2354 printf

(

"\n block variable layout for block: "

);

2355

builder.dump(buffer);

2361void

IvarLayoutBuilder::visitBlock(

const CGBlockInfo

&blockInfo) {

2374 for

(

const auto

&CI :

blockDecl

->captures()) {

2375 const VarDecl

*variable = CI.getVariable();

2387 if

(fieldOffset < lastFieldOffset)

2388

IsDisordered =

true

;

2389

lastFieldOffset = fieldOffset;

2393

IvarsInfo.push_back(IvarInfo(fieldOffset,

1));

2397

assert(!

type

->isArrayType() &&

"array variable should not be caught"

);

2399

visitRecord(record, fieldOffset);

2408

IvarsInfo.push_back(IvarInfo(fieldOffset,

1));

2433void

CGObjCCommonMac::UpdateRunSkipBlockVars(

bool

IsByref,

2439

RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,

2442

RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,

2445

RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,

2448

RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,

2451

RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,

2456void

CGObjCCommonMac::BuildRCRecordLayout(

const

llvm::StructLayout *RecLayout,

2461 bool

IsUnion = (RD && RD->

isUnion

());

2464 const FieldDecl

*LastFieldBitfieldOrUnnamed =

nullptr

;

2468 if

(RecFields.empty())

2472 for

(

unsigned

i = 0, e = RecFields.size(); i != e; ++i) {

2481 if

(!

Field

->getIdentifier() ||

Field

->isBitField()) {

2482

LastFieldBitfieldOrUnnamed =

Field

;

2483

LastBitfieldOrUnnamedOffset = FieldOffset;

2487

LastFieldBitfieldOrUnnamed =

nullptr

;

2494

BytePos + FieldOffset, HasUnion);

2499 auto

*CArray = cast<ConstantArrayType>(Array);

2500 uint64_t

ElCount = CArray->getZExtSize();

2501

assert(CArray &&

"only array with known element size is supported"

);

2502

FQT = CArray->getElementType();

2504 auto

*CArray = cast<ConstantArrayType>(Array);

2505

ElCount *= CArray->getZExtSize();

2506

FQT = CArray->getElementType();

2509 int

OldIndex = RunSkipBlockVars.size() - 1;

2511

BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset, HasUnion);

2516 for

(

int

FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {

2518 for

(

int

i = OldIndex+1; i <= FirstIndex; ++i)

2519

RunSkipBlockVars.push_back(

2520

RUN_SKIP(RunSkipBlockVars[i].opcode,

2521

RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,

2522

RunSkipBlockVars[i].block_var_size));

2530 if

(UnionIvarSize > MaxUnionSize) {

2531

MaxUnionSize = UnionIvarSize;

2533

MaxFieldOffset = FieldOffset;

2536

UpdateRunSkipBlockVars(

false

,

2537

getBlockCaptureLifetime(FQT, ByrefLayout),

2538

BytePos + FieldOffset,

2543 if

(LastFieldBitfieldOrUnnamed) {

2544 if

(LastFieldBitfieldOrUnnamed->

isBitField

()) {

2547 unsigned

UnsSize = (BitFieldSize / ByteSizeInBits) +

2548

((BitFieldSize % ByteSizeInBits) != 0);

2550 Size

+= LastBitfieldOrUnnamedOffset;

2551

UpdateRunSkipBlockVars(

false

,

2552

getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->

getType

(),

2554

BytePos + LastBitfieldOrUnnamedOffset,

2557

assert(!LastFieldBitfieldOrUnnamed->

getIdentifier

() &&

"Expected unnamed"

);

2561

UpdateRunSkipBlockVars(

false

,

2562

getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->

getType

(),

2564

BytePos + LastBitfieldOrUnnamedOffset,

2570

UpdateRunSkipBlockVars(

false

,

2571

getBlockCaptureLifetime(MaxField->

getType

(), ByrefLayout),

2572

BytePos + MaxFieldOffset,

2576void

CGObjCCommonMac::BuildRCBlockVarRecordLayout(

const RecordType

*RT,

2583 const

llvm::StructLayout *RecLayout =

2584

CGM.

getDataLayout

().getStructLayout(cast<llvm::StructType>(Ty));

2586

BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);

2598uint64_t

CGObjCCommonMac::InlineLayoutInstruction(

2601 if

(Layout.size() <= 3) {

2602 unsigned

size = Layout.size();

2603 unsigned

strong_word_count = 0, byref_word_count=0, weak_word_count=0;

2605 enum

BLOCK_LAYOUT_OPCODE opcode ;

2609

opcode = (

enum

BLOCK_LAYOUT_OPCODE) (inst >> 4);

2610 if

(opcode == BLOCK_LAYOUT_STRONG)

2611

strong_word_count = (inst & 0xF)+1;

2615

opcode = (

enum

BLOCK_LAYOUT_OPCODE) (inst >> 4);

2616 if

(opcode == BLOCK_LAYOUT_BYREF)

2617

byref_word_count = (inst & 0xF)+1;

2621

opcode = (

enum

BLOCK_LAYOUT_OPCODE) (inst >> 4);

2622 if

(opcode == BLOCK_LAYOUT_WEAK)

2623

weak_word_count = (inst & 0xF)+1;

2630

opcode = (

enum

BLOCK_LAYOUT_OPCODE) (inst >> 4);

2631 if

(opcode == BLOCK_LAYOUT_STRONG) {

2632

strong_word_count = (inst & 0xF)+1;

2634

opcode = (

enum

BLOCK_LAYOUT_OPCODE) (inst >> 4);

2635 if

(opcode == BLOCK_LAYOUT_BYREF)

2636

byref_word_count = (inst & 0xF)+1;

2637 else if

(opcode == BLOCK_LAYOUT_WEAK)

2638

weak_word_count = (inst & 0xF)+1;

2642 else if

(opcode == BLOCK_LAYOUT_BYREF) {

2643

byref_word_count = (inst & 0xF)+1;

2645

opcode = (

enum

BLOCK_LAYOUT_OPCODE) (inst >> 4);

2646 if

(opcode == BLOCK_LAYOUT_WEAK)

2647

weak_word_count = (inst & 0xF)+1;

2657

opcode = (

enum

BLOCK_LAYOUT_OPCODE) (inst >> 4);

2658 if

(opcode == BLOCK_LAYOUT_STRONG)

2659

strong_word_count = (inst & 0xF)+1;

2660 else if

(opcode == BLOCK_LAYOUT_BYREF)

2661

byref_word_count = (inst & 0xF)+1;

2662 else if

(opcode == BLOCK_LAYOUT_WEAK)

2663

weak_word_count = (inst & 0xF)+1;

2675 if

(strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)

2679

(strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);

2681 if

(size == count) {

2682 if

(strong_word_count)

2683

Result = strong_word_count;

2685 if

(byref_word_count)

2686

Result += byref_word_count;

2688 if

(weak_word_count)

2689

Result += weak_word_count;

2695

llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(

bool

ComputeByrefLayout) {

2696

llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.

Int8PtrTy

);

2697 if

(RunSkipBlockVars.empty())

2701 unsigned

WordSizeInBytes = WordSizeInBits/ByteSizeInBits;

2705

llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());

2708 unsigned

size = RunSkipBlockVars.size();

2709 for

(

unsigned

i = 0; i < size; i++) {

2710 enum

BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;

2711 CharUnits

start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;

2712 CharUnits

end_byte_pos = start_byte_pos;

2715 if

(opcode == RunSkipBlockVars[j].opcode) {

2716

end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;

2723

end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;

2726

RunSkipBlockVars[j].block_var_bytepos -

2727

RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;

2728

size_in_bytes += gap;

2731 if

(opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {

2732

residue_in_bytes = size_in_bytes % WordSizeInBytes;

2733

size_in_bytes -= residue_in_bytes;

2734

opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;

2737 unsigned

size_in_words = size_in_bytes.

getQuantity

() / WordSizeInBytes;

2738 while

(size_in_words >= 16) {

2741 unsigned char

inst = (opcode << 4) | 0xf;

2742

Layout.push_back(inst);

2743

size_in_words -= 16;

2745 if

(size_in_words > 0) {

2748 unsigned char

inst = (opcode << 4) | (size_in_words-1);

2749

Layout.push_back(inst);

2752 unsigned char

inst =

2753

(BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.

getQuantity

()-1);

2754

Layout.push_back(inst);

2758 while

(!Layout.empty()) {

2759 unsigned char

inst = Layout.back();

2760 enum

BLOCK_LAYOUT_OPCODE opcode = (

enum

BLOCK_LAYOUT_OPCODE) (inst >> 4);

2761 if

(opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)

2767 uint64_t

Result = InlineLayoutInstruction(Layout);

2771 if

(ComputeByrefLayout)

2772 printf

(

"\n Inline BYREF variable layout: "

);

2774 printf

(

"\n Inline block variable layout: "

);

2775 printf

(

"0x0%"

PRIx64

""

, Result);

2776 if

(

auto

numStrong = (Result & 0xF00) >> 8)

2777 printf

(

", BL_STRONG:%d"

, (

int

) numStrong);

2778 if

(

auto

numByref = (Result & 0x0F0) >> 4)

2779 printf

(

", BL_BYREF:%d"

, (

int

) numByref);

2780 if

(

auto

numWeak = (Result & 0x00F) >> 0)

2781 printf

(

", BL_WEAK:%d"

, (

int

) numWeak);

2782 printf

(

", BL_OPERATOR:0\n"

);

2784 return

llvm::ConstantInt::get(CGM.

IntPtrTy

, Result);

2787 unsigned char

inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;

2788

Layout.push_back(inst);

2790 for

(

unsigned

i = 0, e = Layout.size(); i != e; i++)

2791

BitMap += Layout[i];

2794 if

(ComputeByrefLayout)

2795 printf

(

"\n Byref variable layout: "

);

2797 printf

(

"\n Block variable layout: "

);

2798 for

(

unsigned

i = 0, e = BitMap.size(); i != e; i++) {

2799 unsigned char

inst = BitMap[i];

2800 enum

BLOCK_LAYOUT_OPCODE opcode = (

enum

BLOCK_LAYOUT_OPCODE) (inst >> 4);

2803 case

BLOCK_LAYOUT_OPERATOR:

2804 printf

(

"BL_OPERATOR:"

);

2807 case

BLOCK_LAYOUT_NON_OBJECT_BYTES:

2808 printf

(

"BL_NON_OBJECT_BYTES:"

);

2810 case

BLOCK_LAYOUT_NON_OBJECT_WORDS:

2811 printf

(

"BL_NON_OBJECT_WORD:"

);

2813 case

BLOCK_LAYOUT_STRONG:

2816 case

BLOCK_LAYOUT_BYREF:

2819 case

BLOCK_LAYOUT_WEAK:

2822 case

BLOCK_LAYOUT_UNRETAINED:

2823 printf

(

"BL_UNRETAINED:"

);

2828 printf

(

"%d"

, (inst & 0xf) + delta);

2836 auto

*Entry = CreateCStringLiteral(BitMap, ObjCLabelType::ClassName,

2844 bool

HasCopyDisposeHelpers) {

2846 for

(

const

CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {

2847 if

(R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {

2851

}

else if

(HasCopyDisposeHelpers) {

2859 case

CGObjCCommonMac::BLOCK_LAYOUT_STRONG:

2862 case

CGObjCCommonMac::BLOCK_LAYOUT_BYREF:

2865 case

CGObjCCommonMac::BLOCK_LAYOUT_WEAK:

2872

Str += llvm::to_string(R.block_var_bytepos.getQuantity());

2873

Str +=

"l"

+ llvm::to_string(R.block_var_size.getQuantity());

2878void

CGObjCCommonMac::fillRunSkipBlockVars(

CodeGenModule

&CGM,

2880

assert(CGM.

getLangOpts

().getGC() == LangOptions::NonGC);

2882

RunSkipBlockVars.clear();

2883 bool

hasUnion =

false

;

2887 unsigned

WordSizeInBytes = WordSizeInBits/ByteSizeInBits;

2892 const

llvm::StructLayout *layout =

2902 for

(

const auto

&CI :

blockDecl

->captures()) {

2903 const VarDecl

*variable = CI.getVariable();

2914

assert(!

type

->isArrayType() &&

"array variable should not be caught"

);

2917

BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);

2925

UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(

type

,

false

),

2926

fieldOffset, fieldSize);

2933

fillRunSkipBlockVars(CGM, blockInfo);

2934 return

getBitmapBlockLayout(

false

);

2937

std::string CGObjCCommonMac::getRCBlockLayoutStr(

CodeGenModule

&CGM,

2939

fillRunSkipBlockVars(CGM, blockInfo);

2945

assert(CGM.

getLangOpts

().getGC() == LangOptions::NonGC);

2946

assert(!

T

->

isArrayType

() &&

"__block array variable should not be caught"

);

2948

RunSkipBlockVars.clear();

2949 bool

hasUnion =

false

;

2951

BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,

true

);

2952

llvm::Constant *Result = getBitmapBlockLayout(

true

);

2953 if

(isa<llvm::ConstantInt>(Result))

2954

Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.

Int8PtrTy

);

2957

llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.

Int8PtrTy

);

2967 return

GetProtocolRef(PD);

2979

GetOrEmitProtocol(PD);

2982

llvm::Constant *CGObjCCommonMac::GetProtocolRef(

const ObjCProtocolDecl

*PD) {

2984 return

GetOrEmitProtocol(PD);

2986 return

GetOrEmitProtocolRef(PD);

2989

llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(

2992

ObjCCommonTypesHelper &ObjCTypes) {

2993

llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();

2995

llvm::Value *className = CGF.

CGM 2997 ID

->getObjCRuntimeNameAsString()))

3001

CGF.

Builder

.CreateBitCast(className,

3004

llvm::CallInst *call = CGF.

Builder

.CreateCall(lookUpClassFn, className);

3005

call->setDoesNotThrow();

3021

llvm::Constant *CGObjCMac::GetOrEmitProtocol(

const ObjCProtocolDecl

*PD) {

3022

llvm::GlobalVariable *Entry = Protocols[PD->

getIdentifier

()];

3025 if

(Entry && Entry->hasInitializer())

3037 auto

methodLists = ProtocolMethodLists::get(PD);

3040 auto

values = builder.beginStruct(ObjCTypes.ProtocolTy);

3041

values.add(EmitProtocolExtension(PD, methodLists));

3043

values.add(EmitProtocolList(

"OBJC_PROTOCOL_REFS_"

+ PD->

getName

(),

3045

values.add(methodLists.emitMethodList(

this

, PD,

3046

ProtocolMethodLists::RequiredInstanceMethods));

3047

values.add(methodLists.emitMethodList(

this

, PD,

3048

ProtocolMethodLists::RequiredClassMethods));

3052

assert(Entry->hasPrivateLinkage());

3053

values.finishAndSetAsInitializer(Entry);

3055

Entry = values.finishAndCreateGlobal(

"OBJC_PROTOCOL_"

+ PD->

getName

(),

3058

llvm::GlobalValue::PrivateLinkage);

3059

Entry->setSection(

"__OBJC,__protocol,regular,no_dead_strip"

);

3068

llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(

const ObjCProtocolDecl

*PD) {

3069

llvm::GlobalVariable *&Entry = Protocols[PD->

getIdentifier

()];

3075

Entry =

new

llvm::GlobalVariable(CGM.

getModule

(), ObjCTypes.ProtocolTy,

3076 false

, llvm::GlobalValue::PrivateLinkage,

3077 nullptr

,

"OBJC_PROTOCOL_"

+ PD->

getName

());

3078

Entry->setSection(

"__OBJC,__protocol,regular,no_dead_strip"

);

3080

Entry->setAlignment(llvm::Align(4));

3098 const

ProtocolMethodLists &methodLists) {

3099 auto

optInstanceMethods =

3100

methodLists.emitMethodList(

this

, PD,

3101

ProtocolMethodLists::OptionalInstanceMethods);

3102 auto

optClassMethods =

3103

methodLists.emitMethodList(

this

, PD,

3104

ProtocolMethodLists::OptionalClassMethods);

3106 auto

extendedMethodTypes =

3107

EmitProtocolMethodTypes(

"OBJC_PROTOCOL_METHOD_TYPES_"

+ PD->

getName

(),

3108

methodLists.emitExtendedTypesArray(

this

),

3111 auto

instanceProperties =

3112

EmitPropertyList(

"OBJC_$_PROP_PROTO_LIST_"

+ PD->

getName

(),

nullptr

, PD,

3114 auto

classProperties =

3115

EmitPropertyList(

"OBJC_$_CLASS_PROP_PROTO_LIST_"

+ PD->

getName

(),

nullptr

,

3116

PD, ObjCTypes,

true

);

3119 if

(optInstanceMethods->isNullValue() &&

3120

optClassMethods->isNullValue() &&

3121

extendedMethodTypes->isNullValue() &&

3122

instanceProperties->isNullValue() &&

3123

classProperties->isNullValue()) {

3124 return

llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);

3128

CGM.

getDataLayout

().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);

3131 auto

values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);

3132

values.addInt(ObjCTypes.IntTy, size);

3133

values.add(optInstanceMethods);

3134

values.add(optClassMethods);

3135

values.add(instanceProperties);

3136

values.add(extendedMethodTypes);

3137

values.add(classProperties);

3140 return

CreateMetadataVar(

"_OBJC_PROTOCOLEXT_"

+ PD->

getName

(), values,

3152

CGObjCMac::EmitProtocolList(Twine name,

3156 auto

PDs = GetRuntimeProtocolList(begin, end);

3158 return

llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);

3161 auto

values = builder.beginStruct();

3164

values.addNullPointer(ObjCTypes.ProtocolListPtrTy);

3167 auto

countSlot = values.addPlaceholder();

3169 auto

refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);

3170 for

(

const auto

*Proto : PDs)

3171

refsArray.add(GetProtocolRef(Proto));

3173 auto

count = refsArray.size();

3176

refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);

3178

refsArray.finishAndAddTo(values);

3179

values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);

3182 if

(CGM.

getTriple

().isOSBinFormatMachO())

3183

section =

"__OBJC,__cat_cls_meth,regular,no_dead_strip"

;

3185

llvm::GlobalVariable *GV =

3186

CreateMetadataVar(name, values, section, CGM.

getPointerAlign

(),

false

);

3194 bool

IsClassProperty) {

3195 for

(

const auto

*PD : Proto->

properties

()) {

3196 if

(IsClassProperty != PD->isClassProperty())

3200

Properties.push_back(PD);

3219

llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,

3220 const Decl

*Container,

3222 const

ObjCCommonTypesHelper &ObjCTypes,

3223 bool

IsClassProperty) {

3224 if

(IsClassProperty) {

3228 if

((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||

3229

(Triple.isiOS() && Triple.isOSVersionLT(9)))

3230 return

llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);

3238 for

(

auto

*PD : ClassExt->properties()) {

3239 if

(IsClassProperty != PD->isClassProperty())

3241 if

(PD->isDirectProperty())

3244

Properties.push_back(PD);

3247 for

(

const auto

*PD : OCD->

properties

()) {

3248 if

(IsClassProperty != PD->isClassProperty())

3254 if

(PD->isDirectProperty())

3256

Properties.push_back(PD);

3260 for

(

const auto

*

P

: OID->all_referenced_protocols())

3264 for

(

const auto

*

P

: CD->protocols())

3269 if

(Properties.empty())

3270 return

llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);

3272 unsigned

propertySize =

3273

CGM.

getDataLayout

().getTypeAllocSize(ObjCTypes.PropertyTy);

3276 auto

values = builder.beginStruct();

3277

values.addInt(ObjCTypes.IntTy, propertySize);

3278

values.addInt(ObjCTypes.IntTy, Properties.size());

3279 auto

propertiesArray = values.beginArray(ObjCTypes.PropertyTy);

3280 for

(

auto

PD : Properties) {

3281 auto property

= propertiesArray.beginStruct(ObjCTypes.PropertyTy);

3283 property

.add(GetPropertyTypeString(PD, Container));

3284 property

.finishAndAddTo(propertiesArray);

3286

propertiesArray.finishAndAddTo(values);

3289 if

(CGM.

getTriple

().isOSBinFormatMachO())

3290

Section = (ObjCABI == 2) ?

"__DATA, __objc_const" 3291

:

"__OBJC,__property,regular,no_dead_strip"

;

3293

llvm::GlobalVariable *GV =

3294

CreateMetadataVar(Name, values, Section, CGM.

getPointerAlign

(),

true

);

3299

CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,

3301 const

ObjCCommonTypesHelper &ObjCTypes) {

3303 if

(MethodTypes.empty())

3304 return

llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);

3306

llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,

3307

MethodTypes.size());

3308

llvm::Constant *

Init

= llvm::ConstantArray::get(AT, MethodTypes);

3311 if

(CGM.

getTriple

().isOSBinFormatMachO() && ObjCABI == 2)

3312

Section =

"__DATA, __objc_const"

;

3314

llvm::GlobalVariable *GV =

3343

llvm::raw_svector_ostream(ExtName) <<

Interface

->getName() <<

'_' 3347 auto

Values = Builder.beginStruct(ObjCTypes.CategoryTy);

3355 for

(

const auto

*MD : OCD->

methods

()) {

3356 if

(!MD->isDirectMethod())

3357

Methods[

unsigned

(MD->isClassMethod())].push_back(MD);

3360

Values.add(GetClassName(OCD->

getName

()));

3361

Values.add(GetClassName(

Interface

->getObjCRuntimeNameAsString()));

3362

LazySymbols.insert(

Interface

->getIdentifier());

3364

Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,

3365

Methods[InstanceMethods]));

3366

Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,

3367

Methods[ClassMethods]));

3370

EmitProtocolList(

"OBJC_CATEGORY_PROTOCOLS_"

+ ExtName.str(),

3373

Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);

3375

Values.addInt(ObjCTypes.IntTy, Size);

3379

Values.add(EmitPropertyList(

"_OBJC_$_PROP_LIST_"

+ ExtName.str(),

3380

OCD,

Category

, ObjCTypes,

false

));

3381

Values.add(EmitPropertyList(

"_OBJC_$_CLASS_PROP_LIST_"

+ ExtName.str(),

3382

OCD,

Category

, ObjCTypes,

true

));

3384

Values.addNullPointer(ObjCTypes.PropertyListPtrTy);

3385

Values.addNullPointer(ObjCTypes.PropertyListPtrTy);

3388

llvm::GlobalVariable *GV =

3389

CreateMetadataVar(

"OBJC_CATEGORY_"

+ ExtName.str(), Values,

3390 "__OBJC,__category,regular,no_dead_strip"

,

3392

DefinedCategories.push_back(GV);

3393

DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));

3395

MethodDefinitions.clear();

3455 for

(

auto

*field : recType->getDecl()->fields()) {

3470

assert(CGM.

getLangOpts

().getGC() == LangOptions::NonGC);

3473

ID->getClassInterface()->all_declared_ivar_begin();

3474

ivar; ivar = ivar->getNextIvar()) {

3504

DefinedSymbols.insert(RuntimeName);

3506

std::string ClassName =

ID

->getNameAsString();

3510

llvm::Constant *Protocols =

3511

EmitProtocolList(

"OBJC_CLASS_PROTOCOLS_"

+

ID

->getName(),

3512 Interface

->all_referenced_protocol_begin(),

3513 Interface

->all_referenced_protocol_end());

3515 if

(

ID

->hasNonZeroConstructors() ||

ID

->hasDestructors())

3518 bool

hasMRCWeak =

false

;

3538 for

(

const auto

*MD :

ID

->methods()) {

3539 if

(!MD->isDirectMethod())

3540

Methods[

unsigned

(MD->isClassMethod())].push_back(MD);

3543 for

(

const auto

*PID :

ID

->property_impls()) {

3545 if

(PID->getPropertyDecl()->isDirectProperty())

3548 if

(GetMethodDefinition(MD))

3549

Methods[InstanceMethods].push_back(MD);

3551 if

(GetMethodDefinition(MD))

3552

Methods[InstanceMethods].push_back(MD);

3557 auto

values = builder.beginStruct(ObjCTypes.ClassTy);

3558

values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));

3561

LazySymbols.insert(Super->getIdentifier());

3563

values.add(GetClassName(Super->getObjCRuntimeNameAsString()));

3565

values.addNullPointer(ObjCTypes.ClassPtrTy);

3567

values.add(GetClassName(

ID

->getObjCRuntimeNameAsString()));

3569

values.addInt(ObjCTypes.LongTy, 0);

3570

values.addInt(ObjCTypes.LongTy, Flags);

3571

values.addInt(ObjCTypes.LongTy,

Size

.getQuantity());

3572

values.add(EmitIvarList(ID,

false

));

3573

values.add(emitMethodList(

ID

->getName(), MethodListType::InstanceMethods,

3574

Methods[InstanceMethods]));

3576

values.addNullPointer(ObjCTypes.CachePtrTy);

3577

values.add(Protocols);

3579

values.add(EmitClassExtension(ID, Size, hasMRCWeak,

3582

std::string Name(

"OBJC_CLASS_"

);

3584 const char

*Section =

"__OBJC,__class,regular,no_dead_strip"

;

3586

llvm::GlobalVariable *GV = CGM.

getModule

().getGlobalVariable(Name,

true

);

3588

assert(GV->getValueType() == ObjCTypes.ClassTy &&

3589 "Forward metaclass reference has incorrect type."

);

3590

values.finishAndSetAsInitializer(GV);

3591

GV->setSection(Section);

3595

GV = CreateMetadataVar(Name, values, Section, CGM.

getPointerAlign

(),

true

);

3596

DefinedClasses.push_back(GV);

3597

ImplementedClasses.push_back(

Interface

);

3599

MethodDefinitions.clear();

3603

llvm::Constant *Protocols,

3612 auto

values = builder.beginStruct(ObjCTypes.ClassTy);

3622

values.add(GetClassName(Super->getObjCRuntimeNameAsString()));

3624

values.addNullPointer(ObjCTypes.ClassPtrTy);

3626

values.add(GetClassName(

ID

->getObjCRuntimeNameAsString()));

3628

values.addInt(ObjCTypes.LongTy, 0);

3629

values.addInt(ObjCTypes.LongTy, Flags);

3630

values.addInt(ObjCTypes.LongTy, Size);

3631

values.add(EmitIvarList(ID,

true

));

3632

values.add(emitMethodList(

ID

->getName(), MethodListType::ClassMethods,

3635

values.addNullPointer(ObjCTypes.CachePtrTy);

3636

values.add(Protocols);

3638

values.addNullPointer(ObjCTypes.Int8PtrTy);

3643

std::string Name(

"OBJC_METACLASS_"

);

3644

Name +=

ID

->getName();

3647

llvm::GlobalVariable *GV = CGM.

getModule

().getGlobalVariable(Name,

true

);

3649

assert(GV->getValueType() == ObjCTypes.ClassTy &&

3650 "Forward metaclass reference has incorrect type."

);

3651

values.finishAndSetAsInitializer(GV);

3655

llvm::GlobalValue::PrivateLinkage);

3657

GV->setSection(

"__OBJC,__meta_class,regular,no_dead_strip"

);

3664

std::string Name =

"OBJC_METACLASS_"

+

ID

->getNameAsString();

3674

llvm::GlobalVariable *GV = CGM.

getModule

().getGlobalVariable(Name,

true

);

3676

GV =

new

llvm::GlobalVariable(CGM.

getModule

(), ObjCTypes.ClassTy,

false

,

3677

llvm::GlobalValue::PrivateLinkage,

nullptr

,

3680

assert(GV->getValueType() == ObjCTypes.ClassTy &&

3681 "Forward metaclass reference has incorrect type."

);

3686

std::string Name =

"OBJC_CLASS_"

+

ID

->getNameAsString();

3687

llvm::GlobalVariable *GV = CGM.

getModule

().getGlobalVariable(Name,

true

);

3690

GV =

new

llvm::GlobalVariable(CGM.

getModule

(), ObjCTypes.ClassTy,

false

,

3691

llvm::GlobalValue::PrivateLinkage,

nullptr

,

3694

assert(GV->getValueType() == ObjCTypes.ClassTy &&

3695 "Forward class metadata reference has incorrect type."

);

3715

llvm::Constant *layout;

3717

layout = llvm::ConstantPointerNull::get(CGM.

Int8PtrTy

);

3724

llvm::Constant *propertyList =

3725

EmitPropertyList((isMetaclass ? Twine(

"_OBJC_$_CLASS_PROP_LIST_"

)

3726

: Twine(

"_OBJC_$_PROP_LIST_"

))

3728

ID,

ID

->getClassInterface(), ObjCTypes, isMetaclass);

3731 if

(layout->isNullValue() && propertyList->isNullValue()) {

3732 return

llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);

3736

CGM.

getDataLayout

().getTypeAllocSize(ObjCTypes.ClassExtensionTy);

3739 auto

values = builder.beginStruct(ObjCTypes.ClassExtensionTy);

3740

values.addInt(ObjCTypes.IntTy, size);

3742

values.add(propertyList);

3744 return

CreateMetadataVar(

"OBJC_CLASSEXT_"

+

ID

->getName(), values,

3745 "__OBJC,__class_ext,regular,no_dead_strip"

,

3769 return

llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);

3774 auto

ivarList = builder.beginStruct();

3775 auto

countSlot = ivarList.addPlaceholder();

3776 auto

ivars = ivarList.beginArray(ObjCTypes.IvarTy);

3781 if

(!IVD->getDeclName())

3784 auto

ivar = ivars.beginStruct(ObjCTypes.IvarTy);

3785

ivar.add(GetMethodVarName(IVD->getIdentifier()));

3786

ivar.add(GetMethodVarType(IVD));

3787

ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));

3788

ivar.finishAndAddTo(ivars);

3792 auto

count = ivars.size();

3796 return

llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);

3799

ivars.finishAndAddTo(ivarList);

3800

ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);

3802

llvm::GlobalVariable *GV;

3803

GV = CreateMetadataVar(

"OBJC_INSTANCE_VARIABLES_"

+

ID

->getName(), ivarList,

3804 "__OBJC,__instance_vars,regular,no_dead_strip"

,

3817 auto

description = builder.

beginStruct

(ObjCTypes.MethodDescriptionTy);

3818

description.add(GetMethodVarName(MD->

getSelector

()));

3819

description.add(GetMethodVarType(MD));

3820

description.finishAndAddTo(builder);

3832

llvm::Function *fn = GetMethodDefinition(MD);

3833

assert(fn &&

"no definition registered for method"

);

3835 auto

method = builder.

beginStruct

(ObjCTypes.MethodTy);

3836

method.add(GetMethodVarName(MD->

getSelector

()));

3837

method.add(GetMethodVarType(MD));

3839

method.finishAndAddTo(builder);

3855

llvm::Constant *CGObjCMac::emitMethodList(Twine name, MethodListType MLT,

3859 bool

forProtocol =

false

;

3861 case

MethodListType::CategoryInstanceMethods:

3862

prefix =

"OBJC_CATEGORY_INSTANCE_METHODS_"

;

3863

section =

"__OBJC,__cat_inst_meth,regular,no_dead_strip"

;

3864

forProtocol =

false

;

3866 case

MethodListType::CategoryClassMethods:

3867

prefix =

"OBJC_CATEGORY_CLASS_METHODS_"

;

3868

section =

"__OBJC,__cat_cls_meth,regular,no_dead_strip"

;

3869

forProtocol =

false

;

3871 case

MethodListType::InstanceMethods:

3872

prefix =

"OBJC_INSTANCE_METHODS_"

;

3873

section =

"__OBJC,__inst_meth,regular,no_dead_strip"

;

3874

forProtocol =

false

;

3876 case

MethodListType::ClassMethods:

3877

prefix =

"OBJC_CLASS_METHODS_"

;

3878

section =

"__OBJC,__cls_meth,regular,no_dead_strip"

;

3879

forProtocol =

false

;

3881 case

MethodListType::ProtocolInstanceMethods:

3882

prefix =

"OBJC_PROTOCOL_INSTANCE_METHODS_"

;

3883

section =

"__OBJC,__cat_inst_meth,regular,no_dead_strip"

;

3884

forProtocol =

true

;

3886 case

MethodListType::ProtocolClassMethods:

3887

prefix =

"OBJC_PROTOCOL_CLASS_METHODS_"

;

3888

section =

"__OBJC,__cat_cls_meth,regular,no_dead_strip"

;

3889

forProtocol =

true

;

3891 case

MethodListType::OptionalProtocolInstanceMethods:

3892

prefix =

"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_"

;

3893

section =

"__OBJC,__cat_inst_meth,regular,no_dead_strip"

;

3894

forProtocol =

true

;

3896 case

MethodListType::OptionalProtocolClassMethods:

3897

prefix =

"OBJC_PROTOCOL_CLASS_METHODS_OPT_"

;

3898

section =

"__OBJC,__cat_cls_meth,regular,no_dead_strip"

;

3899

forProtocol =

true

;

3904 if

(methods.empty())

3905 return

llvm::Constant::getNullValue(forProtocol

3906

? ObjCTypes.MethodDescriptionListPtrTy

3907

: ObjCTypes.MethodListPtrTy);

3914

values.addInt(ObjCTypes.IntTy, methods.size());

3915 auto

methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);

3916 for

(

auto

MD : methods) {

3917

emitMethodDescriptionConstant(methodArray, MD);

3919

methodArray.finishAndAddTo(values);

3921

llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,

3929

values.addNullPointer(ObjCTypes.Int8PtrTy);

3930

values.addInt(ObjCTypes.IntTy, methods.size());

3931 auto

methodArray = values.beginArray(ObjCTypes.MethodTy);

3932 for

(

auto

MD : methods) {

3934

emitMethodConstant(methodArray, MD);

3936

methodArray.finishAndAddTo(values);

3938

llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,

3943

llvm::Function *CGObjCCommonMac::GenerateMethod(

const ObjCMethodDecl

*OMD,

3945

llvm::Function *Method;

3948

Method = GenerateDirectMethod(OMD, CD);

3950 auto

Name = getSymbolNameForMethod(OMD);

3953

llvm::FunctionType *MethodTy =

3954

Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));

3956

llvm::Function::Create(MethodTy, llvm::GlobalValue::InternalLinkage,

3960

MethodDefinitions.insert(std::make_pair(OMD, Method));

3966

CGObjCCommonMac::GenerateDirectMethod(

const ObjCMethodDecl

*OMD,

3969 auto

I = DirectMethodDefinitions.find(COMD);

3970

llvm::Function *OldFn =

nullptr

, *

Fn

=

nullptr

;

3972 if

(I != DirectMethodDefinitions.end()) {

3988

llvm::FunctionType *MethodTy =

3989

Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));

3992 Fn

= llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,

3994 Fn

->takeName(OldFn);

3995

OldFn->replaceAllUsesWith(Fn);

3996

OldFn->eraseFromParent();

4001 auto

Name = getSymbolNameForMethod(OMD,

false

);

4003 Fn

= llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,

4005

DirectMethodDefinitions.insert(std::make_pair(COMD, Fn));

4011void

CGObjCCommonMac::GenerateDirectMethodPrologue(

4014 auto

&Builder = CGF.

Builder

;

4015 bool

ReceiverCanBeNull =

true

;

4017 auto

selfValue = Builder.CreateLoad(selfAddr);

4035 "GenerateDirectMethod() should be called with the Class Interface"

);

4048

result = GeneratePossiblySpecializedMessageSend(

4051

Builder.CreateStore(result.

getScalarVal

(), selfAddr);

4056

ReceiverCanBeNull = isWeakLinkedClass(OID);

4059 if

(ReceiverCanBeNull) {

4060

llvm::BasicBlock *SelfIsNilBlock =

4062

llvm::BasicBlock *ContBlock =

4066 auto

selfTy = cast<llvm::PointerType>(selfValue->getType());

4067 auto Zero

= llvm::ConstantPointerNull::get(selfTy);

4070

Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero), SelfIsNilBlock,

4071

ContBlock, MDHelper.createUnlikelyBranchWeights());

4077

Builder.SetInsertPoint(SelfIsNilBlock);

4078 if

(!retTy->isVoidType()) {

4086

Builder.SetInsertPoint(ContBlock);

4094

Builder.CreateStore(GetSelector(CGF, OMD),

4099

llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,

4104

llvm::GlobalValue::LinkageTypes

LT

=

4106

llvm::GlobalVariable *GV =

4107 Init

.finishAndCreateGlobal(Name, Align,

false

,

LT

);

4108 if

(!Section.empty())

4109

GV->setSection(Section);

4115

llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,

4116

llvm::Constant *

Init

,

4120

llvm::Type *Ty =

Init

->getType();

4121

llvm::GlobalValue::LinkageTypes

LT

=

4123

llvm::GlobalVariable *GV =

4124 new

llvm::GlobalVariable(CGM.

getModule

(), Ty,

false

,

LT

,

Init

, Name);

4125 if

(!Section.empty())

4126

GV->setSection(Section);

4133

llvm::GlobalVariable *

4134

CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType

Type

,

4135 bool

ForceNonFragileABI,

4136 bool

NullTerminate) {

4139 case

ObjCLabelType::ClassName:

Label

=

"OBJC_CLASS_NAME_"

;

break

;

4140 case

ObjCLabelType::MethodVarName:

Label

=

"OBJC_METH_VAR_NAME_"

;

break

;

4141 case

ObjCLabelType::MethodVarType:

Label

=

"OBJC_METH_VAR_TYPE_"

;

break

;

4142 case

ObjCLabelType::PropertyName:

Label

=

"OBJC_PROP_NAME_ATTR_"

;

break

;

4145 bool

NonFragile = ForceNonFragileABI || isNonFragileABI();

4149 case

ObjCLabelType::ClassName:

4150

Section = NonFragile ?

"__TEXT,__objc_classname,cstring_literals" 4151

:

"__TEXT,__cstring,cstring_literals"

;

4153 case

ObjCLabelType::MethodVarName:

4154

Section = NonFragile ?

"__TEXT,__objc_methname,cstring_literals" 4155

:

"__TEXT,__cstring,cstring_literals"

;

4157 case

ObjCLabelType::MethodVarType:

4158

Section = NonFragile ?

"__TEXT,__objc_methtype,cstring_literals" 4159

:

"__TEXT,__cstring,cstring_literals"

;

4161 case

ObjCLabelType::PropertyName:

4162

Section = NonFragile ?

"__TEXT,__objc_methname,cstring_literals" 4163

:

"__TEXT,__cstring,cstring_literals"

;

4167

llvm::Constant *

Value

=

4168

llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);

4169

llvm::GlobalVariable *GV =

4172

llvm::GlobalValue::PrivateLinkage,

Value

,

Label

);

4173 if

(CGM.

getTriple

().isOSBinFormatMachO())

4174

GV->setSection(Section);

4175

GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

4182

llvm::Function *CGObjCMac::ModuleInitFunction() {

4188

llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {

4189 return

ObjCTypes.getGetPropertyFn();

4192

llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {

4193 return

ObjCTypes.getSetPropertyFn();

4196

llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(

bool

atomic,

4198 return

ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);

4201

llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {

4202 return

ObjCTypes.getCopyStructFn();

4205

llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {

4206 return

ObjCTypes.getCopyStructFn();

4209

llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {

4210 return

ObjCTypes.getCppAtomicObjectFunction();

4213

llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {

4214 return

ObjCTypes.getCppAtomicObjectFunction();

4217

llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {

4218 return

ObjCTypes.getEnumerationMutationFn();

4222 return

EmitTryOrSynchronizedStmt(CGF, S);

4227 return

EmitTryOrSynchronizedStmt(CGF, S);

4236

ObjCTypesHelper &ObjCTypes;

4237

PerformFragileFinally(

const Stmt

*S,

4241

ObjCTypesHelper *ObjCTypes)

4242

: S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),

4243

ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}

4248

llvm::BasicBlock *FinallyCallExit =

4250

llvm::BasicBlock *FinallyNoCallExit =

4253

FinallyCallExit, FinallyNoCallExit);

4261 if

(isa<ObjCAtTryStmt>(S)) {

4263

cast<ObjCAtTryStmt>(S).getFinallyStmt()) {

4265 if

(flags.isForEHCleanup())

return

;

4269

llvm::Value *CurCleanupDest =

4272

CGF.

EmitStmt

(FinallyStmt->getFinallyBody());

4291 class

FragileHazards {

4294

llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;

4296

llvm::InlineAsm *ReadHazard;

4297

llvm::InlineAsm *WriteHazard;

4299

llvm::FunctionType *GetAsmFnType();

4301 void

collectLocals();

4307 void

emitWriteHazard();

4308 void

emitHazardsInNewBlocks();

4320 if

(Locals.empty())

return

;

4323 for

(llvm::Function::iterator

4324

I = CGF.

CurFn

->begin(),

E

= CGF.

CurFn

->end(); I !=

E

; ++I)

4325

BlocksBeforeTry.insert(&*I);

4327

llvm::FunctionType *AsmFnTy = GetAsmFnType();

4335

std::string Constraint;

4336 for

(

unsigned

I = 0,

E

= Locals.size(); I !=

E

; ++I) {

4337 if

(I) Constraint +=

','

;

4338

Constraint +=

"*m"

;

4341

ReadHazard = llvm::InlineAsm::get(AsmFnTy,

""

, Constraint,

true

,

false

);

4349

std::string Constraint;

4350 for

(

unsigned

I = 0,

E

= Locals.size(); I !=

E

; ++I) {

4351 if

(I) Constraint +=

','

;

4352

Constraint +=

"=*m"

;

4355

WriteHazard = llvm::InlineAsm::get(AsmFnTy,

""

, Constraint,

true

,

false

);

4360void

FragileHazards::emitWriteHazard() {

4361 if

(Locals.empty())

return

;

4364 for

(

auto

Pair : llvm::enumerate(Locals))

4365 Call

->addParamAttr(Pair.index(), llvm::Attribute::get(

4367

cast<llvm::AllocaInst>(Pair.value())->getAllocatedType()));

4370void

FragileHazards::emitReadHazard(

CGBuilderTy

&Builder) {

4371

assert(!Locals.empty());

4372

llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);

4373

call->setDoesNotThrow();

4375 for

(

auto

Pair : llvm::enumerate(Locals))

4376

call->addParamAttr(Pair.index(), llvm::Attribute::get(

4377

Builder.getContext(), llvm::Attribute::ElementType,

4378

cast<llvm::AllocaInst>(Pair.value())->getAllocatedType()));

4383void

FragileHazards::emitHazardsInNewBlocks() {

4384 if

(Locals.empty())

return

;

4389 for

(llvm::Function::iterator

4390

FI = CGF.

CurFn

->begin(), FE = CGF.

CurFn

->end(); FI != FE; ++FI) {

4391

llvm::BasicBlock &BB = *FI;

4392 if

(BlocksBeforeTry.count(&BB))

continue

;

4395 for

(llvm::BasicBlock::iterator

4396

BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {

4397

llvm::Instruction &I = *BI;

4401 if

(!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))

4403 if

(isa<llvm::IntrinsicInst>(I))

4408 if

(cast<llvm::CallBase>(I).doesNotThrow())

4416

Builder.SetInsertPoint(&BB, BI);

4417

emitReadHazard(Builder);

4424 if

(llvm::Value *Ptr =

V

.getBasePointer())

4428void

FragileHazards::collectLocals() {

4430

llvm::DenseSet<llvm::Value*> AllocasToIgnore;

4436

llvm::BasicBlock &Entry = CGF.

CurFn

->getEntryBlock();

4437 for

(llvm::BasicBlock::iterator

4438

I = Entry.begin(),

E

= Entry.end(); I !=

E

; ++I)

4439 if

(isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))

4440

Locals.push_back(&*I);

4443

llvm::FunctionType *FragileHazards::GetAsmFnType() {

4445 for

(

unsigned

i = 0, e = Locals.size(); i != e; ++i)

4446

tys[i] = Locals[i]->getType();

4447 return

llvm::FunctionType::get(CGF.

VoidTy

, tys,

false

);

4560 bool

isTry = isa<ObjCAtTryStmt>(S);

4564

CodeGenFunction::JumpDest FinallyEnd =

4569

CodeGenFunction::JumpDest FinallyRethrow =

4579

llvm::Value *SyncArg =

4580

CGF.

EmitScalarExpr

(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());

4581

SyncArg = CGF.

Builder

.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);

4593 "exceptiondata.ptr"

);

4599

FragileHazards Hazards(CGF);

4628

ExceptionData.emitRawPointer(CGF));

4631

llvm::Constant *

Zero

= llvm::ConstantInt::get(CGF.

Builder

.getInt32Ty(), 0);

4634

ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes,

4637

ObjCTypes.getSetJmpFn(), SetJmpBuffer,

"setjmp_result"

);

4638

SetJmpResult->setCanReturnTwice();

4644

llvm::Value *DidCatch =

4645

CGF.

Builder

.CreateIsNotNull(SetJmpResult,

"did_catch_exception"

);

4646

CGF.

Builder

.CreateCondBr(DidCatch, TryHandler, TryBlock);

4651

CGF.

EmitStmt

(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()

4652

: cast<ObjCAtSynchronizedStmt>(S).getSynchBody());

4654

CGBuilderTy::InsertPoint TryFallthroughIP = CGF.

Builder

.saveAndClearIP();

4660

Hazards.emitWriteHazard();

4664 if

(!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {

4674

ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),

4685

llvm::BasicBlock *CatchBlock =

nullptr

;

4686

llvm::BasicBlock *CatchHandler =

nullptr

;

4692 "propagating_exception"

);

4698

ExceptionData.emitRawPointer(CGF));

4700

llvm::CallInst *SetJmpResult =

4702

SetJmpBuffer,

"setjmp.result"

);

4703

SetJmpResult->setCanReturnTwice();

4705

llvm::Value *Threw =

4706

CGF.

Builder

.CreateIsNotNull(SetJmpResult,

"did_catch_exception"

);

4710

CGF.

Builder

.CreateCondBr(Threw, CatchHandler, CatchBlock);

4720 bool

AllMatched =

false

;

4722 const VarDecl

*CatchParam = CatchStmt->getCatchParamDecl();

4741

CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);

4745

assert(CGF.

HaveInsertPoint

() &&

"DeclStmt destroyed insert point?"

);

4748

EmitInitOfCatchParam(CGF, Caught, CatchParam);

4751

CGF.

EmitStmt

(CatchStmt->getCatchBody());

4754

CatchVarCleanups.ForceCleanup();

4760

assert(OPT &&

"Unexpected non-object pointer type in @catch"

);

4765

assert(IDecl &&

"Catch parameter must have Objective-C type!"

);

4768

llvm::Value *

Class

= EmitClassRef(CGF, IDecl);

4770

llvm::Value *matchArgs[] = {

Class

, Caught };

4771

llvm::CallInst *Match =

4773

matchArgs,

"match"

);

4778

CGF.

Builder

.CreateCondBr(CGF.

Builder

.CreateIsNotNull(Match,

"matched"

),

4779

MatchedBlock, NextCatchBlock);

4786

CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);

4789

assert(CGF.

HaveInsertPoint

() &&

"DeclStmt destroyed insert point?"

);

4793

CGF.

Builder

.CreateBitCast(Caught,

4795

EmitInitOfCatchParam(CGF, Tmp, CatchParam);

4797

CGF.

EmitStmt

(CatchStmt->getCatchBody());

4800

CatchVarCleanups.ForceCleanup();

4811 if

(Caught->use_empty())

4812

Caught->eraseFromParent();

4828

assert(PropagatingExnVar.

isValid

());

4830

ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),

4841

Hazards.emitHazardsInNewBlocks();

4844

CGF.

Builder

.restoreIP(TryFallthroughIP);

4848

CGF.

EmitBlock

(FinallyEnd.getBlock(),

true

);

4851

CGBuilderTy::InsertPoint SavedIP = CGF.

Builder

.saveAndClearIP();

4852

CGF.

EmitBlock

(FinallyRethrow.getBlock(),

true

);

4855

llvm::Value *PropagatingExn;

4856 if

(PropagatingExnVar.

isValid

()) {

4862

ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF));

4863

PropagatingExn = Caught;

4868

CGF.

Builder

.CreateUnreachable();

4871

CGF.

Builder

.restoreIP(SavedIP);

4876 bool

ClearInsertionPoint) {

4877

llvm::Value *ExceptionAsObject;

4879 if

(

const Expr

*ThrowExpr = S.getThrowExpr()) {

4882

CGF.

Builder

.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);

4885 "Unexpected rethrow outside @catch block."

);

4889

CGF.

EmitRuntimeCall

(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)

4890

->setDoesNotReturn();

4891

CGF.

Builder

.CreateUnreachable();

4894 if

(ClearInsertionPoint)

4895

CGF.

Builder

.ClearInsertionPoint();

4904

llvm::Value *AddrWeakObjVal = CGF.

Builder

.CreateBitCast(

4906

llvm::Value *read_weak =

4908

AddrWeakObjVal,

"weakread"

);

4909

read_weak = CGF.

Builder

.CreateBitCast(read_weak, DestTy);

4917

llvm::Value *src,

Address

dst) {

4918

llvm::Type * SrcTy = src->getType();

4919 if

(!isa<llvm::PointerType>(SrcTy)) {

4921

assert(Size <= 8 && "does not support size > 8

"); 4922 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4923 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4924 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4926 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4927 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), 4928 ObjCTypes.PtrObjectPtrTy); 4929 llvm::Value *args[] = { src, dstVal }; 4930 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 4931 args, "

weakassign

"); 4937

void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,

4938

llvm::Value *src, Address dst,

4940

llvm::Type * SrcTy = src->getType();

4941

if (!isa<llvm::PointerType>(SrcTy)) {

4942

unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);

4943

assert(Size <= 8 && "does

not

support size > 8

"); 4944 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4945 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4946 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4948 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4949 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), 4950 ObjCTypes.PtrObjectPtrTy); 4951 llvm::Value *args[] = {src, dstVal}; 4953 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 4954 args, "

globalassign

"); 4956 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 4957 args, "

threadlocalassign

"); 4963

void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,

4964

llvm::Value *src, Address dst,

4965

llvm::Value *ivarOffset) {

4966

assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is

NULL"); 4967 llvm::Type * SrcTy = src->getType(); 4968 if (!isa<llvm::PointerType>(SrcTy)) { 4969 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy); 4970 assert(Size <= 8 && "

does

not

support size > 8

"); 4971 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4972 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4973 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4975 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4976 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), 4977 ObjCTypes.PtrObjectPtrTy); 4978 llvm::Value *args[] = {src, dstVal, ivarOffset}; 4979 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 4985

void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,

4986

llvm::Value *src, Address dst) {

4987

llvm::Type * SrcTy = src->getType();

4988

if (!isa<llvm::PointerType>(SrcTy)) {

4989

unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);

4990

assert(Size <= 8 && "does

not

support size > 8

"); 4991 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4992 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4993 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4995 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4996 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), 4997 ObjCTypes.PtrObjectPtrTy); 4998 llvm::Value *args[] = {src, dstVal}; 4999 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 5000 args, "

strongassign

"); 5003void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 5004 Address DestPtr, Address SrcPtr, 5005 llvm::Value *size) { 5006 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF), 5007 SrcPtr.emitRawPointer(CGF), size}; 5008 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 5013

LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,

5015

llvm::Value *BaseValue,

5016

const ObjCIvarDecl *Ivar,

5017

unsigned CVRQualifiers) {

5018

const ObjCInterfaceDecl *ID =

5019

ObjectTy->castAs<ObjCObjectType>()->getInterface();

5020

return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,

5021

EmitIvarOffset(CGF, ID, Ivar));

5024

llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,

5025

const ObjCInterfaceDecl *Interface,

5026

const ObjCIvarDecl *Ivar) {

5027

uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);

5028

return llvm::ConstantInt::get(

5029

CGM.getTypes().ConvertType(CGM.getContext().LongTy),

5033

/* *** Private Interface *** */

5035

std::string CGObjCCommonMac::GetSectionName(StringRef Section,

5036

StringRef MachOAttributes) {

5037

switch (CGM.getTriple().getObjectFormat()) {

5038

case llvm::Triple::UnknownObjectFormat:

5039

llvm_unreachable("unexpected

object

file format

"); 5040 case llvm::Triple::MachO: { 5041 if (MachOAttributes.empty()) 5042 return ("

__DATA,

" + Section).str(); 5043 return ("

__DATA,

" + Section + "

,

" + MachOAttributes).str(); 5045 case llvm::Triple::ELF: 5046 assert(Section.starts_with("

__

") && "

expected the name to begin with __

"); 5047 return Section.substr(2).str(); 5048 case llvm::Triple::COFF: 5049 assert(Section.starts_with("

__

") && "

expected the name to begin with __

"); 5050 return ("

.

" + Section.substr(2) + "

$B

").str(); 5051 case llvm::Triple::Wasm: 5052 case llvm::Triple::GOFF: 5053 case llvm::Triple::SPIRV: 5054 case llvm::Triple::XCOFF: 5055 case llvm::Triple::DXContainer: 5056 llvm::report_fatal_error( 5057 "

Objective-

C

support is unimplemented

for object

file format

"); 5060 llvm_unreachable("

Unhandled llvm::Triple::ObjectFormatType

enum"); 5071

enum ImageInfoFlags {

5072

eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.

5073

eImageInfo_GarbageCollected = (1 << 1),

5074

eImageInfo_GCOnly = (1 << 2),

5075

eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.

5077

// A flag indicating that the module has no instances of a @synthesize of a

5078

// superclass variable. This flag used to be consumed by the runtime to work

5079

// around miscompile by gcc.

5080

eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.

5081

eImageInfo_ImageIsSimulated = (1 << 5),

5082

eImageInfo_ClassProperties = (1 << 6)

5085

void CGObjCCommonMac::EmitImageInfo() {

5086

unsigned version = 0; // Version is unused?

5087

std::string Section =

5089

? "__OBJC,__image_info,regular

" 5090 : GetSectionName("

__objc_imageinfo

", "

regular,no_dead_strip

"); 5092 // Generate module-level named metadata to convey this information to the 5093 // linker and code-gen. 5094 llvm::Module &Mod = CGM.getModule(); 5096 // Add the ObjC ABI version to the module flags. 5097 Mod.addModuleFlag(llvm::Module::Error, "

Objective-

C

Version

", ObjCABI); 5098 Mod.addModuleFlag(llvm::Module::Error, "

Objective-

C

Image Info Version

", 5100 Mod.addModuleFlag(llvm::Module::Error, "

Objective-

C

Image Info Section

", 5101 llvm::MDString::get(VMContext, Section)); 5103 auto Int8Ty = llvm::Type::getInt8Ty(VMContext); 5104 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) { 5105 // Non-GC overrides those files which specify GC. 5106 Mod.addModuleFlag(llvm::Module::Error, 5107 "

Objective-

C

Garbage Collection

", 5108 llvm::ConstantInt::get(Int8Ty,0)); 5110 // Add the ObjC garbage collection value. 5111 Mod.addModuleFlag(llvm::Module::Error, 5112 "

Objective-

C

Garbage Collection

", 5113 llvm::ConstantInt::get(Int8Ty, 5114 (uint8_t)eImageInfo_GarbageCollected)); 5116 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { 5117 // Add the ObjC GC Only value. 5118 Mod.addModuleFlag(llvm::Module::Error, "

Objective-

C

GC Only

", 5121 // Require that GC be specified and set to eImageInfo_GarbageCollected. 5122 llvm::Metadata *Ops[2] = { 5123 llvm::MDString::get(VMContext, "

Objective-

C

Garbage Collection

"), 5124 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( 5125 Int8Ty, eImageInfo_GarbageCollected))}; 5126 Mod.addModuleFlag(llvm::Module::Require, "

Objective-

C

GC Only

", 5127 llvm::MDNode::get(VMContext, Ops)); 5131 // Indicate whether we're compiling this to run on a simulator. 5132 if (CGM.getTarget().getTriple().isSimulatorEnvironment()) 5133 Mod.addModuleFlag(llvm::Module::Error, "

Objective-

C

Is Simulated

", 5134 eImageInfo_ImageIsSimulated); 5136 // Indicate whether we are generating class properties. 5137 Mod.addModuleFlag(llvm::Module::Error, "

Objective-

C

Class Properties

", 5138 eImageInfo_ClassProperties); 5141// struct objc_module { 5142// unsigned long version; 5143// unsigned long size; 5148// FIXME: Get from somewhere 5149static const int ModuleVersion = 7; 5151void CGObjCMac::EmitModuleInfo() { 5152 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy); 5154 ConstantInitBuilder builder(CGM); 5155 auto values = builder.beginStruct(ObjCTypes.ModuleTy); 5156 values.addInt(ObjCTypes.LongTy, ModuleVersion); 5157 values.addInt(ObjCTypes.LongTy, Size); 5158 // This used to be the filename, now it is unused. <rdr://4327263> 5159 values.add(GetClassName(StringRef(""))); 5160 values.add(EmitModuleSymbols()); 5161 CreateMetadataVar("

OBJC_MODULES

", values, 5162 "

__OBJC,__module_info,regular,no_dead_strip

", 5163 CGM.getPointerAlign(), true); 5166llvm::Constant *CGObjCMac::EmitModuleSymbols() { 5167 unsigned NumClasses = DefinedClasses.size(); 5168 unsigned NumCategories = DefinedCategories.size(); 5170 // Return null if no symbols were defined. 5171 if (!NumClasses && !NumCategories) 5172 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 5174 ConstantInitBuilder builder(CGM); 5175 auto values = builder.beginStruct(); 5176 values.addInt(ObjCTypes.LongTy, 0); 5177 values.addNullPointer(ObjCTypes.SelectorPtrTy); 5178 values.addInt(ObjCTypes.ShortTy, NumClasses); 5179 values.addInt(ObjCTypes.ShortTy, NumCategories); 5181 // The runtime expects exactly the list of defined classes followed 5182 // by the list of defined categories, in a single array. 5183 auto array = values.beginArray(ObjCTypes.Int8PtrTy); 5184 for (unsigned i=0; i<NumClasses; i++) { 5185 const ObjCInterfaceDecl *ID = ImplementedClasses[i]; 5187 if (ObjCImplementationDecl *IMP = ID->getImplementation()) 5188 // We are implementing a weak imported interface. Give it external linkage 5189 if (ID->isWeakImported() && !IMP->isWeakImported()) 5190 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 5192 array.add(DefinedClasses[i]); 5194 for (unsigned i=0; i<NumCategories; i++) 5195 array.add(DefinedCategories[i]); 5197 array.finishAndAddTo(values); 5199 llvm::GlobalVariable *GV = CreateMetadataVar( 5200 "

OBJC_SYMBOLS

", values, "

__OBJC,__symbols,regular,no_dead_strip

", 5201 CGM.getPointerAlign(), true); 5205llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF, 5206 IdentifierInfo *II) { 5207 LazySymbols.insert(II); 5209 llvm::GlobalVariable *&Entry = ClassReferences[II]; 5213 CreateMetadataVar("

OBJC_CLASS_REFERENCES_

", GetClassName(II->getName()), 5214 "

__OBJC,__cls_refs,literal_pointers,no_dead_strip

", 5215 CGM.getPointerAlign(), true); 5218 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, 5219 CGF.getPointerAlign()); 5222llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF, 5223 const ObjCInterfaceDecl *ID) { 5224 // If the class has the objc_runtime_visible attribute, we need to 5225 // use the Objective-C runtime to get the class. 5226 if (ID->hasAttr<ObjCRuntimeVisibleAttr>()) 5227 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes); 5229 IdentifierInfo *RuntimeName = 5230 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString()); 5231 return EmitClassRefFromId(CGF, RuntimeName); 5234llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) { 5235 IdentifierInfo *II = &CGM.getContext().Idents.get("

NSAutoreleasePool

"); 5236 return EmitClassRefFromId(CGF, II); 5239llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) { 5240 return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel)); 5243ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) { 5244 CharUnits Align = CGM.getPointerAlign(); 5246 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 5248 Entry = CreateMetadataVar( 5249 "

OBJC_SELECTOR_REFERENCES_

", GetMethodVarName(Sel), 5250 "

__OBJC,__message_refs,literal_pointers,no_dead_strip

", Align, true); 5251 Entry->setExternallyInitialized(true); 5254 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align); 5257llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) { 5258 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName]; 5260 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName); 5261 return getConstantGEP(VMContext, Entry, 0, 0); 5264llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) { 5265 return MethodDefinitions.lookup(MD); 5270

llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,

5271

const ObjCCommonTypesHelper &ObjCTypes) {

5272

return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);

5275

void IvarLayoutBuilder::visitRecord(const RecordType *RT,

5277

const RecordDecl *RD = RT->getDecl();

5279

// If this is a union, remember that we had one, because it might mess

5280

// up the ordering of layout entries.

5282

IsDisordered = true;

5284

const ASTRecordLayout *recLayout = nullptr;

5285

visitAggregate(RD->field_begin(), RD->field_end(), offset,

5286

[&](const FieldDecl *field) -> CharUnits {

5288

recLayout = &CGM.getContext().getASTRecordLayout(RD);

5289

auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());

5290

return CGM.getContext().toCharUnitsFromBits(offsetInBits);

5294

template <class Iterator, class GetOffsetFn>

5295

void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,

5296

CharUnits aggregateOffset,

5297

const GetOffsetFn &getOffset) {

5298

for (; begin != end; ++begin) {

5299

auto field = *begin;

5301

// Skip over bitfields.

5302

if (field->isBitField()) {

5306

// Compute the offset of the field within the aggregate.

5307

CharUnits fieldOffset = aggregateOffset + getOffset(field);

5309

visitField(field, fieldOffset);

5314

void IvarLayoutBuilder::visitField(const FieldDecl *field,

5315

CharUnits fieldOffset) {

5316

QualType fieldType = field->getType();

5318

// Drill down into arrays.

5319

uint64_t numElts = 1;

5320

if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {

5322

fieldType = arrayType->getElementType();

5324

// Unlike incomplete arrays, constant arrays can be nested.

5325

while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {

5326

numElts *= arrayType->getZExtSize();

5327

fieldType = arrayType->getElementType();

5330

assert(!fieldType->isArrayType() && "ivar of non-constant array

type

?

"); 5332 // If we ended up with a zero-sized array, we've done what we can do within 5333 // the limits of this layout encoding. 5334 if (numElts == 0) return; 5336 // Recurse if the base element type is a record type. 5337 if (auto recType = fieldType->getAs<RecordType>()) { 5338 size_t oldEnd = IvarsInfo.size(); 5340 visitRecord(recType, fieldOffset); 5342 // If we have an array, replicate the first entry's layout information. 5343 auto numEltEntries = IvarsInfo.size() - oldEnd; 5344 if (numElts != 1 && numEltEntries != 0) { 5345 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType); 5346 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) { 5347 // Copy the last numEltEntries onto the end of the array, adjusting 5348 // each for the element size. 5349 for (size_t i = 0; i != numEltEntries; ++i) { 5350 auto firstEntry = IvarsInfo[oldEnd + i]; 5351 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize, 5352 firstEntry.SizeInWords)); 5360 // Classify the element type. 5361 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType); 5363 // If it matches what we're looking for, add an entry. 5364 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) 5365 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { 5366 assert(CGM.getContext().getTypeSizeInChars(fieldType) 5367 == CGM.getPointerSize()); 5368 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts)); 5375

llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,

5376

llvm::SmallVectorImpl<unsigned char> &buffer) {

5377

// The bitmap is a series of skip/scan instructions, aligned to word

5378

// boundaries. The skip is performed first.

5379

const unsigned char MaxNibble = 0xF;

5380

const unsigned char SkipMask = 0xF0, SkipShift = 4;

5381

const unsigned char ScanMask = 0x0F, ScanShift = 0;

5383

assert(!IvarsInfo.empty() && "generating bitmap

for

no data

"); 5385 // Sort the ivar info on byte position in case we encounterred a 5386 // union nested in the ivar list. 5388 // This isn't a stable sort, but our algorithm should handle it fine. 5389 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end()); 5391 assert(llvm::is_sorted(IvarsInfo)); 5393 assert(IvarsInfo.back().Offset < InstanceEnd); 5395 assert(buffer.empty()); 5397 // Skip the next N words. 5398 auto skip = [&](unsigned numWords) { 5399 assert(numWords > 0); 5401 // Try to merge into the previous byte. Since scans happen second, we 5402 // can't do this if it includes a scan. 5403 if (!buffer.empty() && !(buffer.back() & ScanMask)) { 5404 unsigned lastSkip = buffer.back() >> SkipShift; 5405 if (lastSkip < MaxNibble) { 5406 unsigned claimed = std::min(MaxNibble - lastSkip, numWords); 5407 numWords -= claimed; 5408 lastSkip += claimed; 5409 buffer.back() = (lastSkip << SkipShift); 5413 while (numWords >= MaxNibble) { 5414 buffer.push_back(MaxNibble << SkipShift); 5415 numWords -= MaxNibble; 5418 buffer.push_back(numWords << SkipShift); 5422 // Scan the next N words. 5423 auto scan = [&](unsigned numWords) { 5424 assert(numWords > 0); 5426 // Try to merge into the previous byte. Since scans happen second, we can 5427 // do this even if it includes a skip. 5428 if (!buffer.empty()) { 5429 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift; 5430 if (lastScan < MaxNibble) { 5431 unsigned claimed = std::min(MaxNibble - lastScan, numWords); 5432 numWords -= claimed; 5433 lastScan += claimed; 5434 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift); 5438 while (numWords >= MaxNibble) { 5439 buffer.push_back(MaxNibble << ScanShift); 5440 numWords -= MaxNibble; 5443 buffer.push_back(numWords << ScanShift); 5447 // One past the end of the last scan. 5448 unsigned endOfLastScanInWords = 0; 5449 const CharUnits WordSize = CGM.getPointerSize(); 5451 // Consider all the scan requests. 5452 for (auto &request : IvarsInfo) { 5453 CharUnits beginOfScan = request.Offset - InstanceBegin; 5455 // Ignore scan requests that don't start at an even multiple of the 5456 // word size. We can't encode them. 5457 if ((beginOfScan % WordSize) != 0) continue; 5459 // Ignore scan requests that start before the instance start. 5460 // This assumes that scans never span that boundary. The boundary 5461 // isn't the true start of the ivars, because in the fragile-ARC case 5462 // it's rounded up to word alignment, but the test above should leave 5463 // us ignoring that possibility. 5464 if (beginOfScan.isNegative()) { 5465 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin); 5469 unsigned beginOfScanInWords = beginOfScan / WordSize; 5470 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords; 5472 // If the scan starts some number of words after the last one ended, 5474 if (beginOfScanInWords > endOfLastScanInWords) { 5475 skip(beginOfScanInWords - endOfLastScanInWords); 5477 // Otherwise, start scanning where the last left off. 5479 beginOfScanInWords = endOfLastScanInWords; 5481 // If that leaves us with nothing to scan, ignore this request. 5482 if (beginOfScanInWords >= endOfScanInWords) continue; 5485 // Scan to the end of the request. 5486 assert(beginOfScanInWords < endOfScanInWords); 5487 scan(endOfScanInWords - beginOfScanInWords); 5488 endOfLastScanInWords = endOfScanInWords; 5492 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy); 5494 // For GC layouts, emit a skip to the end of the allocation so that we 5495 // have precise information about the entire thing. This isn't useful 5496 // or necessary for the ARC-style layout strings. 5497 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 5498 unsigned lastOffsetInWords = 5499 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize; 5500 if (lastOffsetInWords > endOfLastScanInWords) { 5501 skip(lastOffsetInWords - endOfLastScanInWords); 5505 // Null terminate the string. 5506 buffer.push_back(0); 5508 auto *Entry = CGObjC.CreateCStringLiteral( 5509 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName); 5510 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0); 5530

CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,

5531

CharUnits beginOffset, CharUnits endOffset,

5532

bool ForStrongLayout, bool HasMRCWeakIvars) {

5533

// If this is MRC, and we're either building a strong layout or there

5534

// are no weak ivars, bail out early.

5535

llvm::Type *PtrTy = CGM.Int8PtrTy;

5536

if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&

5537

!CGM.getLangOpts().ObjCAutoRefCount &&

5538

(ForStrongLayout || !HasMRCWeakIvars))

5539

return llvm::Constant::getNullValue(PtrTy);

5541

const ObjCInterfaceDecl *OI = OMD->getClassInterface();

5542

SmallVector<const ObjCIvarDecl*, 32> ivars;

5544

// GC layout strings include the complete object layout, possibly

5545

// inaccurately in the non-fragile ABI; the runtime knows how to fix this

5548

// ARC layout strings only include the class's ivars. In non-fragile

5549

// runtimes, that means starting at InstanceStart, rounded up to word

5550

// alignment. In fragile runtimes, there's no InstanceStart, so it means

5551

// starting at the offset of the first ivar, rounded up to word alignment.

5553

// MRC weak layout strings follow the ARC style.

5554

CharUnits baseOffset;

5555

if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {

5556

for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();

5557

IVD; IVD = IVD->getNextIvar())

5558

ivars.push_back(IVD);

5560

if (isNonFragileABI()) {

5561

baseOffset = beginOffset; // InstanceStart

5562

} else if (!ivars.empty()) {

5564

CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));

5566

baseOffset = CharUnits::Zero();

5569

baseOffset = baseOffset.alignTo(CGM.getPointerAlign());

5572

CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);

5574

baseOffset = CharUnits::Zero();

5578

return llvm::Constant::getNullValue(PtrTy);

5580

IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);

5582

builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),

5583

[&](const ObjCIvarDecl *ivar) -> CharUnits {

5584

return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));

5587

if (!builder.hasBitmapData())

5588

return llvm::Constant::getNullValue(PtrTy);

5590

llvm::SmallVector<unsigned char, 4> buffer;

5591

llvm::Constant *C = builder.buildBitmap(*this, buffer);

5593

if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {

5594

printf("\n%

s

ivar layout

for class '%s'

:

", 5595 ForStrongLayout ? "

strong

" : "

weak

", 5596 OMD->getClassInterface()->getName().str().c_str()); 5597 builder.dump(buffer); 5602llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) { 5603 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 5604 // FIXME: Avoid std::string in "

Sel.

getAsString

()

" 5606 Entry = CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName); 5607 return getConstantGEP(VMContext, Entry, 0, 0); 5610// FIXME: Merge into a single cstring creation function. 5611llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) { 5612 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 5615llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) { 5616 std::string TypeStr; 5617 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 5619 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 5621 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType); 5622 return getConstantGEP(VMContext, Entry, 0, 0); 5625llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D, 5627 std::string TypeStr = 5628 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended); 5630 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 5632 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType); 5633 return getConstantGEP(VMContext, Entry, 0, 0); 5636// FIXME: Merge into a single cstring creation function. 5637llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) { 5638 llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 5640 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName); 5641 return getConstantGEP(VMContext, Entry, 0, 0); 5644// FIXME: Merge into a single cstring creation function. 5645// FIXME: This Decl should be more precise. 5647CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 5648 const Decl *Container) { 5649 std::string TypeStr = 5650 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container); 5651 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 5654void CGObjCMac::FinishModule() { 5657 // Emit the dummy bodies for any protocols which were referenced but 5659 for (auto &entry : Protocols) { 5660 llvm::GlobalVariable *global = entry.second; 5661 if (global->hasInitializer()) 5664 ConstantInitBuilder builder(CGM); 5665 auto values = builder.beginStruct(ObjCTypes.ProtocolTy); 5666 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy); 5667 values.add(GetClassName(entry.first->getName())); 5668 values.addNullPointer(ObjCTypes.ProtocolListPtrTy); 5669 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy); 5670 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy); 5671 values.finishAndSetAsInitializer(global); 5672 CGM.addCompilerUsedGlobal(global); 5675 // Add assembler directives to add lazy undefined symbol references 5676 // for classes which are referenced but not defined. This is 5677 // important for correct linker interaction. 5679 // FIXME: It would be nice if we had an LLVM construct for this. 5680 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) && 5681 CGM.getTriple().isOSBinFormatMachO()) { 5682 SmallString<256> Asm; 5683 Asm += CGM.getModule().getModuleInlineAsm(); 5684 if (!Asm.empty() && Asm.back() != '\n') 5687 llvm::raw_svector_ostream OS(Asm); 5688 for (const auto *Sym : DefinedSymbols) 5689 OS << "

\t.objc_class_name_

" << Sym->getName() << "

=0\n

" 5690 << "

\t.globl .objc_class_name_

" << Sym->getName() << "

\n

"; 5691 for (const auto *Sym : LazySymbols) 5692 OS << "

\t.lazy_reference .objc_class_name_

" << Sym->getName() << "

\n

"; 5693 for (const auto &Category : DefinedCategoryNames) 5694 OS << "

\t.objc_category_name_

" << Category << "

=0\n

" 5695 << "

\t.globl .objc_category_name_

" << Category << "

\n

"; 5697 CGM.getModule().setModuleInlineAsm(OS.str()); 5701CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) 5702 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr), 5703 ObjCEmptyVtableVar(nullptr) { 5709ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) 5710 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr) 5712 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 5713 ASTContext &Ctx = CGM.getContext(); 5714 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace(); 5716 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy)); 5718 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy)); 5719 Int8PtrTy = CGM.Int8PtrTy; 5720 Int8PtrProgramASTy = llvm::PointerType::get(CGM.Int8Ty, ProgramAS); 5721 Int8PtrPtrTy = CGM.Int8PtrPtrTy; 5723 // arm64 targets use "int" ivar offset variables. All others, 5724 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets. 5725 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64) 5726 IvarOffsetVarTy = IntTy; 5728 IvarOffsetVarTy = LongTy; 5731 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType())); 5733 llvm::PointerType::getUnqual(ObjectPtrTy); 5735 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType())); 5737 // I'm not sure I like this. The implicit coordination is a bit 5738 // gross. We should solve this in a reasonable fashion because this 5739 // is a pretty common task (match some runtime data structure with 5740 // an LLVM data structure). 5742 // FIXME: This is leaked. 5743 // FIXME: Merge with rewriter code? 5745 // struct _objc_super { 5749 RecordDecl *RD = RecordDecl::Create( 5750 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(), 5751 SourceLocation(), &Ctx.Idents.get("

_objc_super

")); 5752 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5753 nullptr, Ctx.getObjCIdType(), nullptr, nullptr, 5754 false, ICIS_NoInit)); 5755 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5756 nullptr, Ctx.getObjCClassType(), nullptr, 5757 nullptr, false, ICIS_NoInit)); 5758 RD->completeDefinition(); 5760 SuperCTy = Ctx.getTagDeclType(RD); 5761 SuperPtrCTy = Ctx.getPointerType(SuperCTy); 5763 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 5764 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 5768 // char *attributes; 5770 PropertyTy = llvm::StructType::create("struct

._prop_t

", Int8PtrTy, Int8PtrTy); 5772 // struct _prop_list_t { 5773 // uint32_t entsize; // sizeof(struct _prop_t) 5774 // uint32_t count_of_properties; 5775 // struct _prop_t prop_list[count_of_properties]; 5777 PropertyListTy = llvm::StructType::create( 5778 "struct

._prop_list_t

", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0)); 5779 // struct _prop_list_t * 5780 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 5782 // struct _objc_method { 5784 // char *method_type; 5787 MethodTy = llvm::StructType::create("struct

._objc_method

", SelectorPtrTy, 5788 Int8PtrTy, Int8PtrProgramASTy); 5790 // struct _objc_cache * 5791 CacheTy = llvm::StructType::create(VMContext, "struct

._objc_cache

"); 5792 CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 5795ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 5796 : ObjCCommonTypesHelper(cgm) { 5797 // struct _objc_method_description { 5801 MethodDescriptionTy = llvm::StructType::create( 5802 "struct

._objc_method_description

", SelectorPtrTy, Int8PtrTy); 5804 // struct _objc_method_description_list { 5806 // struct _objc_method_description[1]; 5808 MethodDescriptionListTy = 5809 llvm::StructType::create("struct

._objc_method_description_list

", IntTy, 5810 llvm::ArrayType::get(MethodDescriptionTy, 0)); 5812 // struct _objc_method_description_list * 5813 MethodDescriptionListPtrTy = 5814 llvm::PointerType::getUnqual(MethodDescriptionListTy); 5816 // Protocol description structures 5818 // struct _objc_protocol_extension { 5819 // uint32_t size; // sizeof(struct _objc_protocol_extension) 5820 // struct _objc_method_description_list *optional_instance_methods; 5821 // struct _objc_method_description_list *optional_class_methods; 5822 // struct _objc_property_list *instance_properties; 5823 // const char ** extendedMethodTypes; 5824 // struct _objc_property_list *class_properties; 5826 ProtocolExtensionTy = llvm::StructType::create( 5827 "struct

._objc_protocol_extension

", IntTy, MethodDescriptionListPtrTy, 5828 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy, 5831 // struct _objc_protocol_extension * 5832 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 5834 // Handle construction of Protocol and ProtocolList types 5836 // struct _objc_protocol { 5837 // struct _objc_protocol_extension *isa; 5838 // char *protocol_name; 5839 // struct _objc_protocol **_objc_protocol_list; 5840 // struct _objc_method_description_list *instance_methods; 5841 // struct _objc_method_description_list *class_methods; 5843 ProtocolTy = llvm::StructType::create( 5844 {ProtocolExtensionPtrTy, Int8PtrTy, 5845 llvm::PointerType::getUnqual(VMContext), MethodDescriptionListPtrTy, 5846 MethodDescriptionListPtrTy}, 5847 "struct

._objc_protocol

"); 5850 llvm::StructType::create({llvm::PointerType::getUnqual(VMContext), LongTy, 5851 llvm::ArrayType::get(ProtocolTy, 0)}, 5852 "struct

._objc_protocol_list

"); 5854 // struct _objc_protocol_list * 5855 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 5857 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 5859 // Class description structures 5861 // struct _objc_ivar { 5866 IvarTy = llvm::StructType::create("struct

._objc_ivar

", Int8PtrTy, Int8PtrTy, 5869 // struct _objc_ivar_list * 5871 llvm::StructType::create(VMContext, "struct

._objc_ivar_list

"); 5872 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 5874 // struct _objc_method_list * 5876 llvm::StructType::create(VMContext, "struct

._objc_method_list

"); 5877 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 5879 // struct _objc_class_extension * 5880 ClassExtensionTy = llvm::StructType::create( 5881 "struct

._objc_class_extension

", IntTy, Int8PtrTy, PropertyListPtrTy); 5882 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 5884 // struct _objc_class { 5886 // Class super_class; 5890 // long instance_size; 5891 // struct _objc_ivar_list *ivars; 5892 // struct _objc_method_list *methods; 5893 // struct _objc_cache *cache; 5894 // struct _objc_protocol_list *protocols; 5895 // char *ivar_layout; 5896 // struct _objc_class_ext *ext; 5898 ClassTy = llvm::StructType::create( 5899 {llvm::PointerType::getUnqual(VMContext), 5900 llvm::PointerType::getUnqual(VMContext), Int8PtrTy, LongTy, LongTy, 5901 LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy, 5902 Int8PtrTy, ClassExtensionPtrTy}, 5903 "struct

._objc_class

"); 5905 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 5907 // struct _objc_category { 5908 // char *category_name; 5909 // char *class_name; 5910 // struct _objc_method_list *instance_method; 5911 // struct _objc_method_list *class_method; 5912 // struct _objc_protocol_list *protocols; 5913 // uint32_t size; // sizeof(struct _objc_category) 5914 // struct _objc_property_list *instance_properties;// category's @property 5915 // struct _objc_property_list *class_properties; 5917 CategoryTy = llvm::StructType::create( 5918 "struct

._objc_category

", Int8PtrTy, Int8PtrTy, MethodListPtrTy, 5919 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy, 5922 // Global metadata structures 5924 // struct _objc_symtab { 5925 // long sel_ref_cnt; 5927 // short cls_def_cnt; 5928 // short cat_def_cnt; 5929 // char *defs[cls_def_cnt + cat_def_cnt]; 5931 SymtabTy = llvm::StructType::create("struct

._objc_symtab

", LongTy, 5932 SelectorPtrTy, ShortTy, ShortTy, 5933 llvm::ArrayType::get(Int8PtrTy, 0)); 5934 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 5936 // struct _objc_module { 5938 // long size; // sizeof(struct _objc_module) 5940 // struct _objc_symtab* symtab; 5942 ModuleTy = llvm::StructType::create("struct

._objc_module

", LongTy, LongTy, 5943 Int8PtrTy, SymtabPtrTy); 5945 // FIXME: This is the size of the setjmp buffer and should be target 5946 // specific. 18 is what's used on 32-bit X86. 5947 uint64_t SetJmpBufferSize = 18; 5950 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4); 5952 ExceptionDataTy = llvm::StructType::create( 5953 "struct

._objc_exception_data

", 5954 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy); 5957ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 5958 : ObjCCommonTypesHelper(cgm) { 5959 // struct _method_list_t { 5960 // uint32_t entsize; // sizeof(struct _objc_method) 5961 // uint32_t method_count; 5962 // struct _objc_method method_list[method_count]; 5965 llvm::StructType::create("struct

.__method_list_t

", IntTy, IntTy, 5966 llvm::ArrayType::get(MethodTy, 0)); 5967 // struct method_list_t * 5968 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 5970 // struct _protocol_t { 5972 // const char * const protocol_name; 5973 // const struct _protocol_list_t * protocol_list; // super protocols 5974 // const struct method_list_t * const instance_methods; 5975 // const struct method_list_t * const class_methods; 5976 // const struct method_list_t *optionalInstanceMethods; 5977 // const struct method_list_t *optionalClassMethods; 5978 // const struct _prop_list_t * properties; 5979 // const uint32_t size; // sizeof(struct _protocol_t) 5980 // const uint32_t flags; // = 0 5981 // const char ** extendedMethodTypes; 5982 // const char *demangledName; 5983 // const struct _prop_list_t * class_properties; 5986 ProtocolnfABITy = llvm::StructType::create( 5987 "struct

._protocol_t

", ObjectPtrTy, Int8PtrTy, 5988 llvm::PointerType::getUnqual(VMContext), MethodListnfABIPtrTy, 5989 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy, 5990 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy, 5993 // struct _protocol_t* 5994 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy); 5996 // struct _protocol_list_t { 5997 // long protocol_count; // Note, this is 32/64 bit 5998 // struct _protocol_t *[protocol_count]; 6000 ProtocolListnfABITy = llvm::StructType::create( 6001 {LongTy, llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)}, 6002 "struct

._objc_protocol_list

"); 6004 // struct _objc_protocol_list* 6005 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 6008 // unsigned [long] int *offset; // pointer to ivar offset location 6011 // uint32_t alignment; 6014 IvarnfABITy = llvm::StructType::create( 6015 "struct

._ivar_t

", llvm::PointerType::getUnqual(IvarOffsetVarTy), 6016 Int8PtrTy, Int8PtrTy, IntTy, IntTy); 6018 // struct _ivar_list_t { 6019 // uint32 entsize; // sizeof(struct _ivar_t) 6021 // struct _iver_t list[count]; 6024 llvm::StructType::create("struct

._ivar_list_t

", IntTy, IntTy, 6025 llvm::ArrayType::get(IvarnfABITy, 0)); 6027 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 6029 // struct _class_ro_t { 6030 // uint32_t const flags; 6031 // uint32_t const instanceStart; 6032 // uint32_t const instanceSize; 6033 // uint32_t const reserved; // only when building for 64bit targets 6034 // const uint8_t * const ivarLayout; 6035 // const char *const name; 6036 // const struct _method_list_t * const baseMethods; 6037 // const struct _objc_protocol_list *const baseProtocols; 6038 // const struct _ivar_list_t *const ivars; 6039 // const uint8_t * const weakIvarLayout; 6040 // const struct _prop_list_t * const properties; 6043 // FIXME. Add 'reserved' field in 64bit abi mode! 6044 ClassRonfABITy = llvm::StructType::create( 6045 "struct

._class_ro_t

", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy, 6046 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy, 6047 Int8PtrTy, PropertyListPtrTy); 6049 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 6050 ImpnfABITy = CGM.UnqualPtrTy; 6052 // struct _class_t { 6053 // struct _class_t *isa; 6054 // struct _class_t * const superclass; 6057 // struct class_ro_t *ro; 6060 ClassnfABITy = llvm::StructType::create( 6061 {llvm::PointerType::getUnqual(VMContext), 6062 llvm::PointerType::getUnqual(VMContext), CachePtrTy, 6063 llvm::PointerType::getUnqual(ImpnfABITy), 6064 llvm::PointerType::getUnqual(ClassRonfABITy)}, 6065 "struct

._class_t

"); 6067 // LLVM for struct _class_t * 6068 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 6070 // struct _category_t { 6071 // const char * const name; 6072 // struct _class_t *const cls; 6073 // const struct _method_list_t * const instance_methods; 6074 // const struct _method_list_t * const class_methods; 6075 // const struct _protocol_list_t * const protocols; 6076 // const struct _prop_list_t * const properties; 6077 // const struct _prop_list_t * const class_properties; 6078 // const uint32_t size; 6080 CategorynfABITy = llvm::StructType::create( 6081 "struct

._category_t

", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy, 6082 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy, 6083 PropertyListPtrTy, IntTy); 6085 // New types for nonfragile abi messaging. 6086 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 6087 ASTContext &Ctx = CGM.getContext(); 6089 // MessageRefTy - LLVM for: 6090 // struct _message_ref_t { 6095 // First the clang type for struct _message_ref_t 6096 RecordDecl *RD = RecordDecl::Create( 6097 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(), 6098 SourceLocation(), &Ctx.Idents.get("

_message_ref_t

")); 6099 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 6100 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false, 6102 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 6103 nullptr, Ctx.getObjCSelType(), nullptr, nullptr, 6104 false, ICIS_NoInit)); 6105 RD->completeDefinition(); 6107 MessageRefCTy = Ctx.getTagDeclType(RD); 6108 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy); 6109 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy)); 6111 // MessageRefPtrTy - LLVM for struct _message_ref_t* 6112 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy); 6114 // SuperMessageRefTy - LLVM for: 6115 // struct _super_message_ref_t { 6116 // SUPER_IMP messenger; 6119 SuperMessageRefTy = llvm::StructType::create("struct

._super_message_ref_t

", 6120 ImpnfABITy, SelectorPtrTy); 6122 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 6123 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); 6126 // struct objc_typeinfo { 6127 // const void** vtable; // objc_ehtype_vtable + 2 6128 // const char* name; // c++ typeinfo string 6131 EHTypeTy = llvm::StructType::create("struct

._objc_typeinfo

", 6132 llvm::PointerType::getUnqual(Int8PtrTy), 6133 Int8PtrTy, ClassnfABIPtrTy); 6134 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy); 6137llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 6138 FinishNonFragileABIModule(); 6143void CGObjCNonFragileABIMac::AddModuleClassList( 6144 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName, 6145 StringRef SectionName) { 6146 unsigned NumClasses = Container.size(); 6151 SmallVector<llvm::Constant*, 8> Symbols(NumClasses); 6152 for (unsigned i=0; i<NumClasses; i++) 6153 Symbols[i] = Container[i]; 6155 llvm::Constant *Init = 6156 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 6160 // Section name is obtained by calling GetSectionName, which returns 6161 // sections in the __DATA segment on MachO. 6162 assert((!CGM.getTriple().isOSBinFormatMachO() || 6163 SectionName.starts_with("

__DATA

")) && 6164 "

SectionName expected to start with __DATA on MachO

"); 6165 llvm::GlobalVariable *GV = new llvm::GlobalVariable( 6166 CGM.getModule(), Init->getType(), false, 6167 llvm::GlobalValue::PrivateLinkage, Init, SymbolName); 6168 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Init->getType())); 6169 GV->setSection(SectionName); 6170 CGM.addCompilerUsedGlobal(GV); 6173void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 6174 // nonfragile abi has no module definition. 6176 // Build list of all implemented class addresses in array 6177 // L_OBJC_LABEL_CLASS_$. 6179 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) { 6180 const ObjCInterfaceDecl *ID = ImplementedClasses[i]; 6182 if (ObjCImplementationDecl *IMP = ID->getImplementation()) 6183 // We are implementing a weak imported interface. Give it external linkage 6184 if (ID->isWeakImported() && !IMP->isWeakImported()) { 6185 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 6186 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 6190 AddModuleClassList(DefinedClasses, "

OBJC_LABEL_CLASS_$

", 6191 GetSectionName("

__objc_classlist

", 6192 "

regular,no_dead_strip

")); 6194 AddModuleClassList(DefinedNonLazyClasses, "

OBJC_LABEL_NONLAZY_CLASS_$

", 6195 GetSectionName("

__objc_nlclslist

", 6196 "

regular,no_dead_strip

")); 6198 // Build list of all implemented category addresses in array 6199 // L_OBJC_LABEL_CATEGORY_$. 6200 AddModuleClassList(DefinedCategories, "

OBJC_LABEL_CATEGORY_$

", 6201 GetSectionName("

__objc_catlist

", 6202 "

regular,no_dead_strip

")); 6203 AddModuleClassList(DefinedStubCategories, "

OBJC_LABEL_STUB_CATEGORY_$

", 6204 GetSectionName("

__objc_catlist2

", 6205 "

regular,no_dead_strip

")); 6206 AddModuleClassList(DefinedNonLazyCategories, "

OBJC_LABEL_NONLAZY_CATEGORY_$

", 6207 GetSectionName("

__objc_nlcatlist

", 6208 "

regular,no_dead_strip

")); 6217

bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {

6218

// At various points we've experimented with using vtable-based

6219

// dispatch for all methods.

6220

switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {

6221

case CodeGenOptions::Legacy:

6223

case CodeGenOptions::NonLegacy:

6225

case CodeGenOptions::Mixed:

6229

// If so, see whether this selector is in the white-list of things which must

6230

// use the new dispatch convention. We lazily build a dense set for this.

6231

if (VTableDispatchMethods.empty()) {

6232

VTableDispatchMethods.insert(GetNullarySelector("alloc

")); 6233 VTableDispatchMethods.insert(GetNullarySelector("class")); 6234 VTableDispatchMethods.insert(GetNullarySelector("

self

")); 6235 VTableDispatchMethods.insert(GetNullarySelector("

isFlipped

")); 6236 VTableDispatchMethods.insert(GetNullarySelector("length")); 6237 VTableDispatchMethods.insert(GetNullarySelector("

count

")); 6239 // These are vtable-based if GC is disabled. 6240 // Optimistically use vtable dispatch for hybrid compiles. 6241 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) { 6242 VTableDispatchMethods.insert(GetNullarySelector("

retain

")); 6243 VTableDispatchMethods.insert(GetNullarySelector("

release

")); 6244 VTableDispatchMethods.insert(GetNullarySelector("

autorelease

")); 6247 VTableDispatchMethods.insert(GetUnarySelector("

allocWithZone

")); 6248 VTableDispatchMethods.insert(GetUnarySelector("

isKindOfClass

")); 6249 VTableDispatchMethods.insert(GetUnarySelector("

respondsToSelector

")); 6250 VTableDispatchMethods.insert(GetUnarySelector("

objectForKey

")); 6251 VTableDispatchMethods.insert(GetUnarySelector("

objectAtIndex

")); 6252 VTableDispatchMethods.insert(GetUnarySelector("

isEqualToString

")); 6253 VTableDispatchMethods.insert(GetUnarySelector("

isEqual

")); 6255 // These are vtable-based if GC is enabled. 6256 // Optimistically use vtable dispatch for hybrid compiles. 6257 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 6258 VTableDispatchMethods.insert(GetNullarySelector("

hash

")); 6259 VTableDispatchMethods.insert(GetUnarySelector("

addObject

")); 6261 // "

countByEnumeratingWithState:objects:count

" 6262 const IdentifierInfo *KeyIdents[] = { 6263 &CGM.getContext().Idents.get("

countByEnumeratingWithState

"), 6264 &CGM.getContext().Idents.get("

objects

"), 6265 &CGM.getContext().Idents.get("

count

")}; 6266 VTableDispatchMethods.insert( 6267 CGM.getContext().Selectors.getSelector(3, KeyIdents)); 6271 return VTableDispatchMethods.count(Sel); 6289

llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(

6291

unsigned InstanceStart,

6292

unsigned InstanceSize,

6293

const ObjCImplementationDecl *ID) {

6294

std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());

6296

CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);

6297

CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);

6299

bool hasMRCWeak = false;

6300

if (CGM.getLangOpts().ObjCAutoRefCount)

6301

flags |= NonFragileABI_Class_CompiledByARC;

6302

else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))

6303

flags |= NonFragileABI_Class_HasMRCWeakIvars;

6305

ConstantInitBuilder builder(CGM);

6306

auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);

6308

values.addInt(ObjCTypes.IntTy, flags);

6309

values.addInt(ObjCTypes.IntTy, InstanceStart);

6310

values.addInt(ObjCTypes.IntTy, InstanceSize);

6311

values.add((flags & NonFragileABI_Class_Meta)

6312

? GetIvarLayoutName(nullptr, ObjCTypes)

6313

: BuildStrongIvarLayout(ID, beginInstance, endInstance));

6314

values.add(GetClassName(ID->getObjCRuntimeNameAsString()));

6316

// const struct _method_list_t * const baseMethods;

6317

SmallVector<const ObjCMethodDecl*, 16> methods;

6318

if (flags & NonFragileABI_Class_Meta) {

6319

for (const auto *MD : ID->class_methods())

6320

if (!MD->isDirectMethod())

6321

methods.push_back(MD);

6323

for (const auto *MD : ID->instance_methods())

6324

if (!MD->isDirectMethod())

6325

methods.push_back(MD);

6328

values.add(emitMethodList(ID->getObjCRuntimeNameAsString(),

6329

(flags & NonFragileABI_Class_Meta)

6330

? MethodListType::ClassMethods

6331

: MethodListType::InstanceMethods,

6334

const ObjCInterfaceDecl *OID = ID->getClassInterface();

6335

assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer

"); 6336 values.add(EmitProtocolList("

_OBJC_CLASS_PROTOCOLS_$_

" 6337 + OID->getObjCRuntimeNameAsString(), 6338 OID->all_referenced_protocol_begin(), 6339 OID->all_referenced_protocol_end())); 6341 if (flags & NonFragileABI_Class_Meta) { 6342 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy); 6343 values.add(GetIvarLayoutName(nullptr, ObjCTypes)); 6344 values.add(EmitPropertyList( 6345 "

_OBJC_$_CLASS_PROP_LIST_

" + ID->getObjCRuntimeNameAsString(), 6346 ID, ID->getClassInterface(), ObjCTypes, true)); 6348 values.add(EmitIvarList(ID)); 6349 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak)); 6350 values.add(EmitPropertyList( 6351 "

_OBJC_$_PROP_LIST_

" + ID->getObjCRuntimeNameAsString(), 6352 ID, ID->getClassInterface(), ObjCTypes, false)); 6355 llvm::SmallString<64> roLabel; 6356 llvm::raw_svector_ostream(roLabel) 6357 << ((flags & NonFragileABI_Class_Meta) ? "

_OBJC_METACLASS_RO_$_

" 6358 : "

_OBJC_CLASS_RO_$_

") 6361 return finishAndCreateGlobal(values, roLabel, CGM); 6374

llvm::GlobalVariable *

6375

CGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,

6377

llvm::Constant *IsAGV,

6378

llvm::Constant *SuperClassGV,

6379

llvm::Constant *ClassRoGV,

6380

bool HiddenVisibility) {

6381

ConstantInitBuilder builder(CGM);

6382

auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);

6385

values.add(SuperClassGV);

6387

values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);

6389

values.add(ObjCEmptyCacheVar);

6390

values.add(ObjCEmptyVtableVar);

6391

values.add(ClassRoGV);

6393

llvm::GlobalVariable *GV =

6394

cast<llvm::GlobalVariable>(GetClassGlobal(CI, isMetaclass, ForDefinition));

6395

values.finishAndSetAsInitializer(GV);

6397

if (CGM.getTriple().isOSBinFormatMachO())

6398

GV->setSection("__DATA, __objc_data

"); 6399 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(ObjCTypes.ClassnfABITy)); 6400 if (!CGM.getTriple().isOSBinFormatCOFF()) 6401 if (HiddenVisibility) 6402 GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 6406bool CGObjCNonFragileABIMac::ImplementationIsNonLazy( 6407 const ObjCImplDecl *OD) const { 6408 return OD->getClassMethod(GetNullarySelector("

load

")) != nullptr || 6409 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() || 6410 OD->hasAttr<ObjCNonLazyClassAttr>(); 6413void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, 6414 uint32_t &InstanceStart, 6415 uint32_t &InstanceSize) { 6416 const ASTRecordLayout &RL = 6417 CGM.getContext().getASTObjCImplementationLayout(OID); 6419 // InstanceSize is really instance end. 6420 InstanceSize = RL.getDataSize().getQuantity(); 6422 // If there are no fields, the start is the same as the end. 6423 if (!RL.getFieldCount()) 6424 InstanceStart = InstanceSize; 6426 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth(); 6429static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM, 6431 IdentifierInfo &II = CGM.getContext().Idents.get(Name); 6432 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); 6433 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); 6435 const VarDecl *VD = nullptr; 6436 for (const auto *Result : DC->lookup(&II)) 6437 if ((VD = dyn_cast<VarDecl>(Result))) 6441 return llvm::GlobalValue::DLLImportStorageClass; 6442 if (VD->hasAttr<DLLExportAttr>()) 6443 return llvm::GlobalValue::DLLExportStorageClass; 6444 if (VD->hasAttr<DLLImportAttr>()) 6445 return llvm::GlobalValue::DLLImportStorageClass; 6446 return llvm::GlobalValue::DefaultStorageClass; 6449void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 6450 if (!ObjCEmptyCacheVar) { 6452 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false, 6453 llvm::GlobalValue::ExternalLinkage, nullptr, 6454 "

_objc_empty_cache

"); 6455 if (CGM.getTriple().isOSBinFormatCOFF()) 6456 ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "

_objc_empty_cache

")); 6458 // Only OS X with deployment version <10.9 use the empty vtable symbol 6459 const llvm::Triple &Triple = CGM.getTarget().getTriple(); 6460 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9)) 6461 ObjCEmptyVtableVar = 6462 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false, 6463 llvm::GlobalValue::ExternalLinkage, nullptr, 6464 "

_objc_empty_vtable

"); 6466 ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(CGM.UnqualPtrTy); 6469 // FIXME: Is this correct (that meta class size is never computed)? 6470 uint32_t InstanceStart = 6471 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy); 6472 uint32_t InstanceSize = InstanceStart; 6473 uint32_t flags = NonFragileABI_Class_Meta; 6475 llvm::Constant *SuperClassGV, *IsAGV; 6477 const auto *CI = ID->getClassInterface(); 6478 assert(CI && "

CGObjCNonFragileABIMac::GenerateClass -

class

is 0

"); 6480 // Build the flags for the metaclass. 6481 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF()) 6482 ? !CI->hasAttr<DLLExportAttr>() 6483 : CI->getVisibility() == HiddenVisibility; 6485 flags |= NonFragileABI_Class_Hidden; 6487 // FIXME: why is this flag set on the metaclass? 6488 // ObjC metaclasses have no fields and don't really get constructed. 6489 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) { 6490 flags |= NonFragileABI_Class_HasCXXStructors; 6491 if (!ID->hasNonZeroConstructors()) 6492 flags |= NonFragileABI_Class_HasCXXDestructorOnly; 6495 if (!CI->getSuperClass()) { 6497 flags |= NonFragileABI_Class_Root; 6499 SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition); 6500 IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition); 6502 // Has a root. Current class is not a root. 6503 const ObjCInterfaceDecl *Root = ID->getClassInterface(); 6504 while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 6507 const auto *Super = CI->getSuperClass(); 6508 IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition); 6509 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition); 6512 llvm::GlobalVariable *CLASS_RO_GV = 6513 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID); 6515 llvm::GlobalVariable *MetaTClass = 6516 BuildClassObject(CI, /*metaclass*/ true, 6517 IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden); 6518 CGM.setGVProperties(MetaTClass, CI); 6519 DefinedMetaClasses.push_back(MetaTClass); 6521 // Metadata for the class 6524 flags |= NonFragileABI_Class_Hidden; 6526 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) { 6527 flags |= NonFragileABI_Class_HasCXXStructors; 6529 // Set a flag to enable a runtime optimization when a class has 6530 // fields that require destruction but which don't require 6531 // anything except zero-initialization during construction. This 6532 // is most notably true of __strong and __weak types, but you can 6533 // also imagine there being C++ types with non-trivial default 6534 // constructors that merely set all fields to null. 6535 if (!ID->hasNonZeroConstructors()) 6536 flags |= NonFragileABI_Class_HasCXXDestructorOnly; 6539 if (hasObjCExceptionAttribute(CGM.getContext(), CI)) 6540 flags |= NonFragileABI_Class_Exception; 6542 if (!CI->getSuperClass()) { 6543 flags |= NonFragileABI_Class_Root; 6544 SuperClassGV = nullptr; 6546 // Has a root. Current class is not a root. 6547 const auto *Super = CI->getSuperClass(); 6548 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition); 6551 GetClassSizeInfo(ID, InstanceStart, InstanceSize); 6553 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID); 6555 llvm::GlobalVariable *ClassMD = 6556 BuildClassObject(CI, /*metaclass*/ false, 6557 MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden); 6558 CGM.setGVProperties(ClassMD, CI); 6559 DefinedClasses.push_back(ClassMD); 6560 ImplementedClasses.push_back(CI); 6562 // Determine if this class is also "

non-lazy

". 6563 if (ImplementationIsNonLazy(ID)) 6564 DefinedNonLazyClasses.push_back(ClassMD); 6566 // Force the definition of the EHType if necessary. 6567 if (flags & NonFragileABI_Class_Exception) 6568 (void) GetInterfaceEHType(CI, ForDefinition); 6569 // Make sure method definition entries are all clear for next implementation. 6570 MethodDefinitions.clear(); 6581

llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,

6582

const ObjCProtocolDecl *PD) {

6584

// This routine is called for @protocol only. So, we must build definition

6585

// of protocol's meta-data (not a reference to it!)

6586

assert(!PD->isNonRuntimeProtocol() &&

6587

"attempting to get a protocol ref to a

static

protocol.

"); 6588 llvm::Constant *Init = GetOrEmitProtocol(PD); 6590 std::string ProtocolName("

_OBJC_PROTOCOL_REFERENCE_$_

"); 6591 ProtocolName += PD->getObjCRuntimeNameAsString(); 6593 CharUnits Align = CGF.getPointerAlign(); 6595 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName); 6597 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align); 6598 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 6599 llvm::GlobalValue::WeakAnyLinkage, Init, 6601 PTGV->setSection(GetSectionName("

__objc_protorefs

", 6602 "

coalesced,no_dead_strip

")); 6603 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 6604 PTGV->setAlignment(Align.getAsAlign()); 6605 if (!CGM.getTriple().isOSBinFormatMachO()) 6606 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName)); 6607 CGM.addUsedGlobal(PTGV); 6608 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align); 6623

void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {

6624

const ObjCInterfaceDecl *Interface = OCD->getClassInterface();

6625

const char *Prefix = "_OBJC_$_CATEGORY_

"; 6627 llvm::SmallString<64> ExtCatName(Prefix); 6628 ExtCatName += Interface->getObjCRuntimeNameAsString(); 6629 ExtCatName += "

_$_

"; 6630 ExtCatName += OCD->getNameAsString(); 6632 ConstantInitBuilder builder(CGM); 6633 auto values = builder.beginStruct(ObjCTypes.CategorynfABITy); 6634 values.add(GetClassName(OCD->getIdentifier()->getName())); 6635 // meta-class entry symbol 6636 values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition)); 6637 std::string listName = 6638 (Interface->getObjCRuntimeNameAsString() + "

_$_

" + OCD->getName()).str(); 6640 SmallVector<const ObjCMethodDecl *, 16> instanceMethods; 6641 SmallVector<const ObjCMethodDecl *, 8> classMethods; 6642 for (const auto *MD : OCD->methods()) { 6643 if (MD->isDirectMethod()) 6645 if (MD->isInstanceMethod()) { 6646 instanceMethods.push_back(MD); 6648 classMethods.push_back(MD); 6652 auto instanceMethodList = emitMethodList( 6653 listName, MethodListType::CategoryInstanceMethods, instanceMethods); 6654 auto classMethodList = emitMethodList( 6655 listName, MethodListType::CategoryClassMethods, classMethods); 6656 values.add(instanceMethodList); 6657 values.add(classMethodList); 6658 // Keep track of whether we have actual metadata to emit. 6659 bool isEmptyCategory = 6660 instanceMethodList->isNullValue() && classMethodList->isNullValue(); 6662 const ObjCCategoryDecl *Category = 6663 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 6665 SmallString<256> ExtName; 6666 llvm::raw_svector_ostream(ExtName) 6667 << Interface->getObjCRuntimeNameAsString() << "

_$_

" << OCD->getName(); 6669 EmitProtocolList("

_OBJC_CATEGORY_PROTOCOLS_$_

" + 6670 Interface->getObjCRuntimeNameAsString() + "

_$_

" + 6671 Category->getName(), 6672 Category->protocol_begin(), Category->protocol_end()); 6673 auto propertyList = EmitPropertyList("

_OBJC_$_PROP_LIST_

" + ExtName.str(), 6674 OCD, Category, ObjCTypes, false); 6675 auto classPropertyList = 6676 EmitPropertyList("

_OBJC_$_CLASS_PROP_LIST_

" + ExtName.str(), OCD, 6677 Category, ObjCTypes, true); 6678 values.add(protocolList); 6679 values.add(propertyList); 6680 values.add(classPropertyList); 6681 isEmptyCategory &= protocolList->isNullValue() && 6682 propertyList->isNullValue() && 6683 classPropertyList->isNullValue(); 6685 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy); 6686 values.addNullPointer(ObjCTypes.PropertyListPtrTy); 6687 values.addNullPointer(ObjCTypes.PropertyListPtrTy); 6690 if (isEmptyCategory) { 6691 // Empty category, don't emit any metadata. 6693 MethodDefinitions.clear(); 6698 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy); 6699 values.addInt(ObjCTypes.IntTy, Size); 6701 llvm::GlobalVariable *GCATV = 6702 finishAndCreateGlobal(values, ExtCatName.str(), CGM); 6703 CGM.addCompilerUsedGlobal(GCATV); 6704 if (Interface->hasAttr<ObjCClassStubAttr>()) 6705 DefinedStubCategories.push_back(GCATV); 6707 DefinedCategories.push_back(GCATV); 6709 // Determine if this category is also "

non-lazy

". 6710 if (ImplementationIsNonLazy(OCD)) 6711 DefinedNonLazyCategories.push_back(GCATV); 6712 // method definition entries must be clear for next implementation. 6713 MethodDefinitions.clear(); 6725

void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,

6726

const ObjCMethodDecl *MD,

6728

auto method = builder.beginStruct(ObjCTypes.MethodTy);

6729

method.add(GetMethodVarName(MD->getSelector()));

6730

method.add(GetMethodVarType(MD));

6733

// Protocol methods have no implementation. So, this entry is always NULL.

6734

method.addNullPointer(ObjCTypes.Int8PtrProgramASTy);

6736

llvm::Function *fn = GetMethodDefinition(MD);

6737

assert(fn && "no definition

for

method?

"); 6741 method.finishAndAddTo(builder); 6753

CGObjCNonFragileABIMac::emitMethodList(Twine name, MethodListType kind,

6754

ArrayRef<const ObjCMethodDecl *> methods) {

6755

// Return null for empty list.

6756

if (methods.empty())

6757

return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);

6762

case MethodListType::CategoryInstanceMethods:

6763

prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_

"; 6764 forProtocol = false; 6766 case MethodListType::CategoryClassMethods: 6767 prefix = "

_OBJC_$_CATEGORY_CLASS_METHODS_

"; 6768 forProtocol = false; 6770 case MethodListType::InstanceMethods: 6771 prefix = "

_OBJC_$_INSTANCE_METHODS_

"; 6772 forProtocol = false; 6774 case MethodListType::ClassMethods: 6775 prefix = "

_OBJC_$_CLASS_METHODS_

"; 6776 forProtocol = false; 6779 case MethodListType::ProtocolInstanceMethods: 6780 prefix = "

_OBJC_$_PROTOCOL_INSTANCE_METHODS_

"; 6783 case MethodListType::ProtocolClassMethods: 6784 prefix = "

_OBJC_$_PROTOCOL_CLASS_METHODS_

"; 6787 case MethodListType::OptionalProtocolInstanceMethods: 6788 prefix = "

_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_

"; 6791 case MethodListType::OptionalProtocolClassMethods: 6792 prefix = "

_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_

"; 6797 ConstantInitBuilder builder(CGM); 6798 auto values = builder.beginStruct(); 6800 // sizeof(struct _objc_method) 6801 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy); 6802 values.addInt(ObjCTypes.IntTy, Size); 6804 values.addInt(ObjCTypes.IntTy, methods.size()); 6805 auto methodArray = values.beginArray(ObjCTypes.MethodTy); 6806 for (auto MD : methods) 6807 emitMethodConstant(methodArray, MD, forProtocol); 6808 methodArray.finishAndAddTo(values); 6810 llvm::GlobalVariable *GV = finishAndCreateGlobal(values, prefix + name, CGM); 6811 CGM.addCompilerUsedGlobal(GV); 6817

llvm::GlobalVariable *

6818

CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,

6819

const ObjCIvarDecl *Ivar) {

6820

const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();

6821

llvm::SmallString<64> Name("OBJC_IVAR_$_

"); 6822 Name += Container->getObjCRuntimeNameAsString(); 6824 Name += Ivar->getName(); 6825 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name); 6826 if (!IvarOffsetGV) { 6828 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.IvarOffsetVarTy, 6829 false, llvm::GlobalValue::ExternalLinkage, 6830 nullptr, Name.str()); 6831 if (CGM.getTriple().isOSBinFormatCOFF()) { 6832 bool IsPrivateOrPackage = 6833 Ivar->getAccessControl() == ObjCIvarDecl::Private || 6834 Ivar->getAccessControl() == ObjCIvarDecl::Package; 6836 const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface(); 6838 if (ContainingID->hasAttr<DLLImportAttr>()) 6840 ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); 6841 else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage) 6843 ->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); 6846 return IvarOffsetGV; 6850CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, 6851 const ObjCIvarDecl *Ivar, 6852 unsigned long int Offset) { 6853 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar); 6854 IvarOffsetGV->setInitializer( 6855 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset)); 6856 IvarOffsetGV->setAlignment( 6857 CGM.getDataLayout().getABITypeAlign(ObjCTypes.IvarOffsetVarTy)); 6859 if (!CGM.getTriple().isOSBinFormatCOFF()) { 6860 // FIXME: This matches gcc, but shouldn't the visibility be set on the use 6861 // as well (i.e., in ObjCIvarOffsetVariable). 6862 if (Ivar->getAccessControl() == ObjCIvarDecl::Private || 6863 Ivar->getAccessControl() == ObjCIvarDecl::Package || 6864 ID->getVisibility() == HiddenVisibility) 6865 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 6867 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); 6870 // If ID's layout is known, then make the global constant. This serves as a 6871 // useful assertion: we'll never use this variable to calculate ivar offsets, 6872 // so if the runtime tries to patch it then we should crash. 6873 if (isClassLayoutKnownStatically(ID)) 6874 IvarOffsetGV->setConstant(true); 6876 if (CGM.getTriple().isOSBinFormatMachO()) 6877 IvarOffsetGV->setSection("

__DATA, __objc_ivar

"); 6878 return IvarOffsetGV; 6898

llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(

6899

const ObjCImplementationDecl *ID) {

6901

ConstantInitBuilder builder(CGM);

6902

auto ivarList = builder.beginStruct();

6903

ivarList.addInt(ObjCTypes.IntTy,

6904

CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));

6905

auto ivarCountSlot = ivarList.addPlaceholder();

6906

auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);

6908

const ObjCInterfaceDecl *OID = ID->getClassInterface();

6909

assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface

"); 6911 // FIXME. Consolidate this with similar code in GenerateClass. 6913 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); 6914 IVD; IVD = IVD->getNextIvar()) { 6915 // Ignore unnamed bit-fields. 6916 if (!IVD->getDeclName()) 6919 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy); 6920 ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD, 6921 ComputeIvarBaseOffset(CGM, ID, IVD))); 6922 ivar.add(GetMethodVarName(IVD->getIdentifier())); 6923 ivar.add(GetMethodVarType(IVD)); 6924 llvm::Type *FieldTy = 6925 CGM.getTypes().ConvertTypeForMem(IVD->getType()); 6926 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy); 6927 unsigned Align = CGM.getContext().getPreferredTypeAlign( 6928 IVD->getType().getTypePtr()) >> 3; 6929 Align = llvm::Log2_32(Align); 6930 ivar.addInt(ObjCTypes.IntTy, Align); 6931 // NOTE. Size of a bitfield does not match gcc's, because of the 6932 // way bitfields are treated special in each. But I am told that 6933 // 'size' for bitfield ivars is ignored by the runtime so it does 6934 // not matter. If it matters, there is enough info to get the 6936 ivar.addInt(ObjCTypes.IntTy, Size); 6937 ivar.finishAndAddTo(ivars); 6939 // Return null for empty list. 6940 if (ivars.empty()) { 6943 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 6946 auto ivarCount = ivars.size(); 6947 ivars.finishAndAddTo(ivarList); 6948 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount); 6950 const char *Prefix = "

_OBJC_$_INSTANCE_VARIABLES_

"; 6951 llvm::GlobalVariable *GV = finishAndCreateGlobal( 6952 ivarList, Prefix + OID->getObjCRuntimeNameAsString(), CGM); 6953 CGM.addCompilerUsedGlobal(GV); 6957llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef( 6958 const ObjCProtocolDecl *PD) { 6959 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 6961 assert(!PD->isNonRuntimeProtocol() && 6962 "

attempting to GetOrEmit a non-runtime protocol

"); 6964 // We use the initializer as a marker of whether this is a forward 6965 // reference or not. At module finalization we add the empty 6966 // contents for protocols which were referenced but never defined. 6967 llvm::SmallString<64> Protocol; 6968 llvm::raw_svector_ostream(Protocol) << "

_OBJC_PROTOCOL_$_

" 6969 << PD->getObjCRuntimeNameAsString(); 6971 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, 6972 false, llvm::GlobalValue::ExternalLinkage, 6974 if (!CGM.getTriple().isOSBinFormatMachO()) 6975 Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol)); 7001

llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(

7002

const ObjCProtocolDecl *PD) {

7003

llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];

7005

// Early exit if a defining object has already been generated.

7006

if (Entry && Entry->hasInitializer())

7009

// Use the protocol definition, if there is one.

7010

assert(PD->hasDefinition() &&

7011

"emitting protocol metadata without definition

"); 7012 PD = PD->getDefinition(); 7014 auto methodLists = ProtocolMethodLists::get(PD); 7016 ConstantInitBuilder builder(CGM); 7017 auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy); 7020 values.addNullPointer(ObjCTypes.ObjectPtrTy); 7021 values.add(GetClassName(PD->getObjCRuntimeNameAsString())); 7022 values.add(EmitProtocolList("

_OBJC_$_PROTOCOL_REFS_

" 7023 + PD->getObjCRuntimeNameAsString(), 7024 PD->protocol_begin(), 7025 PD->protocol_end())); 7026 values.add(methodLists.emitMethodList(this, PD, 7027 ProtocolMethodLists::RequiredInstanceMethods)); 7028 values.add(methodLists.emitMethodList(this, PD, 7029 ProtocolMethodLists::RequiredClassMethods)); 7030 values.add(methodLists.emitMethodList(this, PD, 7031 ProtocolMethodLists::OptionalInstanceMethods)); 7032 values.add(methodLists.emitMethodList(this, PD, 7033 ProtocolMethodLists::OptionalClassMethods)); 7034 values.add(EmitPropertyList( 7035 "

_OBJC_$_PROP_LIST_

" + PD->getObjCRuntimeNameAsString(), 7036 nullptr, PD, ObjCTypes, false)); 7038 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy); 7039 values.addInt(ObjCTypes.IntTy, Size); 7040 values.addInt(ObjCTypes.IntTy, 0); 7041 values.add(EmitProtocolMethodTypes("

_OBJC_$_PROTOCOL_METHOD_TYPES_

" 7042 + PD->getObjCRuntimeNameAsString(), 7043 methodLists.emitExtendedTypesArray(this), 7046 // const char *demangledName; 7047 values.addNullPointer(ObjCTypes.Int8PtrTy); 7049 values.add(EmitPropertyList( 7050 "

_OBJC_$_CLASS_PROP_LIST_

" + PD->getObjCRuntimeNameAsString(), 7051 nullptr, PD, ObjCTypes, true)); 7054 // Already created, fix the linkage and update the initializer. 7055 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage); 7056 values.finishAndSetAsInitializer(Entry); 7058 llvm::SmallString<64> symbolName; 7059 llvm::raw_svector_ostream(symbolName) 7060 << "

_OBJC_PROTOCOL_$_

" << PD->getObjCRuntimeNameAsString(); 7062 Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(), 7064 llvm::GlobalValue::WeakAnyLinkage); 7065 if (!CGM.getTriple().isOSBinFormatMachO()) 7066 Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName)); 7068 Protocols[PD->getIdentifier()] = Entry; 7070 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 7071 CGM.addUsedGlobal(Entry); 7073 // Use this protocol meta-data to build protocol list table in section 7074 // __DATA, __objc_protolist 7075 llvm::SmallString<64> ProtocolRef; 7076 llvm::raw_svector_ostream(ProtocolRef) << "

_OBJC_LABEL_PROTOCOL_$_

" 7077 << PD->getObjCRuntimeNameAsString(); 7079 llvm::GlobalVariable *PTGV = 7080 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, 7081 false, llvm::GlobalValue::WeakAnyLinkage, Entry, 7083 if (!CGM.getTriple().isOSBinFormatMachO()) 7084 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef)); 7086 CGM.getDataLayout().getABITypeAlign(ObjCTypes.ProtocolnfABIPtrTy)); 7087 PTGV->setSection(GetSectionName("

__objc_protolist

", 7088 "

coalesced,no_dead_strip

")); 7089 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 7090 CGM.addUsedGlobal(PTGV); 7103

CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,

7104

ObjCProtocolDecl::protocol_iterator begin,

7105

ObjCProtocolDecl::protocol_iterator end) {

7106

// Just return null for empty protocol lists

7107

auto Protocols = GetRuntimeProtocolList(begin, end);

7108

if (Protocols.empty())

7109

return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);

7111

SmallVector<llvm::Constant *, 16> ProtocolRefs;

7112

ProtocolRefs.reserve(Protocols.size());

7114

for (const auto *PD : Protocols)

7115

ProtocolRefs.push_back(GetProtocolRef(PD));

7117

// If all of the protocols in the protocol list are objc_non_runtime_protocol

7119

if (ProtocolRefs.size() == 0)

7120

return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);

7122

// FIXME: We shouldn't need to do this lookup here, should we?

7123

SmallString<256> TmpName;

7124

Name.toVector(TmpName);

7125

llvm::GlobalVariable *GV =

7126

CGM.getModule().getGlobalVariable(TmpName.str(), true);

7130

ConstantInitBuilder builder(CGM);

7131

auto values = builder.beginStruct();

7132

auto countSlot = values.addPlaceholder();

7134

// A null-terminated array of protocols.

7135

auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);

7136

for (auto const &proto : ProtocolRefs)

7138

auto count = array.size();

7139

array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);

7141

array.finishAndAddTo(values);

7142

values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);

7144

GV = finishAndCreateGlobal(values, Name, CGM);

7145

CGM.addCompilerUsedGlobal(GV);

7155

LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(

7156

CodeGen::CodeGenFunction &CGF,

7158

llvm::Value *BaseValue,

7159

const ObjCIvarDecl *Ivar,

7160

unsigned CVRQualifiers) {

7161

ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();

7162

llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);

7163

return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,

7168

CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,

7169

const ObjCInterfaceDecl *Interface,

7170

const ObjCIvarDecl *Ivar) {

7171

llvm::Value *IvarOffsetValue;

7172

if (isClassLayoutKnownStatically(Interface)) {

7173

IvarOffsetValue = llvm::ConstantInt::get(

7174

ObjCTypes.IvarOffsetVarTy,

7175

ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));

7177

llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);

7179

CGF.Builder.CreateAlignedLoad(GV->getValueType(), GV,

7180

CGF.getSizeAlign(), "ivar

"); 7181 if (IsIvarOffsetKnownIdempotent(CGF, Ivar)) 7182 cast<llvm::LoadInst>(IvarOffsetValue) 7183 ->setMetadata(llvm::LLVMContext::MD_invariant_load, 7184 llvm::MDNode::get(VMContext, {})); 7187 // This could be 32bit int or 64bit integer depending on the architecture. 7188 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value 7189 // as this is what caller always expects. 7190 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy) 7191 IvarOffsetValue = CGF.Builder.CreateIntCast( 7192 IvarOffsetValue, ObjCTypes.LongTy, true, "

ivar.conv

"); 7193 return IvarOffsetValue; 7196static void appendSelectorForMessageRefTable(std::string &buffer, 7197 Selector selector) { 7198 if (selector.isUnarySelector()) { 7199 buffer += selector.getNameForSlot(0); 7203 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) { 7204 buffer += selector.getNameForSlot(i); 7220

CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,

7221

ReturnValueSlot returnSlot,

7222

QualType resultType,

7227

const CallArgList &formalArgs,

7228

const ObjCMethodDecl *method) {

7229

// Compute the actual arguments.

7232

// First argument: the receiver / super-call structure.

7234

arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);

7235

args.add(RValue::get(arg0), arg0Type);

7237

// Second argument: a pointer to the message ref structure. Leave

7238

// the actual argument value blank for now.

7239

args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);

7241

args.insert(args.end(), formalArgs.begin(), formalArgs.end());

7243

MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);

7245

NullReturnState nullReturn;

7247

// Find the function to call and the mangled name for the message

7248

// ref structure. Using a different mangled name wouldn't actually

7249

// be a problem; it would just be a waste.

7251

// The runtime currently never uses vtable dispatch for anything

7252

// except normal, non-super message-sends.

7253

// FIXME: don't use this for that.

7254

llvm::FunctionCallee fn = nullptr;

7255

std::string messageRefName("_

"); 7256 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) { 7258 fn = ObjCTypes.getMessageSendSuper2StretFixupFn(); 7259 messageRefName += "

objc_msgSendSuper2_stret_fixup

"; 7261 nullReturn.init(CGF, arg0); 7262 fn = ObjCTypes.getMessageSendStretFixupFn(); 7263 messageRefName += "

objc_msgSend_stret_fixup

"; 7265 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) { 7266 fn = ObjCTypes.getMessageSendFpretFixupFn(); 7267 messageRefName += "

objc_msgSend_fpret_fixup

"; 7270 fn = ObjCTypes.getMessageSendSuper2FixupFn(); 7271 messageRefName += "

objc_msgSendSuper2_fixup

"; 7273 fn = ObjCTypes.getMessageSendFixupFn(); 7274 messageRefName += "

objc_msgSend_fixup

"; 7277 assert(fn && "

CGObjCNonFragileABIMac::EmitMessageSend

"); 7278 messageRefName += '_'; 7280 // Append the selector name, except use underscores anywhere we 7281 // would have used colons. 7282 appendSelectorForMessageRefTable(messageRefName, selector); 7284 llvm::GlobalVariable *messageRef 7285 = CGM.getModule().getGlobalVariable(messageRefName); 7287 // Build the message ref structure. 7288 ConstantInitBuilder builder(CGM); 7289 auto values = builder.beginStruct(); 7290 values.add(cast<llvm::Constant>(fn.getCallee())); 7291 values.add(GetMethodVarName(selector)); 7292 messageRef = values.finishAndCreateGlobal(messageRefName, 7293 CharUnits::fromQuantity(16), 7295 llvm::GlobalValue::WeakAnyLinkage); 7296 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility); 7297 messageRef->setSection(GetSectionName("

__objc_msgrefs

", "

coalesced

")); 7300 bool requiresnullCheck = false; 7301 if (CGM.getLangOpts().ObjCAutoRefCount && method) 7302 for (const auto *ParamDecl : method->parameters()) { 7303 if (ParamDecl->isDestroyedInCallee()) { 7304 if (!nullReturn.NullBB) 7305 nullReturn.init(CGF, arg0); 7306 requiresnullCheck = true; 7312 Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy), 7313 ObjCTypes.MessageRefTy, CGF.getPointerAlign()); 7315 // Update the message ref argument. 7316 args[1].setRValue(RValue::get(mref, CGF)); 7318 // Load the function to call from the message ref table. 7319 Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0); 7320 llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "

msgSend_fn

"); 7322 calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType); 7323 CGCallee callee(CGCalleeInfo(), calleePtr); 7325 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args); 7326 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs, 7327 requiresnullCheck ? method : nullptr); 7332

CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,

7333

ReturnValueSlot Return,

7334

QualType ResultType,

7336

llvm::Value *Receiver,

7337

const CallArgList &CallArgs,

7338

const ObjCInterfaceDecl *Class,

7339

const ObjCMethodDecl *Method) {

7340

return isVTableDispatchedSelector(Sel)

7341

? EmitVTableMessageSend(CGF, Return, ResultType, Sel,

7342

Receiver, CGF.getContext().getObjCIdType(),

7343

false, CallArgs, Method)

7344

: EmitMessageSend(CGF, Return, ResultType, Sel,

7345

Receiver, CGF.getContext().getObjCIdType(),

7346

false, CallArgs, Method, Class, ObjCTypes);

7350

CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,

7352

ForDefinition_t isForDefinition) {

7354

(metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());

7355

return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),

7357

ID->isWeakImported(),

7359

&& CGM.getTriple().isOSBinFormatCOFF()

7360

&& ID->hasAttr<DLLImportAttr>());

7364

CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,

7365

ForDefinition_t IsForDefinition,

7366

bool Weak, bool DLLImport) {

7367

llvm::GlobalValue::LinkageTypes L =

7368

Weak ? llvm::GlobalValue::ExternalWeakLinkage

7369

: llvm::GlobalValue::ExternalLinkage;

7371

llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);

7372

if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {

7373

auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,

7377

NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);

7380

GV->replaceAllUsesWith(NewGV);

7381

GV->eraseFromParent();

7384

CGM.getModule().insertGlobalVariable(GV);

7387

assert(GV->getLinkage() == L);

7392

CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {

7393

llvm::Constant *ClassGV = GetClassGlobal(ID, /*metaclass*/ false,

7396

if (!ID->hasAttr<ObjCClassStubAttr>())

7399

ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);

7401

// Stub classes are pointer-aligned. Classrefs pointing at stub classes

7402

// must set the least significant bit set to 1.

7403

auto *Idx = llvm::ConstantInt::get(CGM.Int32Ty, 1);

7404

return llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, ClassGV, Idx);

7408

CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,

7409

const ObjCInterfaceDecl *ID,

7410

llvm::GlobalVariable *Entry) {

7411

if (ID && ID->hasAttr<ObjCClassStubAttr>()) {

7412

// Classrefs pointing at Objective-C stub classes must be loaded by calling

7413

// a special runtime function.

7414

return CGF.EmitRuntimeCall(

7415

ObjCTypes.getLoadClassrefFn(), Entry, "load_classref_result

"); 7418 CharUnits Align = CGF.getPointerAlign(); 7419 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, Align); 7423CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF, 7425 const ObjCInterfaceDecl *ID) { 7426 llvm::GlobalVariable *&Entry = ClassReferences[II]; 7429 llvm::Constant *ClassGV; 7431 ClassGV = GetClassGlobalForClassRef(ID); 7433 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(), 7435 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy && 7436 "

classref was emitted with the wrong

type

?

"); 7439 std::string SectionName = 7440 GetSectionName("

__objc_classrefs

", "

regular,no_dead_strip

"); 7441 Entry = new llvm::GlobalVariable( 7442 CGM.getModule(), ClassGV->getType(), false, 7443 getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV, 7444 "

OBJC_CLASSLIST_REFERENCES_$_

"); 7445 Entry->setAlignment(CGF.getPointerAlign().getAsAlign()); 7446 if (!ID || !ID->hasAttr<ObjCClassStubAttr>()) 7447 Entry->setSection(SectionName); 7449 CGM.addCompilerUsedGlobal(Entry); 7452 return EmitLoadOfClassRef(CGF, ID, Entry); 7455llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF, 7456 const ObjCInterfaceDecl *ID) { 7457 // If the class has the objc_runtime_visible attribute, we need to 7458 // use the Objective-C runtime to get the class. 7459 if (ID->hasAttr<ObjCRuntimeVisibleAttr>()) 7460 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes); 7462 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID); 7465llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef( 7466 CodeGenFunction &CGF) { 7467 IdentifierInfo *II = &CGM.getContext().Idents.get("

NSAutoreleasePool

"); 7468 return EmitClassRefFromId(CGF, II, nullptr); 7472CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF, 7473 const ObjCInterfaceDecl *ID) { 7474 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()]; 7477 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID); 7478 std::string SectionName = 7479 GetSectionName("

__objc_superrefs

", "

regular,no_dead_strip

"); 7480 Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false, 7481 llvm::GlobalValue::PrivateLinkage, ClassGV, 7482 "

OBJC_CLASSLIST_SUP_REFS_$_

"); 7483 Entry->setAlignment(CGF.getPointerAlign().getAsAlign()); 7484 Entry->setSection(SectionName); 7485 CGM.addCompilerUsedGlobal(Entry); 7488 return EmitLoadOfClassRef(CGF, ID, Entry); 7494

llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,

7495

const ObjCInterfaceDecl *ID,

7497

CharUnits Align = CGF.getPointerAlign();

7498

llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];

7500

auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);

7501

std::string SectionName =

7502

GetSectionName("__objc_superrefs

", "

regular,no_dead_strip

"); 7503 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, 7504 false, llvm::GlobalValue::PrivateLinkage, 7505 MetaClassGV, "

OBJC_CLASSLIST_SUP_REFS_$_

"); 7506 Entry->setAlignment(Align.getAsAlign()); 7507 Entry->setSection(SectionName); 7508 CGM.addCompilerUsedGlobal(Entry); 7511 return CGF.Builder.CreateAlignedLoad(ObjCTypes.ClassnfABIPtrTy, Entry, Align); 7516

llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,

7517

const ObjCInterfaceDecl *ID) {

7518

if (ID->isWeakImported()) {

7519

auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);

7521

assert(!isa<llvm::GlobalVariable>(ClassGV) ||

7522

cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());

7525

return EmitClassRef(CGF, ID);

7532

CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,

7533

ReturnValueSlot Return,

7534

QualType ResultType,

7536

const ObjCInterfaceDecl *Class,

7537

bool isCategoryImpl,

7538

llvm::Value *Receiver,

7539

bool IsClassMessage,

7540

const CodeGen::CallArgList &CallArgs,

7541

const ObjCMethodDecl *Method) {

7543

// Create and init a super structure; this is a (receiver, class)

7544

// pair we will pass to objc_msgSendSuper.

7545

RawAddress ObjCSuper = CGF.CreateTempAlloca(

7546

ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super

"); 7548 llvm::Value *ReceiverAsObject = 7549 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 7550 CGF.Builder.CreateStore(ReceiverAsObject, 7551 CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 7553 // If this is a class message the metaclass is passed as the target. 7554 llvm::Value *Target; 7556 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported()); 7558 Target = EmitSuperClassRef(CGF, Class); 7560 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 7562 llvm::Type *ClassTy = 7563 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 7564 Target = CGF.Builder.CreateBitCast(Target, ClassTy); 7565 CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 7567 return (isVTableDispatchedSelector(Sel)) 7568 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, 7569 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy, 7570 true, CallArgs, Method) 7571 : EmitMessageSend(CGF, Return, ResultType, Sel, 7572 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy, 7573 true, CallArgs, Method, Class, ObjCTypes); 7576llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF, 7578 Address Addr = EmitSelectorAddr(Sel); 7580 llvm::LoadInst* LI = CGF.Builder.CreateLoad(Addr); 7581 LI->setMetadata(llvm::LLVMContext::MD_invariant_load, 7582 llvm::MDNode::get(VMContext, {})); 7586ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) { 7587 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 7588 CharUnits Align = CGM.getPointerAlign(); 7590 std::string SectionName = 7591 GetSectionName("

__objc_selrefs

", "

literal_pointers,no_dead_strip

"); 7592 Entry = new llvm::GlobalVariable( 7593 CGM.getModule(), ObjCTypes.SelectorPtrTy, false, 7594 getLinkageTypeForObjCMetadata(CGM, SectionName), GetMethodVarName(Sel), 7595 "

OBJC_SELECTOR_REFERENCES_

"); 7596 Entry->setExternallyInitialized(true); 7597 Entry->setSection(SectionName); 7598 Entry->setAlignment(Align.getAsAlign()); 7599 CGM.addCompilerUsedGlobal(Entry); 7602 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align); 7608

void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,

7611

llvm::Value *ivarOffset) {

7612

llvm::Type * SrcTy = src->getType();

7613

if (!isa<llvm::PointerType>(SrcTy)) {

7614

unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);

7615

assert(Size <= 8 && "does

not

support size > 8

"); 7616 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7617 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7618 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7620 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7621 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), 7622 ObjCTypes.PtrObjectPtrTy); 7623 llvm::Value *args[] = {src, dstVal, ivarOffset}; 7624 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 7630

void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(

7631

CodeGen::CodeGenFunction &CGF,

7632

llvm::Value *src, Address dst) {

7633

llvm::Type * SrcTy = src->getType();

7634

if (!isa<llvm::PointerType>(SrcTy)) {

7635

unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);

7636

assert(Size <= 8 && "does

not

support size > 8

"); 7637 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7638 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7639 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7641 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7642 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), 7643 ObjCTypes.PtrObjectPtrTy); 7644 llvm::Value *args[] = {src, dstVal}; 7645 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 7646 args, "

weakassign

"); 7649void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( 7650 CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, 7651 llvm::Value *Size) { 7652 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF), 7653 SrcPtr.emitRawPointer(CGF), Size}; 7654 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 7660

llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(

7661

CodeGen::CodeGenFunction &CGF,

7662

Address AddrWeakObj) {

7663

llvm::Type *DestTy = AddrWeakObj.getElementType();

7664

llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(

7665

AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);

7666

llvm::Value *read_weak =

7667

CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),

7668

AddrWeakObjVal, "weakread

"); 7669 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 7676

void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,

7677

llvm::Value *src, Address dst) {

7678

llvm::Type * SrcTy = src->getType();

7679

if (!isa<llvm::PointerType>(SrcTy)) {

7680

unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);

7681

assert(Size <= 8 && "does

not

support size > 8

"); 7682 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7683 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7684 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7686 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7687 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), 7688 ObjCTypes.PtrObjectPtrTy); 7689 llvm::Value *args[] = {src, dstVal}; 7690 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 7691 args, "

weakassign

"); 7697

void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,

7698

llvm::Value *src, Address dst,

7700

llvm::Type * SrcTy = src->getType();

7701

if (!isa<llvm::PointerType>(SrcTy)) {

7702

unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);

7703

assert(Size <= 8 && "does

not

support size > 8

"); 7704 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7705 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7706 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7708 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7709 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF), 7710 ObjCTypes.PtrObjectPtrTy); 7711 llvm::Value *args[] = {src, dstVal}; 7713 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 7714 args, "

globalassign

"); 7716 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 7717 args, "

threadlocalassign

"); 7721CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 7722 const ObjCAtSynchronizedStmt &S) { 7723 EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(), 7724 ObjCTypes.getSyncExitFn()); 7728CGObjCNonFragileABIMac::GetEHType(QualType T) { 7729 // There's a particular fixed type info for 'id'. 7730 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) { 7731 auto *IDEHType = CGM.getModule().getGlobalVariable("

OBJC_EHTYPE_id

"); 7734 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 7735 llvm::GlobalValue::ExternalLinkage, nullptr, 7736 "

OBJC_EHTYPE_id

"); 7737 if (CGM.getTriple().isOSBinFormatCOFF()) 7738 IDEHType->setDLLStorageClass(getStorage(CGM, "

OBJC_EHTYPE_id

")); 7743 // All other types should be Objective-C interface pointer types. 7744 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 7747 const ObjCInterfaceType *IT = PT->getInterfaceType(); 7748 assert(IT && "

Invalid

@catch type

.

"); 7750 return GetInterfaceEHType(IT->getDecl(), NotForDefinition); 7753void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, 7754 const ObjCAtTryStmt &S) { 7755 EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(), 7756 ObjCTypes.getObjCEndCatchFn(), 7757 ObjCTypes.getExceptionRethrowFn()); 7761

void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,

7762

const ObjCAtThrowStmt &S,

7763

bool ClearInsertionPoint) {

7764

if (const Expr *ThrowExpr = S.getThrowExpr()) {

7765

llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);

7766

Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);

7767

llvm::CallBase *Call =

7768

CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);

7769

Call->setDoesNotReturn();

7771

llvm::CallBase *Call =

7772

CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());

7773

Call->setDoesNotReturn();

7776

CGF.Builder.CreateUnreachable();

7777

if (ClearInsertionPoint)

7778

CGF.Builder.ClearInsertionPoint();

7782

CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,

7783

ForDefinition_t IsForDefinition) {

7784

llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];

7785

StringRef ClassName = ID->getObjCRuntimeNameAsString();

7787

// If we don't need a definition, return the entry if found or check

7788

// if we use an external reference.

7789

if (!IsForDefinition) {

7793

// If this type (or a super class) has the __objc_exception__

7794

// attribute, emit an external reference.

7795

if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {

7796

std::string EHTypeName = ("OBJC_EHTYPE_$_

" + ClassName).str(); 7797 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, 7798 false, llvm::GlobalValue::ExternalLinkage, 7799 nullptr, EHTypeName); 7800 CGM.setGVProperties(Entry, ID); 7805 // Otherwise we need to either make a new entry or fill in the initializer. 7806 assert((!Entry || !Entry->hasInitializer()) && "

Duplicate EHType definition

"); 7808 std::string VTableName = "

objc_ehtype_vtable

"; 7809 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName); 7812 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false, 7813 llvm::GlobalValue::ExternalLinkage, nullptr, 7815 if (CGM.getTriple().isOSBinFormatCOFF()) 7816 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName)); 7819 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); 7820 ConstantInitBuilder builder(CGM); 7821 auto values = builder.beginStruct(ObjCTypes.EHTypeTy); 7823 llvm::ConstantExpr::getInBoundsGetElementPtr(VTableGV->getValueType(), 7824 VTableGV, VTableIdx)); 7825 values.add(GetClassName(ClassName)); 7826 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition)); 7828 llvm::GlobalValue::LinkageTypes L = IsForDefinition 7829 ? llvm::GlobalValue::ExternalLinkage 7830 : llvm::GlobalValue::WeakAnyLinkage; 7832 values.finishAndSetAsInitializer(Entry); 7833 Entry->setAlignment(CGM.getPointerAlign().getAsAlign()); 7835 Entry = values.finishAndCreateGlobal("

OBJC_EHTYPE_$_

" + ClassName, 7836 CGM.getPointerAlign(), 7839 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) 7840 CGM.setGVProperties(Entry, ID); 7842 assert(Entry->getLinkage() == L); 7844 if (!CGM.getTriple().isOSBinFormatCOFF()) 7845 if (ID->getVisibility() == HiddenVisibility) 7846 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 7848 if (IsForDefinition) 7849 if (CGM.getTriple().isOSBinFormatMachO()) 7850 Entry->setSection("

__DATA,__objc_const

"); 7857CodeGen::CGObjCRuntime * 7858CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 7859 switch (CGM.getLangOpts().ObjCRuntime.getKind()) { 7860 case ObjCRuntime::FragileMacOSX: 7861 return new CGObjCMac(CGM); 7863 case ObjCRuntime::MacOSX: 7864 case ObjCRuntime::iOS: 7865 case ObjCRuntime::WatchOS: 7866 return new CGObjCNonFragileABIMac(CGM); 7868 case ObjCRuntime::GNUstep: 7869 case ObjCRuntime::GCC: 7870 case ObjCRuntime::ObjFW: 7871 llvm_unreachable("

these runtimes are

not

Mac runtimes

"); 7873 llvm_unreachable("

bad runtime

");

Defines the clang::ASTContext interface.

ASTImporterLookupTable & LT

@ FragileABI_Class_Meta

Is a meta-class.

@ FragileABI_Class_Hidden

Has hidden visibility.

@ FragileABI_Class_Factory

Apparently: is not a meta-class.

@ FragileABI_Class_HasCXXStructors

Has a non-trivial constructor or destructor.

@ FragileABI_Class_HasMRCWeakIvars

Class implementation was compiled under MRC and has MRC weak ivars.

@ FragileABI_Class_CompiledByARC

Class implementation was compiled under ARC.

static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, bool pointee=false)

static bool hasWeakMember(QualType type)

static std::string getBlockLayoutInfoString(const SmallVectorImpl< CGObjCCommonMac::RUN_SKIP > &RunSkipBlockVars, bool HasCopyDisposeHelpers)

static llvm::StringMapEntry< llvm::GlobalVariable * > & GetConstantStringEntry(llvm::StringMap< llvm::GlobalVariable * > &Map, const StringLiteral *Literal, unsigned &StringLength)

static llvm::GlobalValue::LinkageTypes getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section)

static void addIfPresent(llvm::DenseSet< llvm::Value * > &S, Address V)

static void PushProtocolProperties(llvm::SmallPtrSet< const IdentifierInfo *, 16 > &PropertySet, SmallVectorImpl< const ObjCPropertyDecl * > &Properties, const ObjCProtocolDecl *Proto, bool IsClassProperty)

static llvm::GlobalVariable * finishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder, const llvm::Twine &Name, CodeGenModule &CGM)

A helper function to create an internal or private global variable.

static bool hasMRCWeakIvars(CodeGenModule &CGM, const ObjCImplementationDecl *ID)

For compatibility, we only want to set the "HasMRCWeakIvars" flag (and actually fill in a layout stri...

@ kCFTaggedObjectID_Integer

@ NonFragileABI_Class_HasCXXDestructorOnly

Class has non-trivial destructors, but zero-initialization is okay.

@ NonFragileABI_Class_Hidden

Has hidden visibility.

@ NonFragileABI_Class_HasCXXStructors

Has a non-trivial constructor or destructor.

@ NonFragileABI_Class_Exception

Has the exception attribute.

@ NonFragileABI_Class_HasIvarReleaser

(Obsolete) ARC-specific: this class has a .release_ivars method

@ NonFragileABI_Class_Root

Is a root class.

@ NonFragileABI_Class_Meta

Is a meta-class.

@ NonFragileABI_Class_HasMRCWeakIvars

Class implementation was compiled under MRC and has MRC weak ivars.

@ NonFragileABI_Class_CompiledByARC

Class implementation was compiled under ARC.

static llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)

getConstantGEP() - Help routine to construct simple GEPs.

static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)

hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...

static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)

Defines the clang::LangOptions interface.

llvm::MachO::Target Target

Defines the Objective-C statement AST node classes.

__device__ __2f16 float __ockl_bool s

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

CanQualType getCanonicalParamType(QualType T) const

Return the canonical parameter type corresponding to the specific potentially non-canonical one.

QualType getObjCClassType() const

Represents the Objective-C Class type.

const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const

Get or compute information about the layout of the specified record (struct/union/class) D,...

CanQualType getCanonicalType(QualType T) const

Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...

QualType getPointerType(QualType T) const

Return the uniqued reference to the type for a pointer to the specified type.

const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const

Get or compute information about the layout of the specified Objective-C implementation.

const LangOptions & getLangOpts() const

SelectorTable & Selectors

QualType getObjCProtoType() const

Retrieve the type of the Objective-C Protocol class.

QualType getPointerDiffType() const

Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.

QualType getObjCSelType() const

Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.

CanQualType getSizeType() const

Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.

QualType getObjCIdType() const

Represents the Objective-CC id type.

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

CharUnits getTypeSizeInChars(QualType T) const

Return the size of the specified (complete) type T, in characters.

QualType getObjCClassRedefinitionType() const

Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...

QualType getObjCIdRedefinitionType() const

Retrieve the type that id has been defined to, which may be different from the built-in id if id has ...

CharUnits toCharUnitsFromBits(int64_t BitSize) const

Convert a size in bits to a size in characters.

ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...

CharUnits getSize() const

getSize - Get the record size in characters.

uint64_t getFieldOffset(unsigned FieldNo) const

getFieldOffset - Get the offset of the given field index, in bits.

Represents an array type, per C99 6.7.5.2 - Array Declarators.

Represents a block literal declaration, which is like an unnamed FunctionDecl.

QualType withConst() const

Retrieves a version of this type with const applied.

CharUnits - This is an opaque type for sizes expressed in character units.

llvm::Align getAsAlign() const

getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

static CharUnits One()

One - Construct a CharUnits quantity of one.

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

static CharUnits Zero()

Zero - Construct a CharUnits quantity of zero.

Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...

llvm::Value * emitRawPointer(CodeGenFunction &CGF) const

Return the pointer contained in this class after authenticating it and adding offset to it if necessa...

llvm::Type * getElementType() const

Return the type of the values stored in this address.

unsigned getIndex() const

CharUnits getOffset() const

CGBlockInfo - Information to generate a block literal.

const BlockDecl * getBlockDecl() const

llvm::StructType * StructureType

CharUnits BlockHeaderForcedGapOffset

bool NeedsCopyDispose

True if the block has captures that would necessitate custom copy or dispose helper functions if the ...

CharUnits BlockHeaderForcedGapSize

const Capture & getCapture(const VarDecl *var) const

llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)

llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")

Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")

Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")

llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")

llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")

All available information about a concrete callee.

static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())

Implements runtime-specific code generation functions.

virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0

Returns an i8* which points to the byref layout information.

static void destroyCalleeDestroyedArguments(CodeGenFunction &CGF, const ObjCMethodDecl *method, const CallArgList &callArgs)

Destroy the callee-destroyed arguments of the given method, if it has any.

virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0

Generate a function preamble for a method with the specified types.

virtual std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM, const CGBlockInfo &blockInfo)

virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0

virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0

Generate a constant string object.

virtual void GenerateProtocol(const ObjCProtocolDecl *OPD)=0

Generate the named protocol.

virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0

virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0

Generates prologue for direct Objective-C Methods.

CallArgList - Type for representing both the value and type of arguments in a call.

void add(RValue rvalue, QualType type)

void addFrom(const CallArgList &other)

Add all the arguments from another CallArgList to this one.

CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...

llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)

EmitFromMemory - Change a scalar value from its memory representation to its value representation.

void EmitNullInitialization(Address DestPtr, QualType Ty)

EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...

JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)

The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...

void EmitAutoVarDecl(const VarDecl &D)

EmitAutoVarDecl - Emit an auto variable declaration.

llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)

createBasicBlock - Create an LLVM basic block.

void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)

EmitBlock - Emit the given block.

SmallVector< llvm::Value *, 8 > ObjCEHValueStack

ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.

llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)

CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...

RawAddress getNormalCleanupDestSlot()

JumpDest ReturnBlock

ReturnBlock - Unified return block.

llvm::Value * EmitObjCThrowOperand(const Expr *expr)

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)

EmitCall - Generate a call of the given function, expecting the given result type,...

void EmitVarDecl(const VarDecl &D)

EmitVarDecl - Emit a local variable declaration.

llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")

ASTContext & getContext() const

const Decl * CurFuncDecl

CurFuncDecl - Holds the Decl for the current outermost non-closure context.

void EmitBranchThroughCleanup(JumpDest Dest)

EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...

void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})

EmitStmt - Emit the code for the statement.

void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)

PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.

llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")

llvm::Type * ConvertType(QualType T)

RawAddress NormalCleanupDest

i32s containing the indexes of the cleanup destinations.

Address GetAddrOfLocalVar(const VarDecl *VD)

GetAddrOfLocalVar - Return the address of a local variable.

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

void EnsureInsertPoint()

EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.

llvm::LLVMContext & getLLVMContext()

llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)

EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...

This class organizes the cross-function state that is used while generating LLVM code.

llvm::Module & getModule() const

llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)

Create or return a runtime function declaration with the specified type and name.

void addCompilerUsedGlobal(llvm::GlobalValue *GV)

Add a global to a list to be added to the llvm.compiler.used metadata.

llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)

Get the address of the RTTI descriptor for the given type.

bool ReturnTypeUsesFPRet(QualType ResultType)

Return true iff the given type uses 'fpret' when used as a return type.

const LangOptions & getLangOpts() const

CodeGenTypes & getTypes()

const TargetInfo & getTarget() const

const llvm::DataLayout & getDataLayout() const

bool ReturnTypeUsesFP2Ret(QualType ResultType)

Return true iff the given type uses 'fp2ret' when used as a return type.

const llvm::Triple & getTriple() const

bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)

Return true iff the given type uses an argument slot when 'sret' is used as a return type.

llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)

Create a new runtime global variable with the specified type and name.

ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal)

Return a pointer to a constant CFString object for the given string.

ASTContext & getContext() const

bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)

Return true iff the given type uses 'sret' when used as a return type.

llvm::LLVMContext & getLLVMContext()

llvm::Constant * EmitNullConstant(QualType T)

Return the result of value-initializing the given type, i.e.

ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)

Returns a pointer to a character array containing the literal and a terminating '\0' character.

This class organizes the cross-module state that is used while lowering AST types to LLVM types.

llvm::Type * ConvertType(QualType T)

ConvertType - Convert type T into a llvm::Type.

A specialization of Address that requires the address to be an LLVM Constant.

llvm::Constant * getPointer() const

StructBuilder beginStruct(llvm::StructType *ty=nullptr)

A helper class of ConstantInitBuilder, used for building constant array initializers.

The standard implementation of ConstantInitBuilder used in Clang.

A helper class of ConstantInitBuilder, used for building constant struct initializers.

Information for lazily generating a cleanup.

LValue - This represents an lvalue references.

RValue - This trivial value class is used to represent the result of an expression that is evaluated.

static RValue get(llvm::Value *V)

static RValue getComplex(llvm::Value *V1, llvm::Value *V2)

Address getAggregateAddress() const

getAggregateAddr() - Return the Value* of the address of the aggregate.

llvm::Value * getScalarVal() const

getScalarVal() - Return the Value* of this scalar value.

std::pair< llvm::Value *, llvm::Value * > getComplexVal() const

getComplexVal - Return the real/imag components of this complex value.

An abstract representation of an aligned address.

llvm::Value * getPointer() const

ReturnValueSlot - Contains the address where the return value of a function can be stored,...

Decl - This represents one declaration (or definition), e.g.

bool isUsed(bool CheckUsedAttr=true) const

Whether any (re-)declaration of the entity was used, meaning that a definition is required.

This represents one expression.

Represents a member of a struct/union/class.

bool isBitField() const

Determines whether this field is a bitfield.

unsigned getBitWidthValue() const

Computes the bit width of this field, if this is a bit field.

One of these records is kept for each identifier that is lexed.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

clang::ObjCRuntime ObjCRuntime

std::string ObjCConstantStringClass

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

Represents Objective-C's @catch statement.

Represents Objective-C's @finally statement.

Represents Objective-C's @synchronized statement.

Represents Objective-C's @throw statement.

Represents Objective-C's @try ... @catch ... @finally statement.

const ObjCAtFinallyStmt * getFinallyStmt() const

Retrieve the @finally statement, if any.

catch_range catch_stmts()

ObjCCategoryDecl - Represents a category declaration.

ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.

ObjCCompatibleAliasDecl - Represents alias of a class.

ObjCContainerDecl - Represents a container for method declarations.

method_range methods() const

prop_range properties() const

const ObjCInterfaceDecl * getClassInterface() const

ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...

Represents an ObjC class declaration.

ObjCIvarDecl * all_declared_ivar_begin()

all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...

StringRef getObjCRuntimeNameAsString() const

Produce a name to be used for class's metadata.

ObjCInterfaceDecl * getSuperClass() const

bool isSuperClassOf(const ObjCInterfaceDecl *I) const

isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...

ObjCIvarDecl - Represents an ObjC instance variable.

ObjCInterfaceDecl * getContainingInterface()

Return the class interface that this ivar is logically contained in; this is either the interface whe...

ObjCIvarDecl * getNextIvar()

ObjCMethodDecl - Represents an instance or class method declaration.

ImplicitParamDecl * getSelfDecl() const

bool hasParamDestroyedInCallee() const

True if the method has a parameter that's destroyed in the callee.

Stmt * getBody() const override

Retrieve the body of this method, if it has one.

ObjCMethodDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

bool isDirectMethod() const

True if the method is tagged as objc_direct.

Selector getSelector() const

ImplicitParamDecl * getCmdDecl() const

QualType getReturnType() const

bool isClassMethod() const

ObjCInterfaceDecl * getClassInterface()

Represents a pointer to an Objective C object.

bool isObjCQualifiedIdType() const

True if this is equivalent to 'id.

const ObjCObjectType * getObjectType() const

Gets the type pointed to by this ObjC pointer.

bool isObjCIdType() const

True if this is equivalent to the 'id' type, i.e.

Represents a class type in Objective C.

ObjCInterfaceDecl * getInterface() const

Gets the interface declaration for this object type, if the base type really is an interface.

Represents one property declaration in an Objective-C interface.

Represents an Objective-C protocol declaration.

ObjCProtocolDecl * getDefinition()

Retrieve the definition of this protocol, if any.

StringRef getObjCRuntimeNameAsString() const

Produce a name to be used for protocol's metadata.

ObjCProtocolList::iterator protocol_iterator

protocol_iterator protocol_begin() const

protocol_range protocols() const

protocol_iterator protocol_end() const

bool isNonFragile() const

Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?

PointerType - C99 6.7.5.1 - Pointer Declarators.

A (possibly-)qualified type.

Qualifiers::ObjCLifetime getObjCLifetime() const

Returns lifetime attribute of this type.

bool isObjCGCStrong() const

true when Type is objc's strong.

bool isObjCGCWeak() const

true when Type is objc's weak.

@ OCL_Strong

Assigning into this object requires the old value to be released and the new value to be retained.

@ OCL_ExplicitNone

This object can be modified without requiring retains or releases.

@ OCL_None

There is no lifetime qualification on this type.

@ OCL_Weak

Reading or writing from this object requires a barrier call.

@ OCL_Autoreleasing

Assigning into this object requires a lifetime extension.

Represents a struct/union/class.

field_range fields() const

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

RecordDecl * getDecl() const

Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)

Can create any sort of selector.

Smart pointer class that efficiently represents Objective-C method names.

std::string getAsString() const

Derive the full selector name (e.g.

Stmt - This represents one statement.

StringLiteral - This represents a string literal expression, e.g.

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

uint64_t getPointerWidth(LangAS AddrSpace) const

Return the width of pointers on this target, for the specified address space.

unsigned getCharWidth() const

The base class of the type hierarchy.

bool isBlockPointerType() const

CanQualType getCanonicalTypeUnqualified() const

const T * castAs() const

Member-template castAs<specific type>.

bool isObjCQualifiedIdType() const

bool isObjCIdType() const

bool isObjCObjectPointerType() const

bool isObjCQualifiedClassType() const

bool isObjCClassType() const

const T * getAs() const

Member-template getAs<specific type>'.

bool isRecordType() const

Represents a variable declaration or definition.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl

Matches block declarations.

bool Zero(InterpState &S, CodePtr OpPC)

RangeSelector name(std::string ID)

Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...

The JSON file list parser is used to communicate input to InstallAPI.

bool operator<(DeclarationName LHS, DeclarationName RHS)

Ordering on two declaration names.

Linkage

Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.

Selector GetUnarySelector(StringRef name, ASTContext &Ctx)

Utility function for constructing an unary selector.

Selector GetNullarySelector(StringRef name, ASTContext &Ctx)

Utility function for constructing a nullary selector.

const FunctionProtoType * T

@ Interface

The "__interface" keyword introduces the elaborated-type-specifier.

@ Class

The "class" keyword introduces the elaborated-type-specifier.

@ HiddenVisibility

Objects with "hidden" visibility are not seen by the dynamic linker.

int printf(__constant const char *st,...) __attribute__((format(printf

float __ovld __cnfn length(float)

Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)

llvm::CallingConv::ID getRuntimeCC() const

llvm::IntegerType * Int32Ty

llvm::IntegerType * IntPtrTy

llvm::IntegerType * IntTy

int

llvm::PointerType * Int8PtrTy

llvm::PointerType * UnqualPtrTy

llvm::IntegerType * PtrDiffTy

CharUnits getPointerAlign() const


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4