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 d96c3551010e..7f3204587a95 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); | 
