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 ¶ms) {
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