CGCXXABI.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. //===----- CGCXXABI.cpp - Interface to C++ ABIs -----------------*- C++ -*-===//
  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. static void ErrorUnsupportedABI(CodeGenFunction &CGF,
  19. StringRef S) {
  20. DiagnosticsEngine &Diags = CGF.CGM.getDiags();
  21. unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
  22. "cannot yet compile %1 in this ABI");
  23. Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()),
  24. DiagID)
  25. << S;
  26. }
  27. static llvm::Constant *GetBogusMemberPointer(CodeGenModule &CGM,
  28. QualType T) {
  29. return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T));
  30. }
  31. llvm::Type *
  32. CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
  33. return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
  34. }
  35. llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
  36. llvm::Value *&This,
  37. llvm::Value *MemPtr,
  38. const MemberPointerType *MPT) {
  39. ErrorUnsupportedABI(CGF, "calls through member pointers");
  40. const FunctionProtoType *FPT =
  41. MPT->getPointeeType()->getAs<FunctionProtoType>();
  42. const CXXRecordDecl *RD =
  43. cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
  44. llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
  45. CGM.getTypes().arrangeCXXMethodType(RD, FPT));
  46. return llvm::Constant::getNullValue(FTy->getPointerTo());
  47. }
  48. llvm::Value *CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
  49. llvm::Value *Base,
  50. llvm::Value *MemPtr,
  51. const MemberPointerType *MPT) {
  52. ErrorUnsupportedABI(CGF, "loads of member pointers");
  53. llvm::Type *Ty = CGF.ConvertType(MPT->getPointeeType())->getPointerTo();
  54. return llvm::Constant::getNullValue(Ty);
  55. }
  56. llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
  57. const CastExpr *E,
  58. llvm::Value *Src) {
  59. ErrorUnsupportedABI(CGF, "member function pointer conversions");
  60. return GetBogusMemberPointer(CGM, E->getType());
  61. }
  62. llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E,
  63. llvm::Constant *Src) {
  64. return GetBogusMemberPointer(CGM, E->getType());
  65. }
  66. llvm::Value *
  67. CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
  68. llvm::Value *L,
  69. llvm::Value *R,
  70. const MemberPointerType *MPT,
  71. bool Inequality) {
  72. ErrorUnsupportedABI(CGF, "member function pointer comparison");
  73. return CGF.Builder.getFalse();
  74. }
  75. llvm::Value *
  76. CGCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
  77. llvm::Value *MemPtr,
  78. const MemberPointerType *MPT) {
  79. ErrorUnsupportedABI(CGF, "member function pointer null testing");
  80. return CGF.Builder.getFalse();
  81. }
  82. llvm::Constant *
  83. CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
  84. return GetBogusMemberPointer(CGM, QualType(MPT, 0));
  85. }
  86. llvm::Constant *CGCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
  87. return GetBogusMemberPointer(CGM,
  88. CGM.getContext().getMemberPointerType(MD->getType(),
  89. MD->getParent()->getTypeForDecl()));
  90. }
  91. llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
  92. CharUnits offset) {
  93. return GetBogusMemberPointer(CGM, QualType(MPT, 0));
  94. }
  95. llvm::Constant *CGCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) {
  96. return GetBogusMemberPointer(CGM, 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. ImplicitParamDecl *ThisDecl
  107. = ImplicitParamDecl::Create(CGM.getContext(), 0, MD->getLocation(),
  108. &CGM.getContext().Idents.get("this"),
  109. MD->getThisType(CGM.getContext()));
  110. params.push_back(ThisDecl);
  111. getThisDecl(CGF) = ThisDecl;
  112. }
  113. void CGCXXABI::EmitThisParam(CodeGenFunction &CGF) {
  114. /// Initialize the 'this' slot.
  115. assert(getThisDecl(CGF) && "no 'this' variable for function");
  116. getThisValue(CGF)
  117. = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)),
  118. "this");
  119. }
  120. void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
  121. RValue RV, QualType ResultType) {
  122. CGF.EmitReturnOfRValue(RV, ResultType);
  123. }
  124. CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
  125. return CharUnits::Zero();
  126. }
  127. llvm::Value *CGCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
  128. llvm::Value *NewPtr,
  129. llvm::Value *NumElements,
  130. const CXXNewExpr *expr,
  131. QualType ElementType) {
  132. // Should never be called.
  133. ErrorUnsupportedABI(CGF, "array cookie initialization");
  134. return 0;
  135. }
  136. void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr,
  137. const CXXDeleteExpr *expr, QualType ElementType,
  138. llvm::Value *&NumElements,
  139. llvm::Value *&AllocPtr, CharUnits &CookieSize) {
  140. ErrorUnsupportedABI(CGF, "array cookie reading");
  141. // This should be enough to avoid assertions.
  142. NumElements = 0;
  143. AllocPtr = llvm::Constant::getNullValue(CGF.Builder.getInt8PtrTy());
  144. CookieSize = CharUnits::Zero();
  145. }
  146. void CGCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
  147. const VarDecl &D,
  148. llvm::GlobalVariable *GV,
  149. bool PerformInit) {
  150. ErrorUnsupportedABI(CGF, "static local variable initialization");
  151. }
  152. /// Returns the adjustment, in bytes, required for the given
  153. /// member-pointer operation. Returns null if no adjustment is
  154. /// required.
  155. llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
  156. assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
  157. E->getCastKind() == CK_BaseToDerivedMemberPointer);
  158. QualType derivedType;
  159. if (E->getCastKind() == CK_DerivedToBaseMemberPointer)
  160. derivedType = E->getSubExpr()->getType();
  161. else
  162. derivedType = E->getType();
  163. const CXXRecordDecl *derivedClass =
  164. derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
  165. return CGM.GetNonVirtualBaseClassOffset(derivedClass,
  166. E->path_begin(),
  167. E->path_end());
  168. }