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
getManglingNumber(const CXXMethodDecl * CallOperator)400b57cec5SDimitry Andric unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
410b57cec5SDimitry Andric return ++LambdaManglingNumber;
420b57cec5SDimitry Andric }
430b57cec5SDimitry Andric
getManglingNumber(const BlockDecl * BD)440b57cec5SDimitry Andric unsigned getManglingNumber(const BlockDecl *BD) override {
450b57cec5SDimitry Andric const Type *Ty = nullptr;
460b57cec5SDimitry Andric return ++ManglingNumbers[Ty];
470b57cec5SDimitry Andric }
480b57cec5SDimitry Andric
getStaticLocalNumber(const VarDecl * VD)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
getManglingNumber(const VarDecl * VD,unsigned MSLocalManglingNumber)550b57cec5SDimitry Andric unsigned getManglingNumber(const VarDecl *VD,
560b57cec5SDimitry Andric unsigned MSLocalManglingNumber) override {
570b57cec5SDimitry Andric return MSLocalManglingNumber;
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric
getManglingNumber(const TagDecl * TD,unsigned MSLocalManglingNumber)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;
MSHIPNumberingContext(MangleContext * DeviceMangler)71d409305fSDimitry Andric MSHIPNumberingContext(MangleContext *DeviceMangler) {
72d409305fSDimitry Andric DeviceCtx = createItaniumNumberingContext(DeviceMangler);
73d409305fSDimitry Andric }
74d409305fSDimitry Andric
getDeviceManglingNumber(const CXXMethodDecl * CallOperator)75d409305fSDimitry Andric unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
76d409305fSDimitry Andric return DeviceCtx->getManglingNumber(CallOperator);
77d409305fSDimitry Andric }
7881ad6265SDimitry Andric
getManglingNumber(const TagDecl * TD,unsigned MSLocalManglingNumber)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:
MSSYCLNumberingContext(MangleContext * DeviceMangler)98349cc55cSDimitry Andric MSSYCLNumberingContext(MangleContext *DeviceMangler) {
99349cc55cSDimitry Andric DeviceCtx = createItaniumNumberingContext(DeviceMangler);
100349cc55cSDimitry Andric }
101349cc55cSDimitry Andric
getDeviceManglingNumber(const CXXMethodDecl * CallOperator)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:
MicrosoftCXXABI(ASTContext & Ctx)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
getDefaultMethodCallConv(bool isVariadic) const1380b57cec5SDimitry 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
isNearlyEmpty(const CXXRecordDecl * RD) const1450b57cec5SDimitry 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 *
getCopyConstructorForExceptionObject(CXXRecordDecl * RD)1500b57cec5SDimitry Andric getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
1510b57cec5SDimitry Andric return RecordToCopyCtor[RD];
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric
1540b57cec5SDimitry Andric void
addCopyConstructorForExceptionObject(CXXRecordDecl * RD,CXXConstructorDecl * CD)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
addTypedefNameForUnnamedTagDecl(TagDecl * TD,TypedefNameDecl * DD)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
getTypedefNameForUnnamedTagDecl(const TagDecl * TD)1710b57cec5SDimitry Andric TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
1720b57cec5SDimitry Andric return UnnamedTagDeclToTypedefNameDecl.lookup(
1730b57cec5SDimitry Andric const_cast<TagDecl *>(TD->getCanonicalDecl()));
1740b57cec5SDimitry Andric }
1750b57cec5SDimitry Andric
addDeclaratorForUnnamedTagDecl(TagDecl * TD,DeclaratorDecl * DD)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
getDeclaratorForUnnamedTagDecl(const TagDecl * TD)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>
createMangleNumberingContext() const1910b57cec5SDimitry 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.
usesMultipleInheritanceModel(const CXXRecordDecl * RD)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
calculateInheritanceModel() const222480093f4SDimitry 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
getMSInheritanceModel() const232480093f4SDimitry 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
nullFieldOffsetIsZero() const238480093f4SDimitry Andric bool CXXRecordDecl::nullFieldOffsetIsZero() const {
239480093f4SDimitry Andric return !inheritanceModelHasOnlyOneField(/*IsMemberFunction=*/false,
240480093f4SDimitry Andric getMSInheritanceModel()) ||
241480093f4SDimitry Andric (hasDefinition() && isPolymorphic());
242480093f4SDimitry Andric }
243480093f4SDimitry Andric
getMSVtorDispMode() const244480093f4SDimitry 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>
getMSMemberPointerSlots(const MemberPointerType * MPT)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
getMemberPointerInfo(const MemberPointerType * MPT) const2990b57cec5SDimitry 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
CreateMicrosoftCXXABI(ASTContext & Ctx)3300b57cec5SDimitry Andric CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
3310b57cec5SDimitry Andric return new MicrosoftCXXABI(Ctx);
3320b57cec5SDimitry Andric }
333