xref: /freebsd/contrib/llvm-project/clang/lib/AST/MicrosoftCXXABI.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This provides C++ AST support targeting the Microsoft Visual C++
100b57cec5SDimitry Andric // ABI.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "CXXABI.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
160b57cec5SDimitry Andric #include "clang/AST/Attr.h"
17480093f4SDimitry Andric #include "clang/AST/CXXInheritance.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
19d409305fSDimitry Andric #include "clang/AST/Mangle.h"
200b57cec5SDimitry Andric #include "clang/AST/MangleNumberingContext.h"
210b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h"
220b57cec5SDimitry Andric #include "clang/AST/Type.h"
230b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric using namespace clang;
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric namespace {
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric /// Numbers things which need to correspond across multiple TUs.
300b57cec5SDimitry Andric /// Typically these are things like static locals, lambdas, or blocks.
310b57cec5SDimitry Andric class MicrosoftNumberingContext : public MangleNumberingContext {
320b57cec5SDimitry Andric   llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
33*5f757f3fSDimitry Andric   unsigned LambdaManglingNumber = 0;
34*5f757f3fSDimitry Andric   unsigned StaticLocalNumber = 0;
35*5f757f3fSDimitry Andric   unsigned StaticThreadlocalNumber = 0;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric public:
38*5f757f3fSDimitry Andric   MicrosoftNumberingContext() = default;
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
410b57cec5SDimitry Andric     return ++LambdaManglingNumber;
420b57cec5SDimitry Andric   }
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   unsigned getManglingNumber(const BlockDecl *BD) override {
450b57cec5SDimitry Andric     const Type *Ty = nullptr;
460b57cec5SDimitry Andric     return ++ManglingNumbers[Ty];
470b57cec5SDimitry Andric   }
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric   unsigned getStaticLocalNumber(const VarDecl *VD) override {
500b57cec5SDimitry Andric     if (VD->getTLSKind())
510b57cec5SDimitry Andric       return ++StaticThreadlocalNumber;
520b57cec5SDimitry Andric     return ++StaticLocalNumber;
530b57cec5SDimitry Andric   }
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   unsigned getManglingNumber(const VarDecl *VD,
560b57cec5SDimitry Andric                              unsigned MSLocalManglingNumber) override {
570b57cec5SDimitry Andric     return MSLocalManglingNumber;
580b57cec5SDimitry Andric   }
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   unsigned getManglingNumber(const TagDecl *TD,
610b57cec5SDimitry Andric                              unsigned MSLocalManglingNumber) override {
620b57cec5SDimitry Andric     return MSLocalManglingNumber;
630b57cec5SDimitry Andric   }
640b57cec5SDimitry Andric };
650b57cec5SDimitry Andric 
66d409305fSDimitry Andric class MSHIPNumberingContext : public MicrosoftNumberingContext {
67d409305fSDimitry Andric   std::unique_ptr<MangleNumberingContext> DeviceCtx;
68d409305fSDimitry Andric 
69d409305fSDimitry Andric public:
7081ad6265SDimitry Andric   using MicrosoftNumberingContext::getManglingNumber;
71d409305fSDimitry Andric   MSHIPNumberingContext(MangleContext *DeviceMangler) {
72d409305fSDimitry Andric     DeviceCtx = createItaniumNumberingContext(DeviceMangler);
73d409305fSDimitry Andric   }
74d409305fSDimitry Andric 
75d409305fSDimitry Andric   unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
76d409305fSDimitry Andric     return DeviceCtx->getManglingNumber(CallOperator);
77d409305fSDimitry Andric   }
7881ad6265SDimitry Andric 
7981ad6265SDimitry Andric   unsigned getManglingNumber(const TagDecl *TD,
8081ad6265SDimitry Andric                              unsigned MSLocalManglingNumber) override {
8181ad6265SDimitry Andric     unsigned DeviceN = DeviceCtx->getManglingNumber(TD, MSLocalManglingNumber);
8281ad6265SDimitry Andric     unsigned HostN =
8381ad6265SDimitry Andric         MicrosoftNumberingContext::getManglingNumber(TD, MSLocalManglingNumber);
8481ad6265SDimitry Andric     if (DeviceN > 0xFFFF || HostN > 0xFFFF) {
8581ad6265SDimitry Andric       DiagnosticsEngine &Diags = TD->getASTContext().getDiagnostics();
8681ad6265SDimitry Andric       unsigned DiagID = Diags.getCustomDiagID(
8781ad6265SDimitry Andric           DiagnosticsEngine::Error, "Mangling number exceeds limit (65535)");
8881ad6265SDimitry Andric       Diags.Report(TD->getLocation(), DiagID);
8981ad6265SDimitry Andric     }
9081ad6265SDimitry Andric     return (DeviceN << 16) | HostN;
9181ad6265SDimitry Andric   }
92d409305fSDimitry Andric };
93d409305fSDimitry Andric 
94349cc55cSDimitry Andric class MSSYCLNumberingContext : public MicrosoftNumberingContext {
95349cc55cSDimitry Andric   std::unique_ptr<MangleNumberingContext> DeviceCtx;
96349cc55cSDimitry Andric 
97349cc55cSDimitry Andric public:
98349cc55cSDimitry Andric   MSSYCLNumberingContext(MangleContext *DeviceMangler) {
99349cc55cSDimitry Andric     DeviceCtx = createItaniumNumberingContext(DeviceMangler);
100349cc55cSDimitry Andric   }
101349cc55cSDimitry Andric 
102349cc55cSDimitry Andric   unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
103349cc55cSDimitry Andric     return DeviceCtx->getManglingNumber(CallOperator);
104349cc55cSDimitry Andric   }
105349cc55cSDimitry Andric };
106349cc55cSDimitry Andric 
1070b57cec5SDimitry Andric class MicrosoftCXXABI : public CXXABI {
1080b57cec5SDimitry Andric   ASTContext &Context;
1090b57cec5SDimitry Andric   llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor;
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *>
1120b57cec5SDimitry Andric       UnnamedTagDeclToDeclaratorDecl;
1130b57cec5SDimitry Andric   llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *>
1140b57cec5SDimitry Andric       UnnamedTagDeclToTypedefNameDecl;
1150b57cec5SDimitry Andric 
116d409305fSDimitry Andric   // MangleContext for device numbering context, which is based on Itanium C++
117d409305fSDimitry Andric   // ABI.
118d409305fSDimitry Andric   std::unique_ptr<MangleContext> DeviceMangler;
119d409305fSDimitry Andric 
1200b57cec5SDimitry Andric public:
121d409305fSDimitry Andric   MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) {
122d409305fSDimitry Andric     if (Context.getLangOpts().CUDA && Context.getAuxTargetInfo()) {
123d409305fSDimitry Andric       assert(Context.getTargetInfo().getCXXABI().isMicrosoft() &&
124d409305fSDimitry Andric              Context.getAuxTargetInfo()->getCXXABI().isItaniumFamily() &&
125d409305fSDimitry Andric              "Unexpected combination of C++ ABIs.");
126d409305fSDimitry Andric       DeviceMangler.reset(
127d409305fSDimitry Andric           Context.createMangleContext(Context.getAuxTargetInfo()));
128d409305fSDimitry Andric     }
129349cc55cSDimitry Andric     else if (Context.getLangOpts().isSYCL()) {
130349cc55cSDimitry Andric       DeviceMangler.reset(
131349cc55cSDimitry Andric           ItaniumMangleContext::create(Context, Context.getDiagnostics()));
132349cc55cSDimitry Andric     }
133d409305fSDimitry Andric   }
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric   MemberPointerInfo
1360b57cec5SDimitry Andric   getMemberPointerInfo(const MemberPointerType *MPT) const override;
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
1390b57cec5SDimitry Andric     if (!isVariadic &&
1400b57cec5SDimitry Andric         Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
1410b57cec5SDimitry Andric       return CC_X86ThisCall;
1420b57cec5SDimitry Andric     return Context.getTargetInfo().getDefaultCallingConv();
1430b57cec5SDimitry Andric   }
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
1460b57cec5SDimitry Andric     llvm_unreachable("unapplicable to the MS ABI");
1470b57cec5SDimitry Andric   }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   const CXXConstructorDecl *
1500b57cec5SDimitry Andric   getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
1510b57cec5SDimitry Andric     return RecordToCopyCtor[RD];
1520b57cec5SDimitry Andric   }
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric   void
1550b57cec5SDimitry Andric   addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
1560b57cec5SDimitry Andric                                        CXXConstructorDecl *CD) override {
1570b57cec5SDimitry Andric     assert(CD != nullptr);
1580b57cec5SDimitry Andric     assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD);
1590b57cec5SDimitry Andric     RecordToCopyCtor[RD] = CD;
1600b57cec5SDimitry Andric   }
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
1630b57cec5SDimitry Andric                                        TypedefNameDecl *DD) override {
1640b57cec5SDimitry Andric     TD = TD->getCanonicalDecl();
1650b57cec5SDimitry Andric     DD = DD->getCanonicalDecl();
1660b57cec5SDimitry Andric     TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
1670b57cec5SDimitry Andric     if (!I)
1680b57cec5SDimitry Andric       I = DD;
1690b57cec5SDimitry Andric   }
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric   TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
1720b57cec5SDimitry Andric     return UnnamedTagDeclToTypedefNameDecl.lookup(
1730b57cec5SDimitry Andric         const_cast<TagDecl *>(TD->getCanonicalDecl()));
1740b57cec5SDimitry Andric   }
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
1770b57cec5SDimitry Andric                                       DeclaratorDecl *DD) override {
1780b57cec5SDimitry Andric     TD = TD->getCanonicalDecl();
1790b57cec5SDimitry Andric     DD = cast<DeclaratorDecl>(DD->getCanonicalDecl());
1800b57cec5SDimitry Andric     DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
1810b57cec5SDimitry Andric     if (!I)
1820b57cec5SDimitry Andric       I = DD;
1830b57cec5SDimitry Andric   }
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
1860b57cec5SDimitry Andric     return UnnamedTagDeclToDeclaratorDecl.lookup(
1870b57cec5SDimitry Andric         const_cast<TagDecl *>(TD->getCanonicalDecl()));
1880b57cec5SDimitry Andric   }
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric   std::unique_ptr<MangleNumberingContext>
1910b57cec5SDimitry Andric   createMangleNumberingContext() const override {
192d409305fSDimitry Andric     if (Context.getLangOpts().CUDA && Context.getAuxTargetInfo()) {
193d409305fSDimitry Andric       assert(DeviceMangler && "Missing device mangler");
194d409305fSDimitry Andric       return std::make_unique<MSHIPNumberingContext>(DeviceMangler.get());
195349cc55cSDimitry Andric     } else if (Context.getLangOpts().isSYCL()) {
196349cc55cSDimitry Andric       assert(DeviceMangler && "Missing device mangler");
197349cc55cSDimitry Andric       return std::make_unique<MSSYCLNumberingContext>(DeviceMangler.get());
198d409305fSDimitry Andric     }
199349cc55cSDimitry Andric 
200a7dea167SDimitry Andric     return std::make_unique<MicrosoftNumberingContext>();
2010b57cec5SDimitry Andric   }
2020b57cec5SDimitry Andric };
2030b57cec5SDimitry Andric }
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric // getNumBases() seems to only give us the number of direct bases, and not the
2060b57cec5SDimitry Andric // total.  This function tells us if we inherit from anybody that uses MI, or if
2070b57cec5SDimitry Andric // we have a non-primary base class, which uses the multiple inheritance model.
2080b57cec5SDimitry Andric static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
2090b57cec5SDimitry Andric   while (RD->getNumBases() > 0) {
2100b57cec5SDimitry Andric     if (RD->getNumBases() > 1)
2110b57cec5SDimitry Andric       return true;
2120b57cec5SDimitry Andric     assert(RD->getNumBases() == 1);
2130b57cec5SDimitry Andric     const CXXRecordDecl *Base =
2140b57cec5SDimitry Andric         RD->bases_begin()->getType()->getAsCXXRecordDecl();
2150b57cec5SDimitry Andric     if (RD->isPolymorphic() && !Base->isPolymorphic())
2160b57cec5SDimitry Andric       return true;
2170b57cec5SDimitry Andric     RD = Base;
2180b57cec5SDimitry Andric   }
2190b57cec5SDimitry Andric   return false;
2200b57cec5SDimitry Andric }
2210b57cec5SDimitry Andric 
222480093f4SDimitry Andric MSInheritanceModel CXXRecordDecl::calculateInheritanceModel() const {
2230b57cec5SDimitry Andric   if (!hasDefinition() || isParsingBaseSpecifiers())
224480093f4SDimitry Andric     return MSInheritanceModel::Unspecified;
2250b57cec5SDimitry Andric   if (getNumVBases() > 0)
226480093f4SDimitry Andric     return MSInheritanceModel::Virtual;
2270b57cec5SDimitry Andric   if (usesMultipleInheritanceModel(this))
228480093f4SDimitry Andric     return MSInheritanceModel::Multiple;
229480093f4SDimitry Andric   return MSInheritanceModel::Single;
2300b57cec5SDimitry Andric }
2310b57cec5SDimitry Andric 
232480093f4SDimitry Andric MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
2330b57cec5SDimitry Andric   MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
2340b57cec5SDimitry Andric   assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
235480093f4SDimitry Andric   return IA->getInheritanceModel();
2360b57cec5SDimitry Andric }
2370b57cec5SDimitry Andric 
238480093f4SDimitry Andric bool CXXRecordDecl::nullFieldOffsetIsZero() const {
239480093f4SDimitry Andric   return !inheritanceModelHasOnlyOneField(/*IsMemberFunction=*/false,
240480093f4SDimitry Andric                                           getMSInheritanceModel()) ||
241480093f4SDimitry Andric          (hasDefinition() && isPolymorphic());
242480093f4SDimitry Andric }
243480093f4SDimitry Andric 
244480093f4SDimitry Andric MSVtorDispMode CXXRecordDecl::getMSVtorDispMode() const {
2450b57cec5SDimitry Andric   if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
2460b57cec5SDimitry Andric     return VDA->getVtorDispMode();
247480093f4SDimitry Andric   return getASTContext().getLangOpts().getVtorDispMode();
2480b57cec5SDimitry Andric }
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric // Returns the number of pointer and integer slots used to represent a member
2510b57cec5SDimitry Andric // pointer in the MS C++ ABI.
2520b57cec5SDimitry Andric //
2530b57cec5SDimitry Andric // Member function pointers have the following general form;  however, fields
2540b57cec5SDimitry Andric // are dropped as permitted (under the MSVC interpretation) by the inheritance
2550b57cec5SDimitry Andric // model of the actual class.
2560b57cec5SDimitry Andric //
2570b57cec5SDimitry Andric //   struct {
2580b57cec5SDimitry Andric //     // A pointer to the member function to call.  If the member function is
2590b57cec5SDimitry Andric //     // virtual, this will be a thunk that forwards to the appropriate vftable
2600b57cec5SDimitry Andric //     // slot.
2610b57cec5SDimitry Andric //     void *FunctionPointerOrVirtualThunk;
2620b57cec5SDimitry Andric //
2630b57cec5SDimitry Andric //     // An offset to add to the address of the vbtable pointer after
2640b57cec5SDimitry Andric //     // (possibly) selecting the virtual base but before resolving and calling
2650b57cec5SDimitry Andric //     // the function.
2660b57cec5SDimitry Andric //     // Only needed if the class has any virtual bases or bases at a non-zero
2670b57cec5SDimitry Andric //     // offset.
2680b57cec5SDimitry Andric //     int NonVirtualBaseAdjustment;
2690b57cec5SDimitry Andric //
2700b57cec5SDimitry Andric //     // The offset of the vb-table pointer within the object.  Only needed for
2710b57cec5SDimitry Andric //     // incomplete types.
2720b57cec5SDimitry Andric //     int VBPtrOffset;
2730b57cec5SDimitry Andric //
2740b57cec5SDimitry Andric //     // An offset within the vb-table that selects the virtual base containing
2750b57cec5SDimitry Andric //     // the member.  Loading from this offset produces a new offset that is
2760b57cec5SDimitry Andric //     // added to the address of the vb-table pointer to produce the base.
2770b57cec5SDimitry Andric //     int VirtualBaseAdjustmentOffset;
2780b57cec5SDimitry Andric //   };
2790b57cec5SDimitry Andric static std::pair<unsigned, unsigned>
2800b57cec5SDimitry Andric getMSMemberPointerSlots(const MemberPointerType *MPT) {
2810b57cec5SDimitry Andric   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
282480093f4SDimitry Andric   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
2830b57cec5SDimitry Andric   unsigned Ptrs = 0;
2840b57cec5SDimitry Andric   unsigned Ints = 0;
2850b57cec5SDimitry Andric   if (MPT->isMemberFunctionPointer())
2860b57cec5SDimitry Andric     Ptrs = 1;
2870b57cec5SDimitry Andric   else
2880b57cec5SDimitry Andric     Ints = 1;
289480093f4SDimitry Andric   if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
2900b57cec5SDimitry Andric                                           Inheritance))
2910b57cec5SDimitry Andric     Ints++;
292480093f4SDimitry Andric   if (inheritanceModelHasVBPtrOffsetField(Inheritance))
2930b57cec5SDimitry Andric     Ints++;
294480093f4SDimitry Andric   if (inheritanceModelHasVBTableOffsetField(Inheritance))
2950b57cec5SDimitry Andric     Ints++;
2960b57cec5SDimitry Andric   return std::make_pair(Ptrs, Ints);
2970b57cec5SDimitry Andric }
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
3000b57cec5SDimitry Andric     const MemberPointerType *MPT) const {
3010b57cec5SDimitry Andric   // The nominal struct is laid out with pointers followed by ints and aligned
3020b57cec5SDimitry Andric   // to a pointer width if any are present and an int width otherwise.
3030b57cec5SDimitry Andric   const TargetInfo &Target = Context.getTargetInfo();
304bdd1243dSDimitry Andric   unsigned PtrSize = Target.getPointerWidth(LangAS::Default);
3050b57cec5SDimitry Andric   unsigned IntSize = Target.getIntWidth();
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric   unsigned Ptrs, Ints;
3080b57cec5SDimitry Andric   std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
3090b57cec5SDimitry Andric   MemberPointerInfo MPI;
3100b57cec5SDimitry Andric   MPI.HasPadding = false;
3110b57cec5SDimitry Andric   MPI.Width = Ptrs * PtrSize + Ints * IntSize;
3120b57cec5SDimitry Andric 
3130b57cec5SDimitry Andric   // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
3140b57cec5SDimitry Andric   // 8 bytes.  However, __alignof usually returns 4 for data memptrs and 8 for
3150b57cec5SDimitry Andric   // function memptrs.
3160b57cec5SDimitry Andric   if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
3170b57cec5SDimitry Andric     MPI.Align = 64;
3180b57cec5SDimitry Andric   else if (Ptrs)
319bdd1243dSDimitry Andric     MPI.Align = Target.getPointerAlign(LangAS::Default);
3200b57cec5SDimitry Andric   else
3210b57cec5SDimitry Andric     MPI.Align = Target.getIntAlign();
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric   if (Target.getTriple().isArch64Bit()) {
3240b57cec5SDimitry Andric     MPI.Width = llvm::alignTo(MPI.Width, MPI.Align);
3250b57cec5SDimitry Andric     MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize);
3260b57cec5SDimitry Andric   }
3270b57cec5SDimitry Andric   return MPI;
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
3310b57cec5SDimitry Andric   return new MicrosoftCXXABI(Ctx);
3320b57cec5SDimitry Andric }
333