CGCXXABI.cpp 12 KB

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