xref: /freebsd/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric //
9*700637cbSDimitry Andric // This provides an abstract class for C++ code generation. Concrete subclasses
10*700637cbSDimitry Andric // of this implement code generation for specific C++ ABIs.
11*700637cbSDimitry Andric //
12*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
13*700637cbSDimitry Andric 
14*700637cbSDimitry Andric #include "CIRGenCXXABI.h"
15*700637cbSDimitry Andric #include "CIRGenFunction.h"
16*700637cbSDimitry Andric 
17*700637cbSDimitry Andric #include "clang/AST/Decl.h"
18*700637cbSDimitry Andric #include "clang/AST/GlobalDecl.h"
19*700637cbSDimitry Andric 
20*700637cbSDimitry Andric using namespace clang;
21*700637cbSDimitry Andric using namespace clang::CIRGen;
22*700637cbSDimitry Andric 
~CIRGenCXXABI()23*700637cbSDimitry Andric CIRGenCXXABI::~CIRGenCXXABI() {}
24*700637cbSDimitry Andric 
buildThisParam(CIRGenFunction & cgf,FunctionArgList & params)25*700637cbSDimitry Andric void CIRGenCXXABI::buildThisParam(CIRGenFunction &cgf,
26*700637cbSDimitry Andric                                   FunctionArgList &params) {
27*700637cbSDimitry Andric   const auto *md = cast<CXXMethodDecl>(cgf.curGD.getDecl());
28*700637cbSDimitry Andric 
29*700637cbSDimitry Andric   // FIXME: I'm not entirely sure I like using a fake decl just for code
30*700637cbSDimitry Andric   // generation. Maybe we can come up with a better way?
31*700637cbSDimitry Andric   auto *thisDecl =
32*700637cbSDimitry Andric       ImplicitParamDecl::Create(cgm.getASTContext(), nullptr, md->getLocation(),
33*700637cbSDimitry Andric                                 &cgm.getASTContext().Idents.get("this"),
34*700637cbSDimitry Andric                                 md->getThisType(), ImplicitParamKind::CXXThis);
35*700637cbSDimitry Andric   params.push_back(thisDecl);
36*700637cbSDimitry Andric   cgf.cxxabiThisDecl = thisDecl;
37*700637cbSDimitry Andric 
38*700637cbSDimitry Andric   // Classic codegen computes the alignment of thisDecl and saves it in
39*700637cbSDimitry Andric   // CodeGenFunction::CXXABIThisAlignment, but it is only used in emitTypeCheck
40*700637cbSDimitry Andric   // in CodeGenFunction::StartFunction().
41*700637cbSDimitry Andric   assert(!cir::MissingFeatures::cxxabiThisAlignment());
42*700637cbSDimitry Andric }
43*700637cbSDimitry Andric 
getCXXDestructorLinkage(GVALinkage linkage,const CXXDestructorDecl * dtor,CXXDtorType dt) const44*700637cbSDimitry Andric cir::GlobalLinkageKind CIRGenCXXABI::getCXXDestructorLinkage(
45*700637cbSDimitry Andric     GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const {
46*700637cbSDimitry Andric   // Delegate back to cgm by default.
47*700637cbSDimitry Andric   return cgm.getCIRLinkageForDeclarator(dtor, linkage,
48*700637cbSDimitry Andric                                         /*isConstantVariable=*/false);
49*700637cbSDimitry Andric }
50*700637cbSDimitry Andric 
loadIncomingCXXThis(CIRGenFunction & cgf)51*700637cbSDimitry Andric mlir::Value CIRGenCXXABI::loadIncomingCXXThis(CIRGenFunction &cgf) {
52*700637cbSDimitry Andric   ImplicitParamDecl *vd = getThisDecl(cgf);
53*700637cbSDimitry Andric   Address addr = cgf.getAddrOfLocalVar(vd);
54*700637cbSDimitry Andric   return cgf.getBuilder().create<cir::LoadOp>(
55*700637cbSDimitry Andric       cgf.getLoc(vd->getLocation()), addr.getElementType(), addr.getPointer());
56*700637cbSDimitry Andric }
57*700637cbSDimitry Andric 
setCXXABIThisValue(CIRGenFunction & cgf,mlir::Value thisPtr)58*700637cbSDimitry Andric void CIRGenCXXABI::setCXXABIThisValue(CIRGenFunction &cgf,
59*700637cbSDimitry Andric                                       mlir::Value thisPtr) {
60*700637cbSDimitry Andric   /// Initialize the 'this' slot.
61*700637cbSDimitry Andric   assert(getThisDecl(cgf) && "no 'this' variable for function");
62*700637cbSDimitry Andric   cgf.cxxabiThisValue = thisPtr;
63*700637cbSDimitry Andric }
64