1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This provides an abstract class for C++ code generation. Concrete subclasses 10 // of this implement code generation for specific C++ ABIs. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_LIB_CIR_CIRGENCXXABI_H 15 #define LLVM_CLANG_LIB_CIR_CIRGENCXXABI_H 16 17 #include "CIRGenCall.h" 18 #include "CIRGenFunction.h" 19 #include "CIRGenModule.h" 20 21 #include "clang/AST/Mangle.h" 22 23 namespace clang::CIRGen { 24 25 /// Implements C++ ABI-specific code generation functions. 26 class CIRGenCXXABI { 27 protected: 28 CIRGenModule &cgm; 29 std::unique_ptr<clang::MangleContext> mangleContext; 30 31 public: 32 // TODO(cir): make this protected when target-specific CIRGenCXXABIs are 33 // implemented. CIRGenCXXABI(CIRGenModule & cgm)34 CIRGenCXXABI(CIRGenModule &cgm) 35 : cgm(cgm), mangleContext(cgm.getASTContext().createMangleContext()) {} 36 virtual ~CIRGenCXXABI(); 37 38 void setCXXABIThisValue(CIRGenFunction &cgf, mlir::Value thisPtr); 39 40 /// Emit a single constructor/destructor with the gen type from a C++ 41 /// constructor/destructor Decl. 42 virtual void emitCXXStructor(clang::GlobalDecl gd) = 0; 43 44 public: getThisDecl(CIRGenFunction & cgf)45 clang::ImplicitParamDecl *getThisDecl(CIRGenFunction &cgf) { 46 return cgf.cxxabiThisDecl; 47 } 48 49 /// Emit the ABI-specific prolog for the function 50 virtual void emitInstanceFunctionProlog(SourceLocation Loc, 51 CIRGenFunction &cgf) = 0; 52 53 /// Get the type of the implicit "this" parameter used by a method. May return 54 /// zero if no specific type is applicable, e.g. if the ABI expects the "this" 55 /// parameter to point to some artificial offset in a complete object due to 56 /// vbases being reordered. 57 virtual const clang::CXXRecordDecl * getThisArgumentTypeForMethod(const clang::CXXMethodDecl * md)58 getThisArgumentTypeForMethod(const clang::CXXMethodDecl *md) { 59 return md->getParent(); 60 } 61 62 /// Return whether the given global decl needs a VTT (virtual table table) 63 /// parameter. needsVTTParameter(clang::GlobalDecl gd)64 virtual bool needsVTTParameter(clang::GlobalDecl gd) { return false; } 65 66 /// Build a parameter variable suitable for 'this'. 67 void buildThisParam(CIRGenFunction &cgf, FunctionArgList ¶ms); 68 69 /// Loads the incoming C++ this pointer as it was passed by the caller. 70 mlir::Value loadIncomingCXXThis(CIRGenFunction &cgf); 71 72 /// Emit constructor variants required by this ABI. 73 virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d) = 0; 74 75 /// Emit dtor variants required by this ABI. 76 virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d) = 0; 77 78 /// Returns true if the given destructor type should be emitted as a linkonce 79 /// delegating thunk, regardless of whether the dtor is defined in this TU or 80 /// not. 81 virtual bool useThunkForDtorVariant(const CXXDestructorDecl *dtor, 82 CXXDtorType dt) const = 0; 83 84 virtual cir::GlobalLinkageKind 85 getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, 86 CXXDtorType dt) const; 87 88 /// Returns true if the given constructor or destructor is one of the kinds 89 /// that the ABI says returns 'this' (only applies when called non-virtually 90 /// for destructors). 91 /// 92 /// There currently is no way to indicate if a destructor returns 'this' when 93 /// called virtually, and CIR generation does not support this case. hasThisReturn(clang::GlobalDecl gd)94 virtual bool hasThisReturn(clang::GlobalDecl gd) const { return false; } 95 hasMostDerivedReturn(clang::GlobalDecl gd)96 virtual bool hasMostDerivedReturn(clang::GlobalDecl gd) const { 97 return false; 98 } 99 100 /// Gets the mangle context. getMangleContext()101 clang::MangleContext &getMangleContext() { return *mangleContext; } 102 }; 103 104 /// Creates and Itanium-family ABI 105 CIRGenCXXABI *CreateCIRGenItaniumCXXABI(CIRGenModule &cgm); 106 107 } // namespace clang::CIRGen 108 109 #endif 110