MicrosoftCXXABI.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. //===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
  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 C++ AST support targeting the Microsoft Visual C++
  10. // ABI.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "CXXABI.h"
  14. #include "clang/AST/ASTContext.h"
  15. #include "clang/AST/Attr.h"
  16. #include "clang/AST/CXXInheritance.h"
  17. #include "clang/AST/DeclCXX.h"
  18. #include "clang/AST/Mangle.h"
  19. #include "clang/AST/MangleNumberingContext.h"
  20. #include "clang/AST/RecordLayout.h"
  21. #include "clang/AST/Type.h"
  22. #include "clang/Basic/TargetInfo.h"
  23. using namespace clang;
  24. namespace {
  25. /// Numbers things which need to correspond across multiple TUs.
  26. /// Typically these are things like static locals, lambdas, or blocks.
  27. class MicrosoftNumberingContext : public MangleNumberingContext {
  28. llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
  29. unsigned LambdaManglingNumber;
  30. unsigned StaticLocalNumber;
  31. unsigned StaticThreadlocalNumber;
  32. public:
  33. MicrosoftNumberingContext()
  34. : LambdaManglingNumber(0), StaticLocalNumber(0),
  35. StaticThreadlocalNumber(0) {}
  36. unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
  37. return ++LambdaManglingNumber;
  38. }
  39. unsigned getManglingNumber(const BlockDecl *BD) override {
  40. const Type *Ty = nullptr;
  41. return ++ManglingNumbers[Ty];
  42. }
  43. unsigned getStaticLocalNumber(const VarDecl *VD) override {
  44. if (VD->getTLSKind())
  45. return ++StaticThreadlocalNumber;
  46. return ++StaticLocalNumber;
  47. }
  48. unsigned getManglingNumber(const VarDecl *VD,
  49. unsigned MSLocalManglingNumber) override {
  50. return MSLocalManglingNumber;
  51. }
  52. unsigned getManglingNumber(const TagDecl *TD,
  53. unsigned MSLocalManglingNumber) override {
  54. return MSLocalManglingNumber;
  55. }
  56. };
  57. class MSHIPNumberingContext : public MicrosoftNumberingContext {
  58. std::unique_ptr<MangleNumberingContext> DeviceCtx;
  59. public:
  60. MSHIPNumberingContext(MangleContext *DeviceMangler) {
  61. DeviceCtx = createItaniumNumberingContext(DeviceMangler);
  62. }
  63. unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
  64. return DeviceCtx->getManglingNumber(CallOperator);
  65. }
  66. };
  67. class MSSYCLNumberingContext : public MicrosoftNumberingContext {
  68. std::unique_ptr<MangleNumberingContext> DeviceCtx;
  69. public:
  70. MSSYCLNumberingContext(MangleContext *DeviceMangler) {
  71. DeviceCtx = createItaniumNumberingContext(DeviceMangler);
  72. }
  73. unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
  74. return DeviceCtx->getManglingNumber(CallOperator);
  75. }
  76. };
  77. class MicrosoftCXXABI : public CXXABI {
  78. ASTContext &Context;
  79. llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor;
  80. llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *>
  81. UnnamedTagDeclToDeclaratorDecl;
  82. llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *>
  83. UnnamedTagDeclToTypedefNameDecl;
  84. // MangleContext for device numbering context, which is based on Itanium C++
  85. // ABI.
  86. std::unique_ptr<MangleContext> DeviceMangler;
  87. public:
  88. MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) {
  89. if (Context.getLangOpts().CUDA && Context.getAuxTargetInfo()) {
  90. assert(Context.getTargetInfo().getCXXABI().isMicrosoft() &&
  91. Context.getAuxTargetInfo()->getCXXABI().isItaniumFamily() &&
  92. "Unexpected combination of C++ ABIs.");
  93. DeviceMangler.reset(
  94. Context.createMangleContext(Context.getAuxTargetInfo()));
  95. }
  96. else if (Context.getLangOpts().isSYCL()) {
  97. DeviceMangler.reset(
  98. ItaniumMangleContext::create(Context, Context.getDiagnostics()));
  99. }
  100. }
  101. MemberPointerInfo
  102. getMemberPointerInfo(const MemberPointerType *MPT) const override;
  103. CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
  104. if (!isVariadic &&
  105. Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
  106. return CC_X86ThisCall;
  107. return Context.getTargetInfo().getDefaultCallingConv();
  108. }
  109. bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
  110. llvm_unreachable("unapplicable to the MS ABI");
  111. }
  112. const CXXConstructorDecl *
  113. getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
  114. return RecordToCopyCtor[RD];
  115. }
  116. void
  117. addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
  118. CXXConstructorDecl *CD) override {
  119. assert(CD != nullptr);
  120. assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD);
  121. RecordToCopyCtor[RD] = CD;
  122. }
  123. void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
  124. TypedefNameDecl *DD) override {
  125. TD = TD->getCanonicalDecl();
  126. DD = DD->getCanonicalDecl();
  127. TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
  128. if (!I)
  129. I = DD;
  130. }
  131. TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
  132. return UnnamedTagDeclToTypedefNameDecl.lookup(
  133. const_cast<TagDecl *>(TD->getCanonicalDecl()));
  134. }
  135. void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
  136. DeclaratorDecl *DD) override {
  137. TD = TD->getCanonicalDecl();
  138. DD = cast<DeclaratorDecl>(DD->getCanonicalDecl());
  139. DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
  140. if (!I)
  141. I = DD;
  142. }
  143. DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
  144. return UnnamedTagDeclToDeclaratorDecl.lookup(
  145. const_cast<TagDecl *>(TD->getCanonicalDecl()));
  146. }
  147. std::unique_ptr<MangleNumberingContext>
  148. createMangleNumberingContext() const override {
  149. if (Context.getLangOpts().CUDA && Context.getAuxTargetInfo()) {
  150. assert(DeviceMangler && "Missing device mangler");
  151. return std::make_unique<MSHIPNumberingContext>(DeviceMangler.get());
  152. } else if (Context.getLangOpts().isSYCL()) {
  153. assert(DeviceMangler && "Missing device mangler");
  154. return std::make_unique<MSSYCLNumberingContext>(DeviceMangler.get());
  155. }
  156. return std::make_unique<MicrosoftNumberingContext>();
  157. }
  158. };
  159. }
  160. // getNumBases() seems to only give us the number of direct bases, and not the
  161. // total. This function tells us if we inherit from anybody that uses MI, or if
  162. // we have a non-primary base class, which uses the multiple inheritance model.
  163. static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
  164. while (RD->getNumBases() > 0) {
  165. if (RD->getNumBases() > 1)
  166. return true;
  167. assert(RD->getNumBases() == 1);
  168. const CXXRecordDecl *Base =
  169. RD->bases_begin()->getType()->getAsCXXRecordDecl();
  170. if (RD->isPolymorphic() && !Base->isPolymorphic())
  171. return true;
  172. RD = Base;
  173. }
  174. return false;
  175. }
  176. MSInheritanceModel CXXRecordDecl::calculateInheritanceModel() const {
  177. if (!hasDefinition() || isParsingBaseSpecifiers())
  178. return MSInheritanceModel::Unspecified;
  179. if (getNumVBases() > 0)
  180. return MSInheritanceModel::Virtual;
  181. if (usesMultipleInheritanceModel(this))
  182. return MSInheritanceModel::Multiple;
  183. return MSInheritanceModel::Single;
  184. }
  185. MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
  186. MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
  187. assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
  188. return IA->getInheritanceModel();
  189. }
  190. bool CXXRecordDecl::nullFieldOffsetIsZero() const {
  191. return !inheritanceModelHasOnlyOneField(/*IsMemberFunction=*/false,
  192. getMSInheritanceModel()) ||
  193. (hasDefinition() && isPolymorphic());
  194. }
  195. MSVtorDispMode CXXRecordDecl::getMSVtorDispMode() const {
  196. if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
  197. return VDA->getVtorDispMode();
  198. return getASTContext().getLangOpts().getVtorDispMode();
  199. }
  200. // Returns the number of pointer and integer slots used to represent a member
  201. // pointer in the MS C++ ABI.
  202. //
  203. // Member function pointers have the following general form; however, fields
  204. // are dropped as permitted (under the MSVC interpretation) by the inheritance
  205. // model of the actual class.
  206. //
  207. // struct {
  208. // // A pointer to the member function to call. If the member function is
  209. // // virtual, this will be a thunk that forwards to the appropriate vftable
  210. // // slot.
  211. // void *FunctionPointerOrVirtualThunk;
  212. //
  213. // // An offset to add to the address of the vbtable pointer after
  214. // // (possibly) selecting the virtual base but before resolving and calling
  215. // // the function.
  216. // // Only needed if the class has any virtual bases or bases at a non-zero
  217. // // offset.
  218. // int NonVirtualBaseAdjustment;
  219. //
  220. // // The offset of the vb-table pointer within the object. Only needed for
  221. // // incomplete types.
  222. // int VBPtrOffset;
  223. //
  224. // // An offset within the vb-table that selects the virtual base containing
  225. // // the member. Loading from this offset produces a new offset that is
  226. // // added to the address of the vb-table pointer to produce the base.
  227. // int VirtualBaseAdjustmentOffset;
  228. // };
  229. static std::pair<unsigned, unsigned>
  230. getMSMemberPointerSlots(const MemberPointerType *MPT) {
  231. const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
  232. MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
  233. unsigned Ptrs = 0;
  234. unsigned Ints = 0;
  235. if (MPT->isMemberFunctionPointer())
  236. Ptrs = 1;
  237. else
  238. Ints = 1;
  239. if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
  240. Inheritance))
  241. Ints++;
  242. if (inheritanceModelHasVBPtrOffsetField(Inheritance))
  243. Ints++;
  244. if (inheritanceModelHasVBTableOffsetField(Inheritance))
  245. Ints++;
  246. return std::make_pair(Ptrs, Ints);
  247. }
  248. CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
  249. const MemberPointerType *MPT) const {
  250. // The nominal struct is laid out with pointers followed by ints and aligned
  251. // to a pointer width if any are present and an int width otherwise.
  252. const TargetInfo &Target = Context.getTargetInfo();
  253. unsigned PtrSize = Target.getPointerWidth(0);
  254. unsigned IntSize = Target.getIntWidth();
  255. unsigned Ptrs, Ints;
  256. std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
  257. MemberPointerInfo MPI;
  258. MPI.HasPadding = false;
  259. MPI.Width = Ptrs * PtrSize + Ints * IntSize;
  260. // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
  261. // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for
  262. // function memptrs.
  263. if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
  264. MPI.Align = 64;
  265. else if (Ptrs)
  266. MPI.Align = Target.getPointerAlign(0);
  267. else
  268. MPI.Align = Target.getIntAlign();
  269. if (Target.getTriple().isArch64Bit()) {
  270. MPI.Width = llvm::alignTo(MPI.Width, MPI.Align);
  271. MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize);
  272. }
  273. return MPI;
  274. }
  275. CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
  276. return new MicrosoftCXXABI(Ctx);
  277. }