CGCXXABI.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. //===----- CGCXXABI.cpp - Interface to C++ ABIs ---------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This provides an abstract class for C++ code generation. Concrete subclasses
  11. // of this implement code generation for specific C++ ABIs.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "CGCXXABI.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. bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) const {
  27. // If RD has a non-trivial move or copy constructor, we cannot copy the
  28. // argument.
  29. if (RD->hasNonTrivialCopyConstructor() || RD->hasNonTrivialMoveConstructor())
  30. return false;
  31. // If RD has a non-trivial destructor, we cannot copy the argument.
  32. if (RD->hasNonTrivialDestructor())
  33. return false;
  34. // We can only copy the argument if there exists at least one trivial,
  35. // non-deleted copy or move constructor.
  36. // FIXME: This assumes that all lazily declared copy and move constructors are
  37. // not deleted. This assumption might not be true in some corner cases.
  38. bool CopyDeleted = false;
  39. bool MoveDeleted = false;
  40. for (const CXXConstructorDecl *CD : RD->ctors()) {
  41. if (CD->isCopyConstructor() || CD->isMoveConstructor()) {
  42. assert(CD->isTrivial());
  43. // We had at least one undeleted trivial copy or move ctor. Return
  44. // directly.
  45. if (!CD->isDeleted())
  46. return true;
  47. if (CD->isCopyConstructor())
  48. CopyDeleted = true;
  49. else
  50. MoveDeleted = true;
  51. }
  52. }
  53. // If all trivial copy and move constructors are deleted, we cannot copy the
  54. // argument.
  55. return !(CopyDeleted && MoveDeleted);
  56. }
  57. llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {
  58. return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T));
  59. }
  60. llvm::Type *
  61. CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
  62. return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
  63. }
  64. llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(
  65. CodeGenFunction &CGF, const Expr *E, llvm::Value *&This,
  66. llvm::Value *MemPtr, const MemberPointerType *MPT) {
  67. ErrorUnsupportedABI(CGF, "calls through member pointers");
  68. const FunctionProtoType *FPT =
  69. MPT->getPointeeType()->getAs<FunctionProtoType>();
  70. const CXXRecordDecl *RD =
  71. cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
  72. llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
  73. CGM.getTypes().arrangeCXXMethodType(RD, FPT));
  74. return llvm::Constant::getNullValue(FTy->getPointerTo());
  75. }
  76. llvm::Value *
  77. CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
  78. llvm::Value *Base, llvm::Value *MemPtr,
  79. const MemberPointerType *MPT) {
  80. ErrorUnsupportedABI(CGF, "loads of member pointers");
  81. llvm::Type *Ty = CGF.ConvertType(MPT->getPointeeType())->getPointerTo();
  82. return llvm::Constant::getNullValue(Ty);
  83. }
  84. llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
  85. const CastExpr *E,
  86. llvm::Value *Src) {
  87. ErrorUnsupportedABI(CGF, "member function pointer conversions");
  88. return GetBogusMemberPointer(E->getType());
  89. }
  90. llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E,
  91. llvm::Constant *Src) {
  92. return GetBogusMemberPointer(E->getType());
  93. }
  94. llvm::Value *
  95. CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
  96. llvm::Value *L,
  97. llvm::Value *R,
  98. const MemberPointerType *MPT,
  99. bool Inequality) {
  100. ErrorUnsupportedABI(CGF, "member function pointer comparison");
  101. return CGF.Builder.getFalse();
  102. }
  103. llvm::Value *
  104. CGCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
  105. llvm::Value *MemPtr,
  106. const MemberPointerType *MPT) {
  107. ErrorUnsupportedABI(CGF, "member function pointer null testing");
  108. return CGF.Builder.getFalse();
  109. }
  110. llvm::Constant *
  111. CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
  112. return GetBogusMemberPointer(QualType(MPT, 0));
  113. }
  114. llvm::Constant *CGCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
  115. return GetBogusMemberPointer(CGM.getContext().getMemberPointerType(
  116. MD->getType(), MD->getParent()->getTypeForDecl()));
  117. }
  118. llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
  119. CharUnits offset) {
  120. return GetBogusMemberPointer(QualType(MPT, 0));
  121. }
  122. llvm::Constant *CGCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) {
  123. return GetBogusMemberPointer(MPT);
  124. }
  125. bool CGCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
  126. // Fake answer.
  127. return true;
  128. }
  129. void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList &params) {
  130. const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
  131. // FIXME: I'm not entirely sure I like using a fake decl just for code
  132. // generation. Maybe we can come up with a better way?
  133. ImplicitParamDecl *ThisDecl
  134. = ImplicitParamDecl::Create(CGM.getContext(), nullptr, MD->getLocation(),
  135. &CGM.getContext().Idents.get("this"),
  136. MD->getThisType(CGM.getContext()));
  137. params.push_back(ThisDecl);
  138. getThisDecl(CGF) = ThisDecl;
  139. }
  140. void CGCXXABI::EmitThisParam(CodeGenFunction &CGF) {
  141. /// Initialize the 'this' slot.
  142. assert(getThisDecl(CGF) && "no 'this' variable for function");
  143. // HLSL Change Starts:
  144. if (CGF.CurFn) {
  145. getThisValue(CGF) = CGF.CurFn->args().begin();
  146. } else
  147. // HLSL Change Ends
  148. getThisValue(CGF) = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)),
  149. "this");
  150. }
  151. void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
  152. RValue RV, QualType ResultType) {
  153. CGF.EmitReturnOfRValue(RV, ResultType);
  154. }
  155. CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
  156. if (!requiresArrayCookie(expr))
  157. return CharUnits::Zero();
  158. return getArrayCookieSizeImpl(expr->getAllocatedType());
  159. }
  160. CharUnits CGCXXABI::getArrayCookieSizeImpl(QualType elementType) {
  161. // BOGUS
  162. return CharUnits::Zero();
  163. }
  164. llvm::Value *CGCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
  165. llvm::Value *NewPtr,
  166. llvm::Value *NumElements,
  167. const CXXNewExpr *expr,
  168. QualType ElementType) {
  169. // Should never be called.
  170. ErrorUnsupportedABI(CGF, "array cookie initialization");
  171. return nullptr;
  172. }
  173. bool CGCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
  174. QualType elementType) {
  175. // If the class's usual deallocation function takes two arguments,
  176. // it needs a cookie.
  177. if (expr->doesUsualArrayDeleteWantSize())
  178. return true;
  179. return elementType.isDestructedType();
  180. }
  181. bool CGCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
  182. // If the class's usual deallocation function takes two arguments,
  183. // it needs a cookie.
  184. if (expr->doesUsualArrayDeleteWantSize())
  185. return true;
  186. return expr->getAllocatedType().isDestructedType();
  187. }
  188. void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *ptr,
  189. const CXXDeleteExpr *expr, QualType eltTy,
  190. llvm::Value *&numElements,
  191. llvm::Value *&allocPtr, CharUnits &cookieSize) {
  192. // Derive a char* in the same address space as the pointer.
  193. unsigned AS = ptr->getType()->getPointerAddressSpace();
  194. llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS);
  195. ptr = CGF.Builder.CreateBitCast(ptr, charPtrTy);
  196. // If we don't need an array cookie, bail out early.
  197. if (!requiresArrayCookie(expr, eltTy)) {
  198. allocPtr = ptr;
  199. numElements = nullptr;
  200. cookieSize = CharUnits::Zero();
  201. return;
  202. }
  203. cookieSize = getArrayCookieSizeImpl(eltTy);
  204. allocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(ptr,
  205. -cookieSize.getQuantity());
  206. numElements = readArrayCookieImpl(CGF, allocPtr, cookieSize);
  207. }
  208. llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
  209. llvm::Value *ptr,
  210. CharUnits cookieSize) {
  211. ErrorUnsupportedABI(CGF, "reading a new[] cookie");
  212. return llvm::ConstantInt::get(CGF.SizeTy, 0);
  213. }
  214. /// Returns the adjustment, in bytes, required for the given
  215. /// member-pointer operation. Returns null if no adjustment is
  216. /// required.
  217. llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
  218. assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
  219. E->getCastKind() == CK_BaseToDerivedMemberPointer);
  220. QualType derivedType;
  221. if (E->getCastKind() == CK_DerivedToBaseMemberPointer)
  222. derivedType = E->getSubExpr()->getType();
  223. else
  224. derivedType = E->getType();
  225. const CXXRecordDecl *derivedClass =
  226. derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
  227. return CGM.GetNonVirtualBaseClassOffset(derivedClass,
  228. E->path_begin(),
  229. E->path_end());
  230. }
  231. CharUnits CGCXXABI::getMemberPointerPathAdjustment(const APValue &MP) {
  232. // TODO: Store base specifiers in APValue member pointer paths so we can
  233. // easily reuse CGM.GetNonVirtualBaseClassOffset().
  234. const ValueDecl *MPD = MP.getMemberPointerDecl();
  235. CharUnits ThisAdjustment = CharUnits::Zero();
  236. ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath();
  237. bool DerivedMember = MP.isMemberPointerToDerivedMember();
  238. const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext());
  239. for (unsigned I = 0, N = Path.size(); I != N; ++I) {
  240. const CXXRecordDecl *Base = RD;
  241. const CXXRecordDecl *Derived = Path[I];
  242. if (DerivedMember)
  243. std::swap(Base, Derived);
  244. ThisAdjustment +=
  245. getContext().getASTRecordLayout(Derived).getBaseClassOffset(Base);
  246. RD = Path[I];
  247. }
  248. if (DerivedMember)
  249. ThisAdjustment = -ThisAdjustment;
  250. return ThisAdjustment;
  251. }
  252. llvm::BasicBlock *
  253. CGCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
  254. const CXXRecordDecl *RD) {
  255. if (CGM.getTarget().getCXXABI().hasConstructorVariants())
  256. llvm_unreachable("shouldn't be called in this ABI");
  257. ErrorUnsupportedABI(CGF, "complete object detection in ctor");
  258. return nullptr;
  259. }
  260. bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
  261. return false;
  262. }
  263. llvm::CallInst *
  264. CGCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
  265. llvm::Value *Exn) {
  266. // Just call std::terminate and ignore the violating exception.
  267. return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn());
  268. }