clang: lib/CodeGen/CGObjCRuntime.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

25#include "llvm/IR/Instruction.h"

26#include "llvm/Support/SaveAndRestore.h"

27

28using namespace clang;

29using namespace CodeGen;

30

36}

37

42 Ivar) /

44}

45

51 Ivar);

52}

53

56 llvm::Value *BaseValue,

58 unsigned CVRQualifiers,

59 llvm::Value *Offset) {

60

66 llvm::Value *V = BaseValue;

68

71 return LV;

72 }

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88 uint64_t FieldBitOffset =

94 llvm::alignTo(BitOffset + BitFieldSize, AlignmentBits));

96

97

98

99

100

101

102

107

110 Alignment);

111

115}

116

117namespace {

118 struct CatchHandler {

120 const Stmt *Body;

121 llvm::BasicBlock *Block;

123

124 unsigned Flags;

125 };

126

128 CallObjCEndCatch(bool MightThrow, llvm::FunctionCallee Fn)

129 : MightThrow(MightThrow), Fn(Fn) {}

130 bool MightThrow;

131 llvm::FunctionCallee Fn;

132

134 if (MightThrow)

136 else

138 }

139 };

140}

141

144 llvm::FunctionCallee beginCatchFn,

145 llvm::FunctionCallee endCatchFn,

146 llvm::FunctionCallee exceptionRethrowFn) {

147

149 if (S.getNumCatchStmts())

151

153

155 if (!useFunclets)

157 FinallyInfo.enter(CGF, Finally->getFinallyBody(),

158 beginCatchFn, endCatchFn, exceptionRethrowFn);

159

161

162

163

164 if (S.getNumCatchStmts()) {

165 for (const ObjCAtCatchStmt *CatchStmt : S.catch_stmts()) {

166 const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();

167

168 Handlers.push_back(CatchHandler());

169 CatchHandler &Handler = Handlers.back();

170 Handler.Variable = CatchDecl;

171 Handler.Body = CatchStmt->getCatchBody();

173 Handler.Flags = 0;

174

175

176 if (!CatchDecl) {

178 Handler.TypeInfo = catchAll.RTTI;

179 Handler.Flags = catchAll.Flags;

180

181 break;

182 }

183

185 }

186

188 for (unsigned I = 0, E = Handlers.size(); I != E; ++I)

189 Catch->setHandler(I, { Handlers[I].TypeInfo, Handlers[I].Flags }, Handlers[I].Block);

190 }

191

192 if (useFunclets)

197

198 const Stmt *FinallyBlock = Finally->getFinallyBody();

200

201

202 HelperCGF.EmitStmt(FinallyBlock);

203

205

206 llvm::Function *FinallyFunc = HelperCGF.CurFn;

207

208

209

211 }

212

213

214

215 CGF.EmitStmt(S.getTryBody());

216

217

218 if (S.getNumCatchStmts())

220

221

222 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();

223

224

225 for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {

226 CatchHandler &Handler = Handlers[I];

227

229

232 if (useFunclets) {

233 llvm::Instruction *CPICandidate = Handler.Block->getFirstNonPHI();

234 if (auto *CPI = dyn_cast_or_nullllvm::CatchPadInst(CPICandidate)) {

238 }

239 }

240

242

243

244 llvm::Value *Exn = RawExn;

245 if (beginCatchFn)

247

248 if (endCatchFn) {

249

250 bool EndCatchMightThrow = (Handler.Variable == nullptr);

251

253 EndCatchMightThrow,

254 endCatchFn);

255 }

256

257

258 if (const VarDecl *CatchParam = Handler.Variable) {

259 llvm::Type *CatchType = CGF.ConvertType(CatchParam->getType());

260 llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType);

261

264 }

265

269

270

272

274 }

275

276

277 CGF.Builder.restoreIP(SavedIP);

278

279

280 if (!useFunclets && S.getFinallyStmt())

281 FinallyInfo.exit(CGF);

282

285}

286

288 llvm::Value *exn,

289 const VarDecl *paramDecl) {

290

292

296 [[fallthrough]];

297

302 return;

303

306 return;

307 }

308 llvm_unreachable("invalid ownership qualifier");

309}

310

311namespace {

313 llvm::FunctionCallee SyncExitFn;

314 llvm::Value *SyncArg;

315 CallSyncExit(llvm::FunctionCallee SyncExitFn, llvm::Value *SyncArg)

316 : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}

317

320 }

321 };

322}

323

326 llvm::FunctionCallee syncEnterFn,

327 llvm::FunctionCallee syncExitFn) {

329

330

331

332 const Expr *lockExpr = S.getSynchExpr();

333 llvm::Value *lock;

334 if (CGF.getLangOpts().ObjCAutoRefCount) {

337 } else {

339 }

341

342

343 CGF.Builder.CreateCall(syncEnterFn, lock)->setDoesNotThrow();

344

345

347

348

349 CGF.EmitStmt(S.getSynchBody());

350}

