diff options
Diffstat (limited to 'lib/CodeGen/CGCXXABI.h')
| -rw-r--r-- | lib/CodeGen/CGCXXABI.h | 157 | 
1 files changed, 136 insertions, 21 deletions
diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h index 1e4da631d6f6..9e9a2a7aaf9b 100644 --- a/lib/CodeGen/CGCXXABI.h +++ b/lib/CodeGen/CGCXXABI.h @@ -97,8 +97,12 @@ public:      return *MangleCtx;    } -  /// Returns true if the given instance method is one of the -  /// kinds that the ABI says returns 'this'. +  /// Returns true if the given constructor or destructor is one of the +  /// kinds that the ABI says returns 'this' (only applies when called +  /// non-virtually for destructors). +  /// +  /// There currently is no way to indicate if a destructor returns 'this' +  /// when called virtually, and code generation does not support the case.    virtual bool HasThisReturn(GlobalDecl GD) const { return false; }    /// Returns true if the given record type should be returned indirectly. @@ -192,6 +196,12 @@ protected:    /// is required.    llvm::Constant *getMemberPointerAdjustment(const CastExpr *E); +  /// \brief Computes the non-virtual adjustment needed for a member pointer +  /// conversion along an inheritance path stored in an APValue.  Unlike +  /// getMemberPointerAdjustment(), the adjustment can be negative if the path +  /// is from a derived type to a base type. +  CharUnits getMemberPointerPathAdjustment(const APValue &MP); +  public:    /// Adjust the given non-null pointer to an object of polymorphic    /// type to point to the complete object. @@ -202,11 +212,16 @@ public:                                                llvm::Value *ptr,                                                QualType type) = 0; +  virtual llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF, +                                                 llvm::Value *This, +                                                 const CXXRecordDecl *ClassDecl, +                                        const CXXRecordDecl *BaseClassDecl) = 0; +    /// Build the signature of the given constructor variant by adding -  /// any required parameters.  For convenience, ResTy has been -  /// initialized to 'void', and ArgTys has been initialized with the -  /// type of 'this' (although this may be changed by the ABI) and -  /// will have the formal parameters added to it afterwards. +  /// any required parameters.  For convenience, ArgTys has been initialized +  /// with the type of 'this' and ResTy has been initialized with the type of +  /// 'this' if HasThisReturn(GlobalDecl(Ctor, T)) is true or 'void' otherwise +  /// (although both may be changed by the ABI).    ///    /// If there are ever any ABIs where the implicit parameters are    /// intermixed with the formal parameters, we can address those @@ -216,46 +231,138 @@ public:                                           CanQualType &ResTy,                                 SmallVectorImpl<CanQualType> &ArgTys) = 0; -  virtual llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF); +  virtual llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, +                                                          const CXXRecordDecl *RD); + +  /// Emit the code to initialize hidden members required +  /// to handle virtual inheritance, if needed by the ABI. +  virtual void +  initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF, +                                            const CXXRecordDecl *RD) {} + +  /// Emit constructor variants required by this ABI. +  virtual void EmitCXXConstructors(const CXXConstructorDecl *D) = 0;    /// Build the signature of the given destructor variant by adding -  /// any required parameters.  For convenience, ResTy has been -  /// initialized to 'void' and ArgTys has been initialized with the -  /// type of 'this' (although this may be changed by the ABI). +  /// any required parameters.  For convenience, ArgTys has been initialized +  /// with the type of 'this' and ResTy has been initialized with the type of +  /// 'this' if HasThisReturn(GlobalDecl(Dtor, T)) is true or 'void' otherwise +  /// (although both may be changed by the ABI).    virtual void BuildDestructorSignature(const CXXDestructorDecl *Dtor,                                          CXXDtorType T,                                          CanQualType &ResTy,                                 SmallVectorImpl<CanQualType> &ArgTys) = 0; +  /// Returns true if the given destructor type should be emitted as a linkonce +  /// delegating thunk, regardless of whether the dtor is defined in this TU or +  /// not. +  virtual bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, +                                      CXXDtorType DT) const = 0; + +  /// Emit destructor variants required by this ABI. +  virtual void EmitCXXDestructors(const CXXDestructorDecl *D) = 0; + +  /// Get the type of the implicit "this" parameter used by a method. May return +  /// zero if no specific type is applicable, e.g. if the ABI expects the "this" +  /// parameter to point to some artificial offset in a complete object due to +  /// vbases being reordered. +  virtual const CXXRecordDecl * +  getThisArgumentTypeForMethod(const CXXMethodDecl *MD) { +    return MD->getParent(); +  } + +  /// Perform ABI-specific "this" argument adjustment required prior to +  /// a virtual function call. +  virtual llvm::Value *adjustThisArgumentForVirtualCall(CodeGenFunction &CGF, +                                                        GlobalDecl GD, +                                                        llvm::Value *This) { +    return This; +  } +    /// Build the ABI-specific portion of the parameter list for a    /// function.  This generally involves a 'this' parameter and    /// possibly some extra data for constructors and destructors.    ///    /// ABIs may also choose to override the return type, which has been -  /// initialized with the formal return type of the function. +  /// initialized with the type of 'this' if HasThisReturn(CGF.CurGD) is true or +  /// the formal return type of the function otherwise.    virtual void BuildInstanceFunctionParams(CodeGenFunction &CGF,                                             QualType &ResTy,                                             FunctionArgList &Params) = 0; +  /// Perform ABI-specific "this" parameter adjustment in a virtual function +  /// prologue. +  virtual llvm::Value *adjustThisParameterInVirtualFunctionPrologue( +      CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This) { +    return This; +  } +    /// Emit the ABI-specific prolog for the function.    virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF) = 0;    /// Emit the constructor call. Return the function that is called. -  virtual llvm::Value *EmitConstructorCall(CodeGenFunction &CGF, +  virtual void EmitConstructorCall(CodeGenFunction &CGF,                                     const CXXConstructorDecl *D, -                                   CXXCtorType Type, bool ForVirtualBase, -                                   bool Delegating, +                                   CXXCtorType Type, +                                   bool ForVirtualBase, bool Delegating,                                     llvm::Value *This,                                     CallExpr::const_arg_iterator ArgBeg,                                     CallExpr::const_arg_iterator ArgEnd) = 0; +  /// Emits the VTable definitions required for the given record type. +  virtual void emitVTableDefinitions(CodeGenVTables &CGVT, +                                     const CXXRecordDecl *RD) = 0; + +  /// Get the address point of the vtable for the given base subobject while +  /// building a constructor or a destructor. On return, NeedsVirtualOffset +  /// tells if a virtual base adjustment is needed in order to get the offset +  /// of the base subobject. +  virtual llvm::Value *getVTableAddressPointInStructor( +      CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base, +      const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) = 0; + +  /// Get the address point of the vtable for the given base subobject while +  /// building a constexpr. +  virtual llvm::Constant * +  getVTableAddressPointForConstExpr(BaseSubobject Base, +                                    const CXXRecordDecl *VTableClass) = 0; + +  /// Get the address of the vtable for the given record decl which should be +  /// used for the vptr at the given offset in RD. +  virtual llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, +                                                CharUnits VPtrOffset) = 0; + +  /// Build a virtual function pointer in the ABI-specific way. +  virtual llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, +                                                 GlobalDecl GD, +                                                 llvm::Value *This, +                                                 llvm::Type *Ty) = 0; +    /// Emit the ABI-specific virtual destructor call. -  virtual RValue EmitVirtualDestructorCall(CodeGenFunction &CGF, -                                           const CXXDestructorDecl *Dtor, -                                           CXXDtorType DtorType, -                                           SourceLocation CallLoc, -                                           ReturnValueSlot ReturnValue, -                                           llvm::Value *This) = 0; +  virtual void EmitVirtualDestructorCall(CodeGenFunction &CGF, +                                         const CXXDestructorDecl *Dtor, +                                         CXXDtorType DtorType, +                                         SourceLocation CallLoc, +                                         llvm::Value *This) = 0; + +  virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, +                                                GlobalDecl GD, +                                                CallArgList &CallArgs) {} + +  /// Emit any tables needed to implement virtual inheritance.  For Itanium, +  /// this emits virtual table tables.  For the MSVC++ ABI, this emits virtual +  /// base tables. +  virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD) = 0; + +  virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) = 0; + +  virtual llvm::Value *performThisAdjustment(CodeGenFunction &CGF, +                                             llvm::Value *This, +                                             const ThisAdjustment &TA) = 0; + +  virtual llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, +                                               llvm::Value *Ret, +                                               const ReturnAdjustment &RA) = 0;    virtual void EmitReturnFromThunk(CodeGenFunction &CGF,                                     RValue RV, QualType ResultType); @@ -266,6 +373,10 @@ public:    /// Gets the deleted virtual member call name.    virtual StringRef GetDeletedVirtualCallName() = 0; +  /// \brief Returns true iff static data members that are initialized in the +  /// class definition should have linkonce linkage. +  virtual bool isInlineInitializedStaticDataMemberLinkOnce() { return false; } +    /**************************** Array cookies ******************************/    /// Returns the extra size required in order to store the array @@ -312,6 +423,9 @@ public:                                 QualType ElementType, llvm::Value *&NumElements,                                 llvm::Value *&AllocPtr, CharUnits &CookieSize); +  /// Return whether the given global decl needs a VTT parameter. +  virtual bool NeedsVTTParameter(GlobalDecl GD); +  protected:    /// Returns the extra size required in order to store the array    /// cookie for the given type.  Assumes that an array cookie is @@ -344,7 +458,8 @@ public:    ///   - a static local variable    ///   - a static data member of a class template instantiation    virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, -                               llvm::GlobalVariable *DeclPtr, bool PerformInit); +                               llvm::GlobalVariable *DeclPtr, +                               bool PerformInit) = 0;    /// Emit code to force the execution of a destructor during global    /// teardown.  The default implementation of this uses atexit.  | 
