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 #include "clang/AST/Attr.h" 17 18 using namespace clang; 19 using namespace CodeGen; 20 21 CGCXXABI::~CGCXXABI() { } 22 23 void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) { 24 DiagnosticsEngine &Diags = CGF.CGM.getDiags(); 25 unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, 26 "cannot yet compile %0 in this ABI"); 27 Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()), 28 DiagID) 29 << S; 30 } 31 32 llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) { 33 return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T)); 34 } 35 36 llvm::Type * 37 CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { 38 return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType()); 39 } 40 41 CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer( 42 CodeGenFunction &CGF, const Expr *E, Address This, 43 llvm::Value *&ThisPtrForCall, 44 llvm::Value *MemPtr, const MemberPointerType *MPT) { 45 ErrorUnsupportedABI(CGF, "calls through member pointers"); 46 47 ThisPtrForCall = This.getPointer(); 48 const auto *FPT = MPT->getPointeeType()->castAs<FunctionProtoType>(); 49 llvm::Constant *FnPtr = llvm::Constant::getNullValue( 50 llvm::PointerType::getUnqual(CGM.getLLVMContext())); 51 return CGCallee::forDirect(FnPtr, FPT); 52 } 53 54 llvm::Value * 55 CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, 56 Address Base, llvm::Value *MemPtr, 57 const MemberPointerType *MPT) { 58 ErrorUnsupportedABI(CGF, "loads of member pointers"); 59 llvm::Type *Ty = 60 llvm::PointerType::get(CGF.getLLVMContext(), Base.getAddressSpace()); 61 return llvm::Constant::getNullValue(Ty); 62 } 63 64 llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, 65 const CastExpr *E, 66 llvm::Value *Src) { 67 ErrorUnsupportedABI(CGF, "member function pointer conversions"); 68 return GetBogusMemberPointer(E->getType()); 69 } 70 71 llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E, 72 llvm::Constant *Src) { 73 return GetBogusMemberPointer(E->getType()); 74 } 75 76 llvm::Value * 77 CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, 78 llvm::Value *L, 79 llvm::Value *R, 80 const MemberPointerType *MPT, 81 bool Inequality) { 82 ErrorUnsupportedABI(CGF, "member function pointer comparison"); 83 return CGF.Builder.getFalse(); 84 } 85 86 llvm::Value * 87 CGCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 88 llvm::Value *MemPtr, 89 const MemberPointerType *MPT) { 90 ErrorUnsupportedABI(CGF, "member function pointer null testing"); 91 return CGF.Builder.getFalse(); 92 } 93 94 llvm::Constant * 95 CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { 96 return GetBogusMemberPointer(QualType(MPT, 0)); 97 } 98 99 llvm::Constant *CGCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { 100 return GetBogusMemberPointer(CGM.getContext().getMemberPointerType( 101 MD->getType(), MD->getParent()->getTypeForDecl())); 102 } 103 104 llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, 105 CharUnits offset) { 106 return GetBogusMemberPointer(QualType(MPT, 0)); 107 } 108 109 llvm::Constant *CGCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) { 110 return GetBogusMemberPointer(MPT); 111 } 112 113 bool CGCXXABI::isZeroInitializable(const MemberPointerType *MPT) { 114 // Fake answer. 115 return true; 116 } 117 118 void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList ¶ms) { 119 const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 120 121 // FIXME: I'm not entirely sure I like using a fake decl just for code 122 // generation. Maybe we can come up with a better way? 123 auto *ThisDecl = 124 ImplicitParamDecl::Create(CGM.getContext(), nullptr, MD->getLocation(), 125 &CGM.getContext().Idents.get("this"), 126 MD->getThisType(), ImplicitParamKind::CXXThis); 127 params.push_back(ThisDecl); 128 CGF.CXXABIThisDecl = ThisDecl; 129 130 // Compute the presumed alignment of 'this', which basically comes 131 // down to whether we know it's a complete object or not. 132 auto &Layout = CGF.getContext().getASTRecordLayout(MD->getParent()); 133 if (MD->getParent()->getNumVBases() == 0 || // avoid vcall in common case 134 MD->getParent()->isEffectivelyFinal() || 135 isThisCompleteObject(CGF.CurGD)) { 136 CGF.CXXABIThisAlignment = Layout.getAlignment(); 137 } else { 138 CGF.CXXABIThisAlignment = Layout.getNonVirtualAlignment(); 139 } 140 } 141 142 llvm::Value *CGCXXABI::loadIncomingCXXThis(CodeGenFunction &CGF) { 143 return CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)), 144 "this"); 145 } 146 147 void CGCXXABI::setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr) { 148 /// Initialize the 'this' slot. 149 assert(getThisDecl(CGF) && "no 'this' variable for function"); 150 CGF.CXXABIThisValue = ThisPtr; 151 } 152 153 bool CGCXXABI::mayNeedDestruction(const VarDecl *VD) const { 154 if (VD->needsDestruction(getContext())) 155 return true; 156 157 // If the variable has an incomplete class type (or array thereof), it 158 // might need destruction. 159 const Type *T = VD->getType()->getBaseElementTypeUnsafe(); 160 if (T->getAs<RecordType>() && T->isIncompleteType()) 161 return true; 162 163 return false; 164 } 165 166 bool CGCXXABI::isEmittedWithConstantInitializer( 167 const VarDecl *VD, bool InspectInitForWeakDef) const { 168 VD = VD->getMostRecentDecl(); 169 if (VD->hasAttr<ConstInitAttr>()) 170 return true; 171 172 // All later checks examine the initializer specified on the variable. If 173 // the variable is weak, such examination would not be correct. 174 if (!InspectInitForWeakDef && (VD->isWeak() || VD->hasAttr<SelectAnyAttr>())) 175 return false; 176 177 const VarDecl *InitDecl = VD->getInitializingDeclaration(); 178 if (!InitDecl) 179 return false; 180 181 // If there's no initializer to run, this is constant initialization. 182 if (!InitDecl->hasInit()) 183 return true; 184 185 // If we have the only definition, we don't need a thread wrapper if we 186 // will emit the value as a constant. 187 if (isUniqueGVALinkage(getContext().GetGVALinkageForVariable(VD))) 188 return !mayNeedDestruction(VD) && InitDecl->evaluateValue(); 189 190 // Otherwise, we need a thread wrapper unless we know that every 191 // translation unit will emit the value as a constant. We rely on the 192 // variable being constant-initialized in every translation unit if it's 193 // constant-initialized in any translation unit, which isn't actually 194 // guaranteed by the standard but is necessary for sanity. 195 return InitDecl->hasConstantInitialization(); 196 } 197 198 void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, 199 RValue RV, QualType ResultType) { 200 assert(!CGF.hasAggregateEvaluationKind(ResultType) && 201 "cannot handle aggregates"); 202 CGF.EmitReturnOfRValue(RV, ResultType); 203 } 204 205 CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) { 206 if (!requiresArrayCookie(expr)) 207 return CharUnits::Zero(); 208 return getArrayCookieSizeImpl(expr->getAllocatedType()); 209 } 210 211 CharUnits CGCXXABI::getArrayCookieSizeImpl(QualType elementType) { 212 // BOGUS 213 return CharUnits::Zero(); 214 } 215 216 Address CGCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, 217 Address NewPtr, 218 llvm::Value *NumElements, 219 const CXXNewExpr *expr, 220 QualType ElementType) { 221 // Should never be called. 222 ErrorUnsupportedABI(CGF, "array cookie initialization"); 223 return Address::invalid(); 224 } 225 226 bool CGCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr, 227 QualType elementType) { 228 // If the class's usual deallocation function takes two arguments, 229 // it needs a cookie. 230 if (expr->doesUsualArrayDeleteWantSize()) 231 return true; 232 233 return elementType.isDestructedType(); 234 } 235 236 bool CGCXXABI::requiresArrayCookie(const CXXNewExpr *expr) { 237 // If the class's usual deallocation function takes two arguments, 238 // it needs a cookie. 239 if (expr->doesUsualArrayDeleteWantSize()) 240 return true; 241 242 return expr->getAllocatedType().isDestructedType(); 243 } 244 245 void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr, 246 const CXXDeleteExpr *expr, QualType eltTy, 247 llvm::Value *&numElements, 248 llvm::Value *&allocPtr, CharUnits &cookieSize) { 249 // Derive a char* in the same address space as the pointer. 250 ptr = ptr.withElementType(CGF.Int8Ty); 251 252 // If we don't need an array cookie, bail out early. 253 if (!requiresArrayCookie(expr, eltTy)) { 254 allocPtr = ptr.getPointer(); 255 numElements = nullptr; 256 cookieSize = CharUnits::Zero(); 257 return; 258 } 259 260 cookieSize = getArrayCookieSizeImpl(eltTy); 261 Address allocAddr = 262 CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize); 263 allocPtr = allocAddr.getPointer(); 264 numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize); 265 } 266 267 llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, 268 Address ptr, 269 CharUnits cookieSize) { 270 ErrorUnsupportedABI(CGF, "reading a new[] cookie"); 271 return llvm::ConstantInt::get(CGF.SizeTy, 0); 272 } 273 274 /// Returns the adjustment, in bytes, required for the given 275 /// member-pointer operation. Returns null if no adjustment is 276 /// required. 277 llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) { 278 assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || 279 E->getCastKind() == CK_BaseToDerivedMemberPointer); 280 281 QualType derivedType; 282 if (E->getCastKind() == CK_DerivedToBaseMemberPointer) 283 derivedType = E->getSubExpr()->getType(); 284 else 285 derivedType = E->getType(); 286 287 const CXXRecordDecl *derivedClass = 288 derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl(); 289 290 return CGM.GetNonVirtualBaseClassOffset(derivedClass, 291 E->path_begin(), 292 E->path_end()); 293 } 294 295 llvm::BasicBlock * 296 CGCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, 297 const CXXRecordDecl *RD) { 298 if (CGM.getTarget().getCXXABI().hasConstructorVariants()) 299 llvm_unreachable("shouldn't be called in this ABI"); 300 301 ErrorUnsupportedABI(CGF, "complete object detection in ctor"); 302 return nullptr; 303 } 304 305 void CGCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV, 306 const CXXDestructorDecl *Dtor, 307 CXXDtorType DT) const { 308 // Assume the base C++ ABI has no special rules for destructor variants. 309 CGM.setDLLImportDLLExport(GV, Dtor); 310 } 311 312 llvm::GlobalValue::LinkageTypes CGCXXABI::getCXXDestructorLinkage( 313 GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const { 314 // Delegate back to CGM by default. 315 return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage); 316 } 317 318 bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) { 319 return false; 320 } 321 322 llvm::CallInst * 323 CGCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF, 324 llvm::Value *Exn) { 325 // Just call std::terminate and ignore the violating exception. 326 return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn()); 327 } 328 329 CatchTypeInfo CGCXXABI::getCatchAllTypeInfo() { 330 return CatchTypeInfo{nullptr, 0}; 331 } 332 333 std::vector<CharUnits> CGCXXABI::getVBPtrOffsets(const CXXRecordDecl *RD) { 334 return std::vector<CharUnits>(); 335 } 336 337 CGCXXABI::AddedStructorArgCounts CGCXXABI::addImplicitConstructorArgs( 338 CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, 339 bool ForVirtualBase, bool Delegating, CallArgList &Args) { 340 AddedStructorArgs AddedArgs = 341 getImplicitConstructorArgs(CGF, D, Type, ForVirtualBase, Delegating); 342 for (size_t i = 0; i < AddedArgs.Prefix.size(); ++i) { 343 Args.insert(Args.begin() + 1 + i, 344 CallArg(RValue::get(AddedArgs.Prefix[i].Value), 345 AddedArgs.Prefix[i].Type)); 346 } 347 for (const auto &arg : AddedArgs.Suffix) { 348 Args.add(RValue::get(arg.Value), arg.Type); 349 } 350 return AddedStructorArgCounts(AddedArgs.Prefix.size(), 351 AddedArgs.Suffix.size()); 352 } 353