summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CodeGenFunction.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.h')
-rw-r--r--lib/CodeGen/CodeGenFunction.h178
1 files changed, 120 insertions, 58 deletions
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index d96c355..7f32045 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -133,17 +133,17 @@ public:
/// block.
CleanupBlockInfo PopCleanupBlock();
- /// CleanupScope - RAII object that will create a cleanup block and set the
- /// insert point to that block. When destructed, it sets the insert point to
- /// the previous block and pushes a new cleanup entry on the stack.
- class CleanupScope {
+ /// DelayedCleanupBlock - RAII object that will create a cleanup block and set
+ /// the insert point to that block. When destructed, it sets the insert point
+ /// to the previous block and pushes a new cleanup entry on the stack.
+ class DelayedCleanupBlock {
CodeGenFunction& CGF;
llvm::BasicBlock *CurBB;
llvm::BasicBlock *CleanupEntryBB;
llvm::BasicBlock *CleanupExitBB;
public:
- CleanupScope(CodeGenFunction &cgf)
+ DelayedCleanupBlock(CodeGenFunction &cgf)
: CGF(cgf), CurBB(CGF.Builder.GetInsertBlock()),
CleanupEntryBB(CGF.createBasicBlock("cleanup")), CleanupExitBB(0) {
CGF.Builder.SetInsertPoint(CleanupEntryBB);
@@ -155,7 +155,7 @@ public:
return CleanupExitBB;
}
- ~CleanupScope() {
+ ~DelayedCleanupBlock() {
CGF.PushCleanupBlock(CleanupEntryBB, CleanupExitBB);
// FIXME: This is silly, move this into the builder.
if (CurBB)
@@ -165,6 +165,50 @@ public:
}
};
+ /// \brief Enters a new scope for capturing cleanups, all of which will be
+ /// executed once the scope is exited.
+ class CleanupScope {
+ CodeGenFunction& CGF;
+ size_t CleanupStackDepth;
+ bool OldDidCallStackSave;
+ bool PerformCleanup;
+
+ CleanupScope(const CleanupScope &); // DO NOT IMPLEMENT
+ CleanupScope &operator=(const CleanupScope &); // DO NOT IMPLEMENT
+
+ public:
+ /// \brief Enter a new cleanup scope.
+ explicit CleanupScope(CodeGenFunction &CGF)
+ : CGF(CGF), PerformCleanup(true)
+ {
+ CleanupStackDepth = CGF.CleanupEntries.size();
+ OldDidCallStackSave = CGF.DidCallStackSave;
+ }
+
+ /// \brief Exit this cleanup scope, emitting any accumulated
+ /// cleanups.
+ ~CleanupScope() {
+ if (PerformCleanup) {
+ CGF.DidCallStackSave = OldDidCallStackSave;
+ CGF.EmitCleanupBlocks(CleanupStackDepth);
+ }
+ }
+
+ /// \brief Determine whether this scope requires any cleanups.
+ bool requiresCleanups() const {
+ return CGF.CleanupEntries.size() > CleanupStackDepth;
+ }
+
+ /// \brief Force the emission of cleanups now, instead of waiting
+ /// until this object is destroyed.
+ void ForceCleanup() {
+ assert(PerformCleanup && "Already forced cleanup");
+ CGF.DidCallStackSave = OldDidCallStackSave;
+ CGF.EmitCleanupBlocks(CleanupStackDepth);
+ PerformCleanup = false;
+ }
+ };
+
/// EmitCleanupBlocks - Takes the old cleanup stack size and emits the cleanup
/// blocks that have been added.
void EmitCleanupBlocks(size_t OldCleanupStackSize);
@@ -176,27 +220,31 @@ public:
/// this behavior for branches?
void EmitBranchThroughCleanup(llvm::BasicBlock *Dest);
- /// PushConditionalTempDestruction - Should be called before a conditional
- /// part of an expression is emitted. For example, before the RHS of the
- /// expression below is emitted:
+ /// StartConditionalBranch - Should be called before a conditional part of an
+ /// expression is emitted. For example, before the RHS of the expression below
+ /// is emitted:
///
/// b && f(T());
///
- /// This is used to make sure that any temporaryes created in the conditional
+ /// This is used to make sure that any temporaries created in the conditional
/// branch are only destroyed if the branch is taken.
- void PushConditionalTempDestruction();
+ void StartConditionalBranch() {
+ ++ConditionalBranchLevel;
+ }
- /// PopConditionalTempDestruction - Should be called after a conditional
- /// part of an expression has been emitted.
- void PopConditionalTempDestruction();
+ /// FinishConditionalBranch - Should be called after a conditional part of an
+ /// expression has been emitted.
+ void FinishConditionalBranch() {
+ --ConditionalBranchLevel;
+ }
private:
CGDebugInfo *DebugInfo;
- /// IndirectBranch - The first time an indirect goto is seen we create a
- /// block with an indirect branch. Every time we see the address of a label
- /// taken, we add the label to the indirect goto. Every subsequent indirect
- /// goto is codegen'd as a jump to the IndirectBranch's basic block.
+ /// IndirectBranch - The first time an indirect goto is seen we create a block
+ /// with an indirect branch. Every time we see the address of a label taken,
+ /// we add the label to the indirect goto. Every subsequent indirect goto is
+ /// codegen'd as a jump to the IndirectBranch's basic block.
llvm::IndirectBrInst *IndirectBranch;
/// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
@@ -269,10 +317,15 @@ private:
/// BlockScopes - Map of which "cleanup scope" scope basic blocks have.
BlockScopeMap BlockScopes;
- /// CXXThisDecl - When parsing an C++ function, this will hold the implicit
- /// 'this' declaration.
+ /// CXXThisDecl - When generating code for a C++ member function,
+ /// this will hold the implicit 'this' declaration.
ImplicitParamDecl *CXXThisDecl;
+ /// CXXVTTDecl - When generating code for a base object constructor or
+ /// base object destructor with virtual bases, this will hold the implicit
+ /// VTT parameter.
+ ImplicitParamDecl *CXXVTTDecl;
+
/// CXXLiveTemporaryInfo - Holds information about a live C++ temporary.
struct CXXLiveTemporaryInfo {
/// Temporary - The live temporary.
@@ -284,9 +337,9 @@ private:
/// DtorBlock - The destructor block.
llvm::BasicBlock *DtorBlock;
- /// CondPtr - If this is a conditional temporary, this is the pointer to
- /// the condition variable that states whether the destructor should be
- /// called or not.
+ /// CondPtr - If this is a conditional temporary, this is the pointer to the
+ /// condition variable that states whether the destructor should be called
+ /// or not.
llvm::Value *CondPtr;
CXXLiveTemporaryInfo(const CXXTemporary *temporary,
@@ -298,10 +351,10 @@ private:
llvm::SmallVector<CXXLiveTemporaryInfo, 4> LiveTemporaries;
- /// ConditionalTempDestructionStack - Contains the number of live temporaries
- /// when PushConditionalTempDestruction was called. This is used so that
- /// we know how many temporaries were created by a certain expression.
- llvm::SmallVector<size_t, 4> ConditionalTempDestructionStack;
+ /// ConditionalBranchLevel - Contains the nesting level of the current
+ /// conditional branch. This is used so that we know if a temporary should be
+ /// destroyed conditionally.
+ unsigned ConditionalBranchLevel;
/// ByrefValueInfoMap - For each __block variable, contains a pair of the LLVM
@@ -384,15 +437,17 @@ public:
/// DynamicTypeAdjust - Do the non-virtual and virtual adjustments on an
/// object pointer to alter the dynamic type of the pointer. Used by
/// GenerateCovariantThunk for building thunks.
- llvm::Value *DynamicTypeAdjust(llvm::Value *V, int64_t nv, int64_t v);
+ llvm::Value *DynamicTypeAdjust(llvm::Value *V,
+ const ThunkAdjustment &Adjustment);
/// GenerateThunk - Generate a thunk for the given method
llvm::Constant *GenerateThunk(llvm::Function *Fn, const CXXMethodDecl *MD,
- bool Extern, int64_t nv, int64_t v);
- llvm::Constant *GenerateCovariantThunk(llvm::Function *Fn,
- const CXXMethodDecl *MD, bool Extern,
- int64_t nv_t, int64_t v_t,
- int64_t nv_r, int64_t v_r);
+ bool Extern,
+ const ThunkAdjustment &ThisAdjustment);
+ llvm::Constant *
+ GenerateCovariantThunk(llvm::Function *Fn, const CXXMethodDecl *MD,
+ bool Extern,
+ const CovariantThunkAdjustment &Adjustment);
void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type);
@@ -416,8 +471,8 @@ public:
const FunctionArgList &Args);
/// EmitDtorEpilogue - Emit all code that comes at the end of class's
- /// destructor. This is to call destructors on members and base classes
- /// in reverse order of their construction.
+ /// destructor. This is to call destructors on members and base classes in
+ /// reverse order of their construction.
void EmitDtorEpilogue(const CXXDestructorDecl *Dtor,
CXXDtorType Type);
@@ -461,9 +516,9 @@ public:
/// label maps to.
llvm::BasicBlock *getBasicBlockForLabel(const LabelStmt *S);
- /// SimplifyForwardingBlocks - If the given basic block is only a
- /// branch to another basic block, simplify it. This assumes that no
- /// other code could potentially reference the basic block.
+ /// SimplifyForwardingBlocks - If the given basic block is only a branch to
+ /// another basic block, simplify it. This assumes that no other code could
+ /// potentially reference the basic block.
void SimplifyForwardingBlocks(llvm::BasicBlock *BB);
/// EmitBlock - Emit the given block \arg BB and set it as the insert point,
@@ -579,9 +634,9 @@ public:
// instruction in LLVM instead once it works well enough.
llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty);
- // EmitVLASize - Generate code for any VLA size expressions that might occur
- // in a variably modified type. If Ty is a VLA, will return the value that
- // corresponds to the size in bytes of the VLA type. Will return 0 otherwise.
+ /// EmitVLASize - Generate code for any VLA size expressions that might occur
+ /// in a variably modified type. If Ty is a VLA, will return the value that
+ /// corresponds to the size in bytes of the VLA type. Will return 0 otherwise.
///
/// This function can be called with a null (unreachable) insert point.
llvm::Value *EmitVLASize(QualType Ty);
@@ -594,15 +649,20 @@ public:
/// generating code for an C++ member function.
llvm::Value *LoadCXXThis();
- /// GetAddressCXXOfBaseClass - This function will add the necessary delta
- /// to the load of 'this' and returns address of the base class.
+ /// GetAddressOfBaseClass - This function will add the necessary delta to the
+ /// load of 'this' and returns address of the base class.
// FIXME. This currently only does a derived to non-virtual base conversion.
// Other kinds of conversions will come later.
- llvm::Value *GetAddressCXXOfBaseClass(llvm::Value *BaseValue,
+ llvm::Value *GetAddressOfBaseClass(llvm::Value *Value,
+ const CXXRecordDecl *ClassDecl,
+ const CXXRecordDecl *BaseClassDecl,
+ bool NullCheckValue);
+
+ llvm::Value *GetAddressOfDerivedClass(llvm::Value *Value,
const CXXRecordDecl *ClassDecl,
- const CXXRecordDecl *BaseClassDecl,
+ const CXXRecordDecl *DerivedClassDecl,
bool NullCheckValue);
-
+
llvm::Value *
GetVirtualCXXBaseClassOffset(llvm::Value *This,
const CXXRecordDecl *ClassDecl,
@@ -637,10 +697,15 @@ public:
void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
const ConstantArrayType *ArrayTy,
- llvm::Value *ArrayPtr);
+ llvm::Value *ArrayPtr,
+ CallExpr::const_arg_iterator ArgBeg,
+ CallExpr::const_arg_iterator ArgEnd);
+
void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
llvm::Value *NumElements,
- llvm::Value *ArrayPtr);
+ llvm::Value *ArrayPtr,
+ CallExpr::const_arg_iterator ArgBeg,
+ CallExpr::const_arg_iterator ArgEnd);
void EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
const ArrayType *Array,
@@ -858,7 +923,6 @@ public:
LValue EmitBlockDeclRefLValue(const BlockDeclRefExpr *E);
- LValue EmitCXXConditionDeclLValue(const CXXConditionDeclExpr *E);
LValue EmitCXXConstructLValue(const CXXConstructExpr *E);
LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E);
LValue EmitCXXExprWithTemporariesLValue(const CXXExprWithTemporaries *E);
@@ -880,9 +944,8 @@ public:
/// result type, and using the given argument list which specifies both the
/// LLVM arguments and the types they were derived from.
///
- /// \param TargetDecl - If given, the decl of the function in a
- /// direct call; used to set attributes on the call (noreturn,
- /// etc.).
+ /// \param TargetDecl - If given, the decl of the function in a direct call;
+ /// used to set attributes on the call (noreturn, etc.).
RValue EmitCall(const CGFunctionInfo &FnInfo,
llvm::Value *Callee,
const CallArgList &Args,
@@ -994,15 +1057,14 @@ public:
/// LoadComplexFromAddr - Load a complex number from the specified address.
ComplexPairTy LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile);
- /// CreateStaticBlockVarDecl - Create a zero-initialized LLVM global
- /// for a static block var decl.
+ /// CreateStaticBlockVarDecl - Create a zero-initialized LLVM global for a
+ /// static block var decl.
llvm::GlobalVariable * CreateStaticBlockVarDecl(const VarDecl &D,
const char *Separator,
- llvm::GlobalValue::LinkageTypes
- Linkage);
+ llvm::GlobalValue::LinkageTypes Linkage);
- /// EmitStaticCXXBlockVarDeclInit - Create the initializer for a C++
- /// runtime initialized static block var decl.
+ /// EmitStaticCXXBlockVarDeclInit - Create the initializer for a C++ runtime
+ /// initialized static block var decl.
void EmitStaticCXXBlockVarDeclInit(const VarDecl &D,
llvm::GlobalVariable *GV);
OpenPOWER on IntegriCloud