diff options
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 178 |
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); |