26#include "llvm/IR/Instruction.h"
27#include "llvm/IR/Instructions.h"
28#include "llvm/Support/ErrorHandling.h"
29#include "llvm/Support/SaveAndRestore.h"
37 return CGM.getContext().lookupFieldBitOffset(OID, Ivar) /
38 CGM.getContext().getCharWidth();
45 CGM.getContext().getCharWidth();
52 return CGM.getContext().lookupFieldBitOffset(ID, Ivar);
57 llvm::Value *BaseValue,
59 unsigned CVRQualifiers,
60 llvm::Value *Offset) {
67 llvm::Value *
V = BaseValue;
89 uint64_t FieldBitOffset =
95 llvm::alignTo(BitOffset + BitFieldSize, AlignmentBits));
119 struct CatchHandler {
122 llvm::BasicBlock *
Block;
128 struct CallObjCEndCatch final : EHScopeStack::Cleanup {
129 CallObjCEndCatch(
bool MightThrow, llvm::FunctionCallee Fn)
130 : MightThrow(MightThrow), Fn(Fn) {}
132 llvm::FunctionCallee Fn;
145 llvm::FunctionCallee beginCatchFn,
146 llvm::FunctionCallee endCatchFn,
147 llvm::FunctionCallee exceptionRethrowFn) {
163 FinallyInfo.
enter(CGF, Finally->getFinallyBody(), beginCatchFn,
164 endCatchFn, exceptionRethrowFn);
169 const Stmt *FinallyBlock = Finally->getFinallyBody();
174 llvm::Function *FinallyFunc = HelperCGF.
CurFn;
179 if (useFunclets && IsMSVC)
185 const Stmt *FinallyBlock = Finally->getFinallyBody();
193 llvm::Function *FinallyFunc = HelperCGF.
CurFn;
204 const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
206 Handlers.push_back(CatchHandler());
207 CatchHandler &Handler = Handlers.back();
208 Handler.Variable = CatchDecl;
209 Handler.Body = CatchStmt->getCatchBody();
216 Handler.TypeInfo = catchAll.RTTI;
217 Handler.Flags = catchAll.Flags;
227 for (
unsigned I = 0, E = Handlers.size(); I != E; ++I)
228 Catch->
setHandler(I, { Handlers[I].TypeInfo, Handlers[I].Flags }, Handlers[I].Block);
235 llvm::BasicBlock *DispatchBlock =
nullptr;
246 llvm::BasicBlock *WasmCatchStartBlock =
nullptr;
247 llvm::CatchPadInst *CPI =
nullptr;
248 if (DispatchBlock && IsWasm) {
251 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
252 ? CatchSwitch->getSuccessor(1)
253 : CatchSwitch->getSuccessor(0);
259 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
264 bool HasCatchAll =
false;
265 for (CatchHandler &Handler : Handlers) {
266 HasCatchAll |= Handler.TypeInfo ==
nullptr;
270 Handler.Body->getSourceRange());
273 llvm::BasicBlock::iterator CPICandidate =
274 Handler.Block->getFirstNonPHIIt();
275 if (CPICandidate != Handler.Block->end()) {
276 if ((CPI = dyn_cast_or_null<llvm::CatchPadInst>(CPICandidate))) {
292 llvm::Value *Exn = RawExn;
298 bool EndCatchMightThrow = (Handler.Variable ==
nullptr);
300 CGF.
EHStack.pushCleanup<CallObjCEndCatch>(
305 if (
const VarDecl *CatchParam = Handler.Variable) {
306 llvm::Type *CatchType = CGF.
ConvertType(CatchParam->getType());
307 llvm::Value *CastExn = CGF.
Builder.CreateBitCast(Exn, CatchType);
325 if (IsWasm && !HasCatchAll && WasmCatchStartBlock) {
330 CGF.
Builder.restoreIP(SavedIP);
338 FinallyInfo.
exit(CGF);
367 llvm_unreachable(
"invalid ownership qualifier");
371 struct CallSyncExit final : EHScopeStack::Cleanup {
372 llvm::FunctionCallee SyncExitFn;
373 llvm::Value *SyncArg;
374 CallSyncExit(llvm::FunctionCallee SyncExitFn, llvm::Value *SyncArg)
375 : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
385 llvm::FunctionCallee syncEnterFn,
386 llvm::FunctionCallee syncExitFn) {
402 CGF.
Builder.CreateCall(syncEnterFn, lock)->setDoesNotThrow();
422 unsigned ProgramAS =
CGM.getDataLayout().getProgramAddressSpace();
424 llvm::PointerType *signatureType =
425 llvm::PointerType::get(
CGM.getLLVMContext(), ProgramAS);
432 CGM.getTypes().arrangeObjCMessageSendSignature(method, callArgs[0].Ty);
435 CGM.getTypes().arrangeCall(signature, callArgs,
nullptr);
442 CGM.getTypes().arrangeUnprototypedObjCMessageSend(resultType, callArgs);
462 if (
auto curMethod = dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl)) {
463 auto self = curMethod->getSelfDecl();
464 if (self->getType().isConstQualified()) {
465 if (
auto LI = dyn_cast<llvm::LoadInst>(receiver->stripPointerCasts())) {
467 if (selfAddr == LI->getPointerOperand()) {
487 if (ID->isWeakImported())
489 }
while ((ID = ID->getSuperClass()));
497 CallArgList::const_iterator I = callArgs.begin();
501 if (param->
hasAttr<NSConsumedAttr>()) {
502 RValue RV = I->getRValue(CGF);
504 "NullReturnState::complete - arg not on object");
509 if (RD && RD->isParamDestroyedInCallee()) {
510 RValue RV = I->getRValue(CGF);
520 llvm_unreachable(
"unexpected dtor kind");
535 bool includeCategoryName,
538 llvm::raw_string_ostream
out(buffer);
539 CGM.getCXXABI().getMangleContext().mangleObjCMethodName(
540 OMD,
out,
true, includeCategoryName, useDirectABI);
Defines the Objective-C statement AST node classes.
uint64_t lookupFieldBitOffset(const ObjCInterfaceDecl *OID, const ObjCIvarDecl *Ivar) const
Get the offset of an ObjCIvarDecl in bits.
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.
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.
This is an opaque type for sizes expressed in character units.
static CharUnits fromQuantity(QuantityType Quantity)
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="")
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.
std::string getSymbolNameForMethod(const ObjCMethodDecl *method, bool includeCategoryName=true, bool useDirectABI=false)
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)
bool canClassObjectBeUnrealized(const ObjCInterfaceDecl *ClassDecl, CodeGenFunction &CGF) const
Check if a class object can be unrealized (not yet initialized).
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...
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
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 EmitARCInitWeak(Address addr, llvm::Value *value)
i8* @objc_initWeak(i8** addr, i8* value) Returns value.
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
llvm::Type * ConvertType(QualType T)
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
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.
const LangOptions & getLangOpts() const
static Destroyer destroyCXXObject
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
Release the given object.
Address getExceptionSlot()
Returns a pointer to the function's exception object and selector slot, which is assigned in every la...
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(),...
void popCatchScope()
popCatchScope - Pops the catch scope at the top of the EHScope stack, emitting any required code (oth...
void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, const Stmt *OutlinedStmt)
Arrange a function prototype that can be called by Windows exception handling personalities.
void pushSEHCleanup(CleanupKind kind, llvm::Function *FinallyFunc)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
Retain the given object, with normal retain semantics.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
void WasmEmitFallthroughRethrow(llvm::BasicBlock *WasmCatchStartBlock)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::Instruction * CurrentFuncletPad
llvm::LLVMContext & getLLVMContext()
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
This class organizes the cross-function state that is used while generating LLVM code.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
ASTContext & getContext() const
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
A scope which attempts to handle some, possibly all, types of exceptions.
void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
class EHCatchScope * pushCatch(unsigned NumHandlers)
Push a set of catch handlers on the stack.
llvm::BasicBlock * getCachedEHDispatchBlock() const
bool hasEHBranches() const
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.
Represents Objective-C's @catch statement.
Represents Objective-C's @finally statement.
Represents Objective-C's @synchronized statement.
const Expr * getSynchExpr() const
const CompoundStmt * getSynchBody() const
Represents Objective-C's @try ... @catch ... @finally statement.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
const Stmt * getTryBody() const
Retrieve the @try body.
catch_range catch_stmts()
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
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharAlign() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
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 ...
const EHPersonality & getEHPersonality(CodeGenModule &CGM, const FunctionDecl *FD)
Selects the personality function to use for FD, or for the translation unit as a whole when FD is nul...
@ 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...
Top level wrappers for InstallAPI frontend operations.
U cast(CodeGen::Address addr)
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets?
bool isWasmPersonality() const
bool isMSVCPersonality() const
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