xref: /freebsd-src/contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===----- CGCXXABI.cpp - Interface to C++ ABIs ---------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This provides an abstract class for C++ code generation. Concrete subclasses
100b57cec5SDimitry Andric // of this implement code generation for specific C++ ABIs.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "CGCXXABI.h"
150b57cec5SDimitry Andric #include "CGCleanup.h"
16480093f4SDimitry Andric #include "clang/AST/Attr.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric using namespace clang;
190b57cec5SDimitry Andric using namespace CodeGen;
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric CGCXXABI::~CGCXXABI() { }
220b57cec5SDimitry Andric 
23*0fca6ea1SDimitry Andric Address CGCXXABI::getThisAddress(CodeGenFunction &CGF) {
24*0fca6ea1SDimitry Andric   return CGF.makeNaturalAddressForPointer(
25*0fca6ea1SDimitry Andric       CGF.CXXABIThisValue, CGF.CXXABIThisDecl->getType()->getPointeeType(),
26*0fca6ea1SDimitry Andric       CGF.CXXABIThisAlignment);
27*0fca6ea1SDimitry Andric }
28*0fca6ea1SDimitry Andric 
290b57cec5SDimitry Andric void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) {
300b57cec5SDimitry Andric   DiagnosticsEngine &Diags = CGF.CGM.getDiags();
310b57cec5SDimitry Andric   unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
320b57cec5SDimitry Andric                                           "cannot yet compile %0 in this ABI");
330b57cec5SDimitry Andric   Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()),
340b57cec5SDimitry Andric                DiagID)
350b57cec5SDimitry Andric     << S;
360b57cec5SDimitry Andric }
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {
390b57cec5SDimitry Andric   return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T));
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric llvm::Type *
430b57cec5SDimitry Andric CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
440b57cec5SDimitry Andric   return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer(
480b57cec5SDimitry Andric     CodeGenFunction &CGF, const Expr *E, Address This,
490b57cec5SDimitry Andric     llvm::Value *&ThisPtrForCall,
500b57cec5SDimitry Andric     llvm::Value *MemPtr, const MemberPointerType *MPT) {
510b57cec5SDimitry Andric   ErrorUnsupportedABI(CGF, "calls through member pointers");
520b57cec5SDimitry Andric 
53*0fca6ea1SDimitry Andric   const auto *RD =
54*0fca6ea1SDimitry Andric       cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
55*0fca6ea1SDimitry Andric   ThisPtrForCall =
56*0fca6ea1SDimitry Andric       CGF.getAsNaturalPointerTo(This, CGF.getContext().getRecordType(RD));
57*0fca6ea1SDimitry Andric   const FunctionProtoType *FPT =
58*0fca6ea1SDimitry Andric       MPT->getPointeeType()->getAs<FunctionProtoType>();
5906c3fb27SDimitry Andric   llvm::Constant *FnPtr = llvm::Constant::getNullValue(
6006c3fb27SDimitry Andric       llvm::PointerType::getUnqual(CGM.getLLVMContext()));
610b57cec5SDimitry Andric   return CGCallee::forDirect(FnPtr, FPT);
620b57cec5SDimitry Andric }
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric llvm::Value *
650b57cec5SDimitry Andric CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
660b57cec5SDimitry Andric                                        Address Base, llvm::Value *MemPtr,
670b57cec5SDimitry Andric                                        const MemberPointerType *MPT) {
680b57cec5SDimitry Andric   ErrorUnsupportedABI(CGF, "loads of member pointers");
6906c3fb27SDimitry Andric   llvm::Type *Ty =
7006c3fb27SDimitry Andric       llvm::PointerType::get(CGF.getLLVMContext(), Base.getAddressSpace());
710b57cec5SDimitry Andric   return llvm::Constant::getNullValue(Ty);
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
750b57cec5SDimitry Andric                                                    const CastExpr *E,
760b57cec5SDimitry Andric                                                    llvm::Value *Src) {
770b57cec5SDimitry Andric   ErrorUnsupportedABI(CGF, "member function pointer conversions");
780b57cec5SDimitry Andric   return GetBogusMemberPointer(E->getType());
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E,
820b57cec5SDimitry Andric                                                       llvm::Constant *Src) {
830b57cec5SDimitry Andric   return GetBogusMemberPointer(E->getType());
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric llvm::Value *
870b57cec5SDimitry Andric CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
880b57cec5SDimitry Andric                                       llvm::Value *L,
890b57cec5SDimitry Andric                                       llvm::Value *R,
900b57cec5SDimitry Andric                                       const MemberPointerType *MPT,
910b57cec5SDimitry Andric                                       bool Inequality) {
920b57cec5SDimitry Andric   ErrorUnsupportedABI(CGF, "member function pointer comparison");
930b57cec5SDimitry Andric   return CGF.Builder.getFalse();
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric llvm::Value *
970b57cec5SDimitry Andric CGCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
980b57cec5SDimitry Andric                                      llvm::Value *MemPtr,
990b57cec5SDimitry Andric                                      const MemberPointerType *MPT) {
1000b57cec5SDimitry Andric   ErrorUnsupportedABI(CGF, "member function pointer null testing");
1010b57cec5SDimitry Andric   return CGF.Builder.getFalse();
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric llvm::Constant *
1050b57cec5SDimitry Andric CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
1060b57cec5SDimitry Andric   return GetBogusMemberPointer(QualType(MPT, 0));
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric llvm::Constant *CGCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
1100b57cec5SDimitry Andric   return GetBogusMemberPointer(CGM.getContext().getMemberPointerType(
1110b57cec5SDimitry Andric       MD->getType(), MD->getParent()->getTypeForDecl()));
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
1150b57cec5SDimitry Andric                                                 CharUnits offset) {
1160b57cec5SDimitry Andric   return GetBogusMemberPointer(QualType(MPT, 0));
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric llvm::Constant *CGCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) {
1200b57cec5SDimitry Andric   return GetBogusMemberPointer(MPT);
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric bool CGCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
1240b57cec5SDimitry Andric   // Fake answer.
1250b57cec5SDimitry Andric   return true;
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList &params) {
1290b57cec5SDimitry Andric   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   // FIXME: I'm not entirely sure I like using a fake decl just for code
1320b57cec5SDimitry Andric   // generation. Maybe we can come up with a better way?
1335f757f3fSDimitry Andric   auto *ThisDecl =
1345f757f3fSDimitry Andric       ImplicitParamDecl::Create(CGM.getContext(), nullptr, MD->getLocation(),
1355f757f3fSDimitry Andric                                 &CGM.getContext().Idents.get("this"),
1365f757f3fSDimitry Andric                                 MD->getThisType(), ImplicitParamKind::CXXThis);
1370b57cec5SDimitry Andric   params.push_back(ThisDecl);
1380b57cec5SDimitry Andric   CGF.CXXABIThisDecl = ThisDecl;
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   // Compute the presumed alignment of 'this', which basically comes
1410b57cec5SDimitry Andric   // down to whether we know it's a complete object or not.
1420b57cec5SDimitry Andric   auto &Layout = CGF.getContext().getASTRecordLayout(MD->getParent());
1430b57cec5SDimitry Andric   if (MD->getParent()->getNumVBases() == 0 || // avoid vcall in common case
144e8d8bef9SDimitry Andric       MD->getParent()->isEffectivelyFinal() ||
145e8d8bef9SDimitry Andric       isThisCompleteObject(CGF.CurGD)) {
1460b57cec5SDimitry Andric     CGF.CXXABIThisAlignment = Layout.getAlignment();
1470b57cec5SDimitry Andric   } else {
1480b57cec5SDimitry Andric     CGF.CXXABIThisAlignment = Layout.getNonVirtualAlignment();
1490b57cec5SDimitry Andric   }
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric llvm::Value *CGCXXABI::loadIncomingCXXThis(CodeGenFunction &CGF) {
1530b57cec5SDimitry Andric   return CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)),
1540b57cec5SDimitry Andric                                 "this");
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric void CGCXXABI::setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr) {
1580b57cec5SDimitry Andric   /// Initialize the 'this' slot.
1590b57cec5SDimitry Andric   assert(getThisDecl(CGF) && "no 'this' variable for function");
1600b57cec5SDimitry Andric   CGF.CXXABIThisValue = ThisPtr;
1610b57cec5SDimitry Andric }
1620b57cec5SDimitry Andric 
16304eeddc0SDimitry Andric bool CGCXXABI::mayNeedDestruction(const VarDecl *VD) const {
16404eeddc0SDimitry Andric   if (VD->needsDestruction(getContext()))
16504eeddc0SDimitry Andric     return true;
16604eeddc0SDimitry Andric 
16704eeddc0SDimitry Andric   // If the variable has an incomplete class type (or array thereof), it
16804eeddc0SDimitry Andric   // might need destruction.
16904eeddc0SDimitry Andric   const Type *T = VD->getType()->getBaseElementTypeUnsafe();
17004eeddc0SDimitry Andric   if (T->getAs<RecordType>() && T->isIncompleteType())
17104eeddc0SDimitry Andric     return true;
17204eeddc0SDimitry Andric 
17304eeddc0SDimitry Andric   return false;
17404eeddc0SDimitry Andric }
17504eeddc0SDimitry Andric 
17604eeddc0SDimitry Andric bool CGCXXABI::isEmittedWithConstantInitializer(
17704eeddc0SDimitry Andric     const VarDecl *VD, bool InspectInitForWeakDef) const {
17804eeddc0SDimitry Andric   VD = VD->getMostRecentDecl();
17904eeddc0SDimitry Andric   if (VD->hasAttr<ConstInitAttr>())
18004eeddc0SDimitry Andric     return true;
18104eeddc0SDimitry Andric 
18204eeddc0SDimitry Andric   // All later checks examine the initializer specified on the variable. If
18304eeddc0SDimitry Andric   // the variable is weak, such examination would not be correct.
18404eeddc0SDimitry Andric   if (!InspectInitForWeakDef && (VD->isWeak() || VD->hasAttr<SelectAnyAttr>()))
18504eeddc0SDimitry Andric     return false;
18604eeddc0SDimitry Andric 
18704eeddc0SDimitry Andric   const VarDecl *InitDecl = VD->getInitializingDeclaration();
18804eeddc0SDimitry Andric   if (!InitDecl)
18904eeddc0SDimitry Andric     return false;
19004eeddc0SDimitry Andric 
19104eeddc0SDimitry Andric   // If there's no initializer to run, this is constant initialization.
19204eeddc0SDimitry Andric   if (!InitDecl->hasInit())
19304eeddc0SDimitry Andric     return true;
19404eeddc0SDimitry Andric 
19504eeddc0SDimitry Andric   // If we have the only definition, we don't need a thread wrapper if we
19604eeddc0SDimitry Andric   // will emit the value as a constant.
19704eeddc0SDimitry Andric   if (isUniqueGVALinkage(getContext().GetGVALinkageForVariable(VD)))
19804eeddc0SDimitry Andric     return !mayNeedDestruction(VD) && InitDecl->evaluateValue();
19904eeddc0SDimitry Andric 
20004eeddc0SDimitry Andric   // Otherwise, we need a thread wrapper unless we know that every
20104eeddc0SDimitry Andric   // translation unit will emit the value as a constant. We rely on the
20204eeddc0SDimitry Andric   // variable being constant-initialized in every translation unit if it's
20304eeddc0SDimitry Andric   // constant-initialized in any translation unit, which isn't actually
20404eeddc0SDimitry Andric   // guaranteed by the standard but is necessary for sanity.
20504eeddc0SDimitry Andric   return InitDecl->hasConstantInitialization();
20604eeddc0SDimitry Andric }
20704eeddc0SDimitry Andric 
2080b57cec5SDimitry Andric void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
2090b57cec5SDimitry Andric                                    RValue RV, QualType ResultType) {
2105ffd83dbSDimitry Andric   assert(!CGF.hasAggregateEvaluationKind(ResultType) &&
2115ffd83dbSDimitry Andric          "cannot handle aggregates");
2120b57cec5SDimitry Andric   CGF.EmitReturnOfRValue(RV, ResultType);
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
2160b57cec5SDimitry Andric   if (!requiresArrayCookie(expr))
2170b57cec5SDimitry Andric     return CharUnits::Zero();
2180b57cec5SDimitry Andric   return getArrayCookieSizeImpl(expr->getAllocatedType());
2190b57cec5SDimitry Andric }
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric CharUnits CGCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2220b57cec5SDimitry Andric   // BOGUS
2230b57cec5SDimitry Andric   return CharUnits::Zero();
2240b57cec5SDimitry Andric }
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric Address CGCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2270b57cec5SDimitry Andric                                         Address NewPtr,
2280b57cec5SDimitry Andric                                         llvm::Value *NumElements,
2290b57cec5SDimitry Andric                                         const CXXNewExpr *expr,
2300b57cec5SDimitry Andric                                         QualType ElementType) {
2310b57cec5SDimitry Andric   // Should never be called.
2320b57cec5SDimitry Andric   ErrorUnsupportedABI(CGF, "array cookie initialization");
2330b57cec5SDimitry Andric   return Address::invalid();
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric bool CGCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
2370b57cec5SDimitry Andric                                    QualType elementType) {
2380b57cec5SDimitry Andric   // If the class's usual deallocation function takes two arguments,
2390b57cec5SDimitry Andric   // it needs a cookie.
2400b57cec5SDimitry Andric   if (expr->doesUsualArrayDeleteWantSize())
2410b57cec5SDimitry Andric     return true;
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric   return elementType.isDestructedType();
2440b57cec5SDimitry Andric }
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric bool CGCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
2470b57cec5SDimitry Andric   // If the class's usual deallocation function takes two arguments,
2480b57cec5SDimitry Andric   // it needs a cookie.
2490b57cec5SDimitry Andric   if (expr->doesUsualArrayDeleteWantSize())
2500b57cec5SDimitry Andric     return true;
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   return expr->getAllocatedType().isDestructedType();
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr,
2560b57cec5SDimitry Andric                                const CXXDeleteExpr *expr, QualType eltTy,
2570b57cec5SDimitry Andric                                llvm::Value *&numElements,
2580b57cec5SDimitry Andric                                llvm::Value *&allocPtr, CharUnits &cookieSize) {
2590b57cec5SDimitry Andric   // Derive a char* in the same address space as the pointer.
26006c3fb27SDimitry Andric   ptr = ptr.withElementType(CGF.Int8Ty);
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric   // If we don't need an array cookie, bail out early.
2630b57cec5SDimitry Andric   if (!requiresArrayCookie(expr, eltTy)) {
264*0fca6ea1SDimitry Andric     allocPtr = ptr.emitRawPointer(CGF);
2650b57cec5SDimitry Andric     numElements = nullptr;
2660b57cec5SDimitry Andric     cookieSize = CharUnits::Zero();
2670b57cec5SDimitry Andric     return;
2680b57cec5SDimitry Andric   }
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric   cookieSize = getArrayCookieSizeImpl(eltTy);
271*0fca6ea1SDimitry Andric   Address allocAddr = CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize);
272*0fca6ea1SDimitry Andric   allocPtr = allocAddr.emitRawPointer(CGF);
2730b57cec5SDimitry Andric   numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize);
2740b57cec5SDimitry Andric }
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2770b57cec5SDimitry Andric                                            Address ptr,
2780b57cec5SDimitry Andric                                            CharUnits cookieSize) {
2790b57cec5SDimitry Andric   ErrorUnsupportedABI(CGF, "reading a new[] cookie");
2800b57cec5SDimitry Andric   return llvm::ConstantInt::get(CGF.SizeTy, 0);
2810b57cec5SDimitry Andric }
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric /// Returns the adjustment, in bytes, required for the given
2840b57cec5SDimitry Andric /// member-pointer operation.  Returns null if no adjustment is
2850b57cec5SDimitry Andric /// required.
2860b57cec5SDimitry Andric llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
2870b57cec5SDimitry Andric   assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
2880b57cec5SDimitry Andric          E->getCastKind() == CK_BaseToDerivedMemberPointer);
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric   QualType derivedType;
2910b57cec5SDimitry Andric   if (E->getCastKind() == CK_DerivedToBaseMemberPointer)
2920b57cec5SDimitry Andric     derivedType = E->getSubExpr()->getType();
2930b57cec5SDimitry Andric   else
2940b57cec5SDimitry Andric     derivedType = E->getType();
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   const CXXRecordDecl *derivedClass =
2970b57cec5SDimitry Andric     derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   return CGM.GetNonVirtualBaseClassOffset(derivedClass,
3000b57cec5SDimitry Andric                                           E->path_begin(),
3010b57cec5SDimitry Andric                                           E->path_end());
3020b57cec5SDimitry Andric }
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric llvm::BasicBlock *
3050b57cec5SDimitry Andric CGCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
3060b57cec5SDimitry Andric                                         const CXXRecordDecl *RD) {
3070b57cec5SDimitry Andric   if (CGM.getTarget().getCXXABI().hasConstructorVariants())
3080b57cec5SDimitry Andric     llvm_unreachable("shouldn't be called in this ABI");
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   ErrorUnsupportedABI(CGF, "complete object detection in ctor");
3110b57cec5SDimitry Andric   return nullptr;
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric void CGCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
3150b57cec5SDimitry Andric                                           const CXXDestructorDecl *Dtor,
3160b57cec5SDimitry Andric                                           CXXDtorType DT) const {
3170b57cec5SDimitry Andric   // Assume the base C++ ABI has no special rules for destructor variants.
3180b57cec5SDimitry Andric   CGM.setDLLImportDLLExport(GV, Dtor);
3190b57cec5SDimitry Andric }
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes CGCXXABI::getCXXDestructorLinkage(
3220b57cec5SDimitry Andric     GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const {
3230b57cec5SDimitry Andric   // Delegate back to CGM by default.
3248a4dda33SDimitry Andric   return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage);
3250b57cec5SDimitry Andric }
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
3280b57cec5SDimitry Andric   return false;
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric llvm::CallInst *
3320b57cec5SDimitry Andric CGCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
3330b57cec5SDimitry Andric                                               llvm::Value *Exn) {
3340b57cec5SDimitry Andric   // Just call std::terminate and ignore the violating exception.
3350b57cec5SDimitry Andric   return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn());
3360b57cec5SDimitry Andric }
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric CatchTypeInfo CGCXXABI::getCatchAllTypeInfo() {
3390b57cec5SDimitry Andric   return CatchTypeInfo{nullptr, 0};
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric std::vector<CharUnits> CGCXXABI::getVBPtrOffsets(const CXXRecordDecl *RD) {
3430b57cec5SDimitry Andric   return std::vector<CharUnits>();
3440b57cec5SDimitry Andric }
3455ffd83dbSDimitry Andric 
3465ffd83dbSDimitry Andric CGCXXABI::AddedStructorArgCounts CGCXXABI::addImplicitConstructorArgs(
3475ffd83dbSDimitry Andric     CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
3485ffd83dbSDimitry Andric     bool ForVirtualBase, bool Delegating, CallArgList &Args) {
3495ffd83dbSDimitry Andric   AddedStructorArgs AddedArgs =
3505ffd83dbSDimitry Andric       getImplicitConstructorArgs(CGF, D, Type, ForVirtualBase, Delegating);
3515ffd83dbSDimitry Andric   for (size_t i = 0; i < AddedArgs.Prefix.size(); ++i) {
3525ffd83dbSDimitry Andric     Args.insert(Args.begin() + 1 + i,
3535ffd83dbSDimitry Andric                 CallArg(RValue::get(AddedArgs.Prefix[i].Value),
3545ffd83dbSDimitry Andric                         AddedArgs.Prefix[i].Type));
3555ffd83dbSDimitry Andric   }
3565ffd83dbSDimitry Andric   for (const auto &arg : AddedArgs.Suffix) {
3575ffd83dbSDimitry Andric     Args.add(RValue::get(arg.Value), arg.Type);
3585ffd83dbSDimitry Andric   }
3595ffd83dbSDimitry Andric   return AddedStructorArgCounts(AddedArgs.Prefix.size(),
3605ffd83dbSDimitry Andric                                 AddedArgs.Suffix.size());
3615ffd83dbSDimitry Andric }
362