351

352

353

354

355

356

357

358

363 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();

364

365 llvm::PointerType *signatureType =

367

368

369 if (method) {

372

375

377 }

378

379

382

384}

385

388 bool isSuper,

390 llvm::Value *receiver) {

391

392

393 if (isSuper)

394 return false;

395

396

397

398 if (classReceiver && method && method->isClassMethod())

400

401

402

403 if (auto curMethod =

404 dyn_cast_or_null(CGF.CurCodeDecl)) {

405 auto self = curMethod->getSelfDecl();

406 if (self->getType().isConstQualified()) {

407 if (auto LI = dyn_castllvm::LoadInst(receiver->stripPointerCasts())) {

409 if (selfAddr == LI->getPointerOperand()) {

410 return false;

411 }

412 }

413 }

414 }

415

416

417 return true;

418}

419

421 do {

422 if (ID->isWeakImported())

423 return true;

424 } while ((ID = ID->getSuperClass()));

425

426 return false;

427}

428

432 CallArgList::const_iterator I = callArgs.begin();

434 i != e; ++i, ++I) {

436 if (param->hasAttr()) {

437 RValue RV = I->getRValue(CGF);

439 "NullReturnState::complete - arg not on object");

441 } else {

444 if (RT && RT->getDecl()->isParamDestroyedInCallee()) {

445 RValue RV = I->getRValue(CGF);

447 switch (DtorKind) {

450 break;

453 break;

454 default:

455 llvm_unreachable("unexpected dtor kind");

456 break;

457 }

458 }

459 }

460 }

461}

462

463llvm::Constant *

467}

468

470 bool includeCategoryName) {

471 std::string buffer;

472 llvm::raw_string_ostream out(buffer);

474 true,

475 includeCategoryName);

476 return buffer;

477}

Defines the Objective-C statement AST node classes.

QualType getObjCObjectPointerType(QualType OIT) const

Return a ObjCObjectPointerType type for the given ObjCObjectType.

int64_t toBits(CharUnits CharSize) const

Convert a size in characters to a size in bits.

uint64_t lookupFieldBitOffset(const ObjCInterfaceDecl *OID, const ObjCImplementationDecl *ID, const ObjCIvarDecl *Ivar) const

Get the offset of an ObjCIvarDecl in bits.

CharUnits toCharUnitsFromBits(int64_t BitSize) const

Convert a size in bits to a size in characters.

uint64_t getCharWidth() const

Return the size of the character type, in bits.

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

static CharUnits fromQuantity(QuantityType Quantity)

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

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::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)

Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")

MangleContext & getMangleContext()

Gets the mangle context.

CGFunctionInfo - Class to encapsulate the information about a function definition.

virtual llvm::Constant * GetEHType(QualType T)=0

Get the type constant to catch for the given ObjC pointer type.

virtual CatchTypeInfo getCatchAllTypeInfo()

void EmitInitOfCatchParam(CodeGenFunction &CGF, llvm::Value *exn, const VarDecl *paramDecl)

bool canMessageReceiverBeNull(CodeGenFunction &CGF, const ObjCMethodDecl *method, bool isSuper, const ObjCInterfaceDecl *classReceiver, llvm::Value *receiver)

std::string getSymbolNameForMethod(const ObjCMethodDecl *method, bool includeCategoryName=true)

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

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

LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *OID, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers, llvm::Value *Offset)

uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *Ivar)

Compute an offset to the given ivar, suitable for passing to EmitValueForIvarAtOffset.

static bool isWeakLinkedClass(const ObjCInterfaceDecl *cls)

virtual llvm::Constant * GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0

GetOrEmitProtocol - Get the protocol object for the given declaration, emitting it if necessary.

void EmitTryCatchStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S, llvm::FunctionCallee beginCatchFn, llvm::FunctionCallee endCatchFn, llvm::FunctionCallee exceptionRethrowFn)

Emits a try / catch statement.

CodeGen::CodeGenModule & CGM

MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method, QualType resultType, CallArgList &callArgs)

Compute the pointer-to-function type to which a message send should be casted in order to correctly c...

void EmitAtSynchronizedStmt(CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S, llvm::FunctionCallee syncEnterFn, llvm::FunctionCallee syncExitFn)

Emits an @synchronize() statement, using the syncEnterFn and syncExitFn arguments as the functions ca...

unsigned ComputeBitfieldBitOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *ID, const ObjCIvarDecl *Ivar)

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

A class controlling the emission of a finally block.

void exit(CodeGenFunction &CGF)

void enter(CodeGenFunction &CGF, const Stmt *Finally, llvm::FunctionCallee beginCatchFn, llvm::FunctionCallee endCatchFn, llvm::FunctionCallee rethrowFn)

