1 //===----- CGCXXABI.cpp - Interface to C++ ABIs ---------------------------===// 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 #include "CGCXXABI.h" 15 #include "CGCleanup.h" 16 17 using namespace clang; 18 using namespace CodeGen; 19 20 CGCXXABI::~CGCXXABI() { } 21 22 void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) { 23 DiagnosticsEngine &Diags = CGF.CGM.getDiags(); 24 unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, 25 "cannot yet compile %0 in this ABI"); 26 Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()), 27 DiagID) 28 << S; 29 } 30 31 bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) const { 32 // We can only copy the argument if there exists at least one trivial, 33 // non-deleted copy or move constructor. 34 return RD->canPassInRegisters(); 35 } 36 37 llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) { 38 return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T)); 39 } 40 41 llvm::Type * 42 CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { 43 return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType()); 44 } 45 46 CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer( 47 CodeGenFunction &CGF, const Expr *E, Address This, 48 llvm::Value *&ThisPtrForCall, 49 llvm::Value *MemPtr, const MemberPointerType *MPT) { 50 ErrorUnsupportedABI(CGF, "calls through member pointers"); 51 52 ThisPtrForCall = This.getPointer(); 53 const FunctionProtoType *FPT = 54 MPT->getPointeeType()->getAs<FunctionProtoType>(); 55 const CXXRecordDecl *RD = 56 cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl()); 57 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType( 58 CGM.getTypes().arrangeCXXMethodType(RD, FPT, /*FD=*/nullptr)); 59 llvm::Constant *FnPtr = llvm::Constant::getNullValue(FTy->getPointerTo()); 60 return CGCallee::forDirect(FnPtr, FPT); 61 } 62 63 llvm::Value * 64 CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, 65 Address Base, llvm::Value *MemPtr, 66 const MemberPointerType *MPT) { 67 ErrorUnsupportedABI(CGF, "loads of member pointers"); 68 llvm::Type *Ty = CGF.ConvertType(MPT->getPointeeType()) 69 ->getPointerTo(Base.getAddressSpace()); 70 return llvm::Constant::getNullValue(Ty); 71 } 72 73 llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, 74 const CastExpr *E, 75 llvm::Value *Src) { 76 ErrorUnsupportedABI(CGF, "member function pointer conversions"); 77 return GetBogusMemberPointer(E->getType()); 78 } 79 80 llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E, 81 llvm::Constant *Src) { 82 return GetBogusMemberPointer(E->getType()); 83 } 84 85 llvm::Value * 86 CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, 87 llvm::Value *L, 88 llvm::Value *R, 89 const MemberPointerType *MPT, 90 bool Inequality) { 91 ErrorUnsupportedABI(CGF, "member function pointer comparison"); 92 return CGF.Builder.getFalse(); 93 } 94 95 llvm::Value * 96 CGCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 97 llvm::Value *MemPtr, 98 const MemberPointerType *MPT) { 99 ErrorUnsupportedABI(CGF, "member function pointer null testing"); 100 return CGF.Builder.getFalse(); 101 } 102 103 llvm::Constant * 104 CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { 105 return GetBogusMemberPointer(QualType(MPT, 0)); 106 } 107 108 llvm::Constant *CGCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { 109 return GetBogusMemberPointer(CGM.getContext().getMemberPointerType( 110 MD->getType(), MD->getParent()->getTypeForDecl())); 111 } 112 113 llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, 114 CharUnits offset) { 115 return GetBogusMemberPointer(QualType(MPT, 0)); 116 } 117 118 llvm::Constant *CGCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) { 119 return GetBogusMemberPointer(MPT); 120 } 121 122 bool CGCXXABI::isZeroInitializable(const MemberPointerType *MPT) { 123 // Fake answer. 124 return true; 125 } 126 127 void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList ¶ms) { 128 const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 129 130 // FIXME: I'm not entirely sure I like using a fake decl just for code 131 // generation. Maybe we can come up with a better way? 132 auto *ThisDecl = ImplicitParamDecl::Create( 133 CGM.getContext(), nullptr, MD->getLocation(), 134 &CGM.getContext().Idents.get("this"), MD->getThisType(), 135 ImplicitParamDecl::CXXThis); 136 params.push_back(ThisDecl); 137 CGF.CXXABIThisDecl = ThisDecl; 138 139 // Compute the presumed alignment of 'this', which basically comes 140 // down to whether we know it's a complete object or not. 141 auto &Layout = CGF.getContext().getASTRecordLayout(MD->getParent()); 142 if (MD->getParent()->getNumVBases() == 0 || // avoid vcall in common case 143 MD->getParent()->hasAttr<FinalAttr>() || 144 !isThisCompleteObject(CGF.CurGD)) { 145 CGF.CXXABIThisAlignment = Layout.getAlignment(); 146 } else { 147 CGF.CXXABIThisAlignment = Layout.getNonVirtualAlignment(); 148 } 149 } 150 151 llvm::Value *CGCXXABI::loadIncomingCXXThis(CodeGenFunction &CGF) { 152 return CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)), 153 "this"); 154 } 155 156 void CGCXXABI::setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr) { 157 /// Initialize the 'this' slot. 158 assert(getThisDecl(CGF) && "no 'this' variable for function"); 159 CGF.CXXABIThisValue = ThisPtr; 160 } 161 162 void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, 163 RValue RV, QualType ResultType) { 164 CGF.EmitReturnOfRValue(RV, ResultType); 165 } 166 167 CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) { 168 if (!requiresArrayCookie(expr)) 169 return CharUnits::Zero(); 170 return getArrayCookieSizeImpl(expr->getAllocatedType()); 171 } 172 173 CharUnits CGCXXABI::getArrayCookieSizeImpl(QualType elementType) { 174 // BOGUS 175 return CharUnits::Zero(); 176 } 177 178 Address CGCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, 179 Address NewPtr, 180 llvm::Value *NumElements, 181 const CXXNewExpr *expr, 182 QualType ElementType) { 183 // Should never be called. 184 ErrorUnsupportedABI(CGF, "array cookie initialization"); 185 return Address::invalid(); 186 } 187 188 bool CGCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr, 189 QualType elementType) { 190 // If the class's usual deallocation function takes two arguments, 191 // it needs a cookie. 192 if (expr->doesUsualArrayDeleteWantSize()) 193 return true; 194 195 return elementType.isDestructedType(); 196 } 197 198 bool CGCXXABI::requiresArrayCookie(const CXXNewExpr *expr) { 199 // If the class's usual deallocation function takes two arguments, 200 // it needs a cookie. 201 if (expr->doesUsualArrayDeleteWantSize()) 202 return true; 203 204 return expr->getAllocatedType().isDestructedType(); 205 } 206 207 void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr, 208 const CXXDeleteExpr *expr, QualType eltTy, 209 llvm::Value *&numElements, 210 llvm::Value *&allocPtr, CharUnits &cookieSize) { 211 // Derive a char* in the same address space as the pointer. 212 ptr = CGF.Builder.CreateElementBitCast(ptr, CGF.Int8Ty); 213 214 // If we don't need an array cookie, bail out early. 215 if (!requiresArrayCookie(expr, eltTy)) { 216 allocPtr = ptr.getPointer(); 217 numElements = nullptr; 218 cookieSize = CharUnits::Zero(); 219 return; 220 } 221 222 cookieSize = getArrayCookieSizeImpl(eltTy); 223 Address allocAddr = 224 CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize); 225 allocPtr = allocAddr.getPointer(); 226 numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize); 227 } 228 229 llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, 230 Address ptr, 231 CharUnits cookieSize) { 232 ErrorUnsupportedABI(CGF, "reading a new[] cookie"); 233 return llvm::ConstantInt::get(CGF.SizeTy, 0); 234 } 235 236 /// Returns the adjustment, in bytes, required for the given 237 /// member-pointer operation. Returns null if no adjustment is 238 /// required. 239 llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) { 240 assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || 241 E->getCastKind() == CK_BaseToDerivedMemberPointer); 242 243 QualType derivedType; 244 if (E->getCastKind() == CK_DerivedToBaseMemberPointer) 245 derivedType = E->getSubExpr()->getType(); 246 else 247 derivedType = E->getType(); 248 249 const CXXRecordDecl *derivedClass = 250 derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl(); 251 252 return CGM.GetNonVirtualBaseClassOffset(derivedClass, 253 E->path_begin(), 254 E->path_end()); 255 } 256 257 CharUnits CGCXXABI::getMemberPointerPathAdjustment(const APValue &MP) { 258 // TODO: Store base specifiers in APValue member pointer paths so we can 259 // easily reuse CGM.GetNonVirtualBaseClassOffset(). 260 const ValueDecl *MPD = MP.getMemberPointerDecl(); 261 CharUnits ThisAdjustment = CharUnits::Zero(); 262 ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath(); 263 bool DerivedMember = MP.isMemberPointerToDerivedMember(); 264 const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext()); 265 for (unsigned I = 0, N = Path.size(); I != N; ++I) { 266 const CXXRecordDecl *Base = RD; 267 const CXXRecordDecl *Derived = Path[I]; 268 if (DerivedMember) 269 std::swap(Base, Derived); 270 ThisAdjustment += 271 getContext().getASTRecordLayout(Derived).getBaseClassOffset(Base); 272 RD = Path[I]; 273 } 274 if (DerivedMember) 275 ThisAdjustment = -ThisAdjustment; 276 return ThisAdjustment; 277 } 278 279 llvm::BasicBlock * 280 CGCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, 281 const CXXRecordDecl *RD) { 282 if (CGM.getTarget().getCXXABI().hasConstructorVariants()) 283 llvm_unreachable("shouldn't be called in this ABI"); 284 285 ErrorUnsupportedABI(CGF, "complete object detection in ctor"); 286 return nullptr; 287 } 288 289 void CGCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV, 290 const CXXDestructorDecl *Dtor, 291 CXXDtorType DT) const { 292 // Assume the base C++ ABI has no special rules for destructor variants. 293 CGM.setDLLImportDLLExport(GV, Dtor); 294 } 295 296 llvm::GlobalValue::LinkageTypes CGCXXABI::getCXXDestructorLinkage( 297 GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const { 298 // Delegate back to CGM by default. 299 return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage, 300 /*isConstantVariable=*/false); 301 } 302 303 bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) { 304 return false; 305 } 306 307 llvm::CallInst * 308 CGCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF, 309 llvm::Value *Exn) { 310 // Just call std::terminate and ignore the violating exception. 311 return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn()); 312 } 313 314 CatchTypeInfo CGCXXABI::getCatchAllTypeInfo() { 315 return CatchTypeInfo{nullptr, 0}; 316 } 317 318 std::vector<CharUnits> CGCXXABI::getVBPtrOffsets(const CXXRecordDecl *RD) { 319 return std::vector<CharUnits>(); 320 } 321