MicrosoftCXXABI.cpp 12 KB

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