//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This provides an abstract class for C++ code generation. Concrete subclasses // of this implement code generation for specific C++ ABIs. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_LIB_CIR_CIRGENCXXABI_H #define LLVM_CLANG_LIB_CIR_CIRGENCXXABI_H #include "CIRGenCall.h" #include "CIRGenFunction.h" #include "CIRGenModule.h" #include "clang/AST/Mangle.h" namespace clang::CIRGen { /// Implements C++ ABI-specific code generation functions. class CIRGenCXXABI { protected: CIRGenModule &cgm; std::unique_ptr mangleContext; public: // TODO(cir): make this protected when target-specific CIRGenCXXABIs are // implemented. CIRGenCXXABI(CIRGenModule &cgm) : cgm(cgm), mangleContext(cgm.getASTContext().createMangleContext()) {} virtual ~CIRGenCXXABI(); void setCXXABIThisValue(CIRGenFunction &cgf, mlir::Value thisPtr); /// Emit a single constructor/destructor with the gen type from a C++ /// constructor/destructor Decl. virtual void emitCXXStructor(clang::GlobalDecl gd) = 0; public: clang::ImplicitParamDecl *getThisDecl(CIRGenFunction &cgf) { return cgf.cxxabiThisDecl; } /// Emit the ABI-specific prolog for the function virtual void emitInstanceFunctionProlog(SourceLocation Loc, CIRGenFunction &cgf) = 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 clang::CXXRecordDecl * getThisArgumentTypeForMethod(const clang::CXXMethodDecl *md) { return md->getParent(); } /// Return whether the given global decl needs a VTT (virtual table table) /// parameter. virtual bool needsVTTParameter(clang::GlobalDecl gd) { return false; } /// Build a parameter variable suitable for 'this'. void buildThisParam(CIRGenFunction &cgf, FunctionArgList ¶ms); /// Loads the incoming C++ this pointer as it was passed by the caller. mlir::Value loadIncomingCXXThis(CIRGenFunction &cgf); /// Emit constructor variants required by this ABI. virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d) = 0; /// Emit dtor variants required by this ABI. virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d) = 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; virtual cir::GlobalLinkageKind getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const; /// 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 CIR generation does not support this case. virtual bool hasThisReturn(clang::GlobalDecl gd) const { return false; } virtual bool hasMostDerivedReturn(clang::GlobalDecl gd) const { return false; } /// Gets the mangle context. clang::MangleContext &getMangleContext() { return *mangleContext; } }; /// Creates and Itanium-family ABI CIRGenCXXABI *CreateCIRGenItaniumCXXABI(CIRGenModule &cgm); } // namespace clang::CIRGen #endif