Enters a finally block for an implementation using zero-cost exceptions.

void ForceCleanup()

Force the emission of cleanups now, instead of waiting until this object is destroyed.

Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.

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

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

Address getExceptionSlot()

Returns a pointer to the function's exception object and selector slot, which is assigned in every la...

static Destroyer destroyNonTrivialCStruct

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 startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, const Stmt *OutlinedStmt)

void EmitAutoVarDecl(const VarDecl &D)

EmitAutoVarDecl - Emit an auto variable declaration.

void popCatchScope()

popCatchScope - Pops the catch scope at the top of the EHScope stack, emitting any required code (oth...

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

createBasicBlock - Create an LLVM basic block.

const LangOptions & getLangOpts() const

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.

const Decl * CurCodeDecl

CurCodeDecl - This is the inner-most code context, which includes blocks.

static Destroyer destroyCXXObject

llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)

void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)

void pushSEHCleanup(CleanupKind kind, llvm::Function *FinallyFunc)

LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)

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

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.

llvm::Type * ConvertType(QualType T)

void EmitARCInitWeak(Address addr, llvm::Value *value)

llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")

llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)

Address GetAddrOfLocalVar(const VarDecl *VD)

GetAddrOfLocalVar - Return the address of a local variable.

llvm::Instruction * CurrentFuncletPad

llvm::LLVMContext & getLLVMContext()

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

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

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

llvm::Value * getExceptionFromSlot()

Returns the contents of the function's exception object and selector slots.

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

CodeGenTypes & getTypes()

const TargetInfo & getTarget() const

const llvm::DataLayout & getDataLayout() const

CGCXXABI & getCXXABI() const

ASTContext & getContext() const

llvm::LLVMContext & getLLVMContext()

CGObjCRuntime & getObjCRuntime()

Return a reference to the configured Objective-C runtime.

const CGFunctionInfo & arrangeUnprototypedObjCMessageSend(QualType returnType, const CallArgList &args)

const CGFunctionInfo & arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, QualType receiverType)

Arrange the argument and result information for the function type through which to perform a send to ...

const CGFunctionInfo & arrangeCall(const CGFunctionInfo &declFI, const CallArgList &args)

Given a function info for a declaration, return the function info for a call with the given arguments...

A scope which attempts to handle some, possibly all, types of exceptions.

void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)

Information for lazily generating a cleanup.

class EHCatchScope * pushCatch(unsigned NumHandlers)

Push a set of catch handlers on the stack.

LValue - This represents an lvalue references.

static LValue MakeBitfield(Address Addr, const CGBitFieldInfo &Info, QualType type, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)

Create a new object to represent a bit-field access.

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

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.

This represents one expression.

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.

void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS, bool includePrefixByte=true, bool includeCategoryNamespace=true)

Represents Objective-C's @catch statement.

Represents Objective-C's @finally statement.

Represents Objective-C's @synchronized statement.

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

const ObjCInterfaceDecl * getClassInterface() const

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

Represents an ObjC class declaration.

const Type * getTypeForDecl() const

ObjCIvarDecl - Represents an ObjC instance variable.

QualType getUsageType(QualType objectType) const

Retrieve the type of this instance variable when viewed as a member of a specific object type.

ObjCMethodDecl - Represents an instance or class method declaration.

param_const_iterator param_end() const

param_const_iterator param_begin() const

bool isClassMethod() const

Represents an Objective-C protocol declaration.

Represents a parameter to a function.

A (possibly-)qualified type.

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

QualType withCVRQualifiers(unsigned CVR) const

DestructionKind isDestructedType() const

Returns a nonzero value if objects of this type require non-trivial work to clean up after.

@ 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.

ObjCLifetime getObjCLifetime() const

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

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

unsigned getCharAlign() const

const T * getAs() const

Member-template getAs'.

Represents a variable declaration or definition.

@ Decl

The l-value was an access to a declared entity or something equivalently strong, like the address of ...

@ NormalCleanup

Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...

llvm::Constant * emitObjCProtocolObject(CodeGenModule &CGM, const ObjCProtocolDecl *p)

Get a pointer to a protocol object for the given declaration, emitting it if it hasn't already been e...

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

Structure with information about how a bitfield should be accessed.

unsigned StorageSize

The storage size in bits which should be used when accessing this bitfield.

static CGBitFieldInfo MakeInfo(class CodeGenTypes &Types, const FieldDecl *FD, uint64_t Offset, uint64_t Size, uint64_t StorageSize, CharUnits StorageOffset)

Given a bit-field decl, build an appropriate helper object for accessing that field (which is expecte...

A jump destination is an abstract label, branching to which may require a jump out through normal cle...

llvm::BasicBlock * getBlock() const

llvm::PointerType * VoidPtrTy

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64

static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)

bool usesFuncletPads() const

Does this personality use landingpads or the family of pad instructions designed to form funclets?