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