1071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===// 2071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// 3071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// The LLVM Compiler Infrastructure 4071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// 5071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// This file is distributed under the University of Illinois Open Source 6071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// License. See LICENSE.TXT for details. 7071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// 8071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//===----------------------------------------------------------------------===// 9071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// 10fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner// This provides C++ AST support targeting the Microsoft Visual C++ 11071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// ABI. 12071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// 13071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//===----------------------------------------------------------------------===// 14071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 15071cc7deffad608165b1ddd5263e8bf181861520Charles Davis#include "CXXABI.h" 16071cc7deffad608165b1ddd5263e8bf181861520Charles Davis#include "clang/AST/ASTContext.h" 17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/AST/Attr.h" 18071cc7deffad608165b1ddd5263e8bf181861520Charles Davis#include "clang/AST/DeclCXX.h" 19942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner#include "clang/AST/MangleNumberingContext.h" 20dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson#include "clang/AST/RecordLayout.h" 21dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson#include "clang/AST/Type.h" 22dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson#include "clang/Basic/TargetInfo.h" 23071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 24071cc7deffad608165b1ddd5263e8bf181861520Charles Davisusing namespace clang; 25071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 26071cc7deffad608165b1ddd5263e8bf181861520Charles Davisnamespace { 27942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 28942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner/// \brief Numbers things which need to correspond across multiple TUs. 29942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner/// Typically these are things like static locals, lambdas, or blocks. 30942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Klecknerclass MicrosoftNumberingContext : public MangleNumberingContext { 31176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::DenseMap<const Type *, unsigned> ManglingNumbers; 32176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unsigned LambdaManglingNumber; 33176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unsigned StaticLocalNumber; 34176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 35942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Klecknerpublic: 36176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines MicrosoftNumberingContext() 37176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines : MangleNumberingContext(), LambdaManglingNumber(0), 38176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StaticLocalNumber(0) {} 39176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 40176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { 41176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ++LambdaManglingNumber; 42176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 43176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 44176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unsigned getManglingNumber(const BlockDecl *BD) override { 45176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const Type *Ty = nullptr; 46176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ++ManglingNumbers[Ty]; 47176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 48176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 49176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unsigned getStaticLocalNumber(const VarDecl *VD) override { 50176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ++StaticLocalNumber; 51176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 52176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned getManglingNumber(const VarDecl *VD, 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned MSLocalManglingNumber) override { 55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSLocalManglingNumber; 56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 57942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned getManglingNumber(const TagDecl *TD, 59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned MSLocalManglingNumber) override { 60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSLocalManglingNumber; 61942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner } 62942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner}; 63942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 64071cc7deffad608165b1ddd5263e8bf181861520Charles Davisclass MicrosoftCXXABI : public CXXABI { 65071cc7deffad608165b1ddd5263e8bf181861520Charles Davis ASTContext &Context; 663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor; 673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar llvm::SmallDenseMap<std::pair<const CXXConstructorDecl *, unsigned>, Expr *> 683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CtorToDefaultArgExpr; 693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 70071cc7deffad608165b1ddd5263e8bf181861520Charles Davispublic: 71071cc7deffad608165b1ddd5263e8bf181861520Charles Davis MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { } 72071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 7384e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner std::pair<uint64_t, unsigned> 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override; 75424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis 76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CallingConv getDefaultMethodCallConv(bool isVariadic) const override { 77a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer if (!isVariadic && 78a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86) 79424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis return CC_X86ThisCall; 80a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer return CC_C; 81424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis } 82dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson 83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isNearlyEmpty(const CXXRecordDecl *RD) const override { 84dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson // FIXME: Audit the corners 85dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson if (!RD->isDynamicClass()) 86dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson return false; 87dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson 88dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 90dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson // In the Microsoft ABI, classes can have one or two vtable pointers. 913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CharUnits PointerSize = 923ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 935c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck return Layout.getNonVirtualSize() == PointerSize || 945c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck Layout.getNonVirtualSize() == PointerSize * 2; 953ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar void addDefaultArgExprForConstructor(const CXXConstructorDecl *CD, 983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar unsigned ParmIdx, Expr *DAE) override { 993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CtorToDefaultArgExpr[std::make_pair(CD, ParmIdx)] = DAE; 1003ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 1013ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1023ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD, 1033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar unsigned ParmIdx) override { 1043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return CtorToDefaultArgExpr[std::make_pair(CD, ParmIdx)]; 1053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 1063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar const CXXConstructorDecl * 1083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override { 1093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar return RecordToCopyCtor[RD]; 1103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 1113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar 1123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar void 1133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar addCopyConstructorForExceptionObject(CXXRecordDecl *RD, 1143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar CXXConstructorDecl *CD) override { 1153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert(CD != nullptr); 1163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD); 1173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar RecordToCopyCtor[RD] = CD; 1183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar } 119942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MangleNumberingContext *createMangleNumberingContext() const override { 121942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner return new MicrosoftNumberingContext(); 122942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner } 123071cc7deffad608165b1ddd5263e8bf181861520Charles Davis}; 124071cc7deffad608165b1ddd5263e8bf181861520Charles Davis} 125071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 12684e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner// getNumBases() seems to only give us the number of direct bases, and not the 12784e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner// total. This function tells us if we inherit from anybody that uses MI, or if 12884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner// we have a non-primary base class, which uses the multiple inheritance model. 129a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramerstatic bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) { 13084e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner while (RD->getNumBases() > 0) { 13184e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner if (RD->getNumBases() > 1) 13284e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner return true; 13384e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner assert(RD->getNumBases() == 1); 134a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer const CXXRecordDecl *Base = 135a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer RD->bases_begin()->getType()->getAsCXXRecordDecl(); 13684e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner if (RD->isPolymorphic() && !Base->isPolymorphic()) 13784e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner return true; 13884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner RD = Base; 13984e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner } 14084e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner return false; 14184e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner} 14284e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner 143651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const { 144c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!hasDefinition() || isParsingBaseSpecifiers()) 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSInheritanceAttr::Keyword_unspecified_inheritance; 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (getNumVBases() > 0) 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSInheritanceAttr::Keyword_virtual_inheritance; 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (usesMultipleInheritanceModel(this)) 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSInheritanceAttr::Keyword_multiple_inheritance; 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSInheritanceAttr::Keyword_single_inheritance; 1514410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner} 15284e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner 153651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMSInheritanceAttr::Spelling 154651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesCXXRecordDecl::getMSInheritanceModel() const { 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>(); 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!"); 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return IA->getSemanticSpelling(); 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 160651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const { 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>()) 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return VDA->getVtorDispMode(); 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode); 1644410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner} 1654410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner 1664410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// Returns the number of pointer and integer slots used to represent a member 1674410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// pointer in the MS C++ ABI. 1684410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 1694410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// Member function pointers have the following general form; however, fields 1704410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// are dropped as permitted (under the MSVC interpretation) by the inheritance 1714410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// model of the actual class. 1724410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 1734410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// struct { 1744410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // A pointer to the member function to call. If the member function is 1754410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // virtual, this will be a thunk that forwards to the appropriate vftable 1764410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // slot. 1774410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// void *FunctionPointerOrVirtualThunk; 1784410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 1794410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // An offset to add to the address of the vbtable pointer after (possibly) 1804410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // selecting the virtual base but before resolving and calling the function. 1814410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // Only needed if the class has any virtual bases or bases at a non-zero 1824410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // offset. 1834410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// int NonVirtualBaseAdjustment; 1844410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// // The offset of the vb-table pointer within the object. Only needed for 186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// // incomplete types. 187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// int VBPtrOffset; 188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 1894410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // An offset within the vb-table that selects the virtual base containing 1904410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // the member. Loading from this offset produces a new offset that is 1914410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // added to the address of the vb-table pointer to produce the base. 1924410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// int VirtualBaseAdjustmentOffset; 1934410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// }; 194a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerstatic std::pair<unsigned, unsigned> 195a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknergetMSMemberPointerSlots(const MemberPointerType *MPT) { 196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); 197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); 198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned Ptrs = 0; 1994410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned Ints = 0; 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MPT->isMemberFunctionPointer()) 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Ptrs = 1; 202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else 203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Ints = 1; 204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(), 205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Inheritance)) 206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Ints++; 207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Ints++; 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance)) 210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Ints++; 2114410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner return std::make_pair(Ptrs, Ints); 2124410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner} 21384e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner 214a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramerstd::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign( 215a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer const MemberPointerType *MPT) const { 2164410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner const TargetInfo &Target = Context.getTargetInfo(); 2174410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner assert(Target.getTriple().getArch() == llvm::Triple::x86 || 2184410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner Target.getTriple().getArch() == llvm::Triple::x86_64); 2194410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned Ptrs, Ints; 220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT); 2214410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner // The nominal struct is laid out with pointers followed by ints and aligned 2224410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner // to a pointer width if any are present and an int width otherwise. 2234410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned PtrSize = Target.getPointerWidth(0); 2244410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned IntSize = Target.getIntWidth(); 2254410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner uint64_t Width = Ptrs * PtrSize + Ints * IntSize; 226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned Align; 227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // When MSVC does x86_32 record layout, it aligns aggregate member pointers to 229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for 230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // function memptrs. 231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Ptrs + Ints > 1 && Target.getTriple().getArch() == llvm::Triple::x86) 232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Align = 8 * 8; 233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if (Ptrs) 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Align = Target.getPointerAlign(0); 235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Align = Target.getIntAlign(); 237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Target.getTriple().getArch() == llvm::Triple::x86_64) 239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Width = llvm::RoundUpToAlignment(Width, Align); 24084e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner return std::make_pair(Width, Align); 241071cc7deffad608165b1ddd5263e8bf181861520Charles Davis} 242071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 243071cc7deffad608165b1ddd5263e8bf181861520Charles DavisCXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) { 244071cc7deffad608165b1ddd5263e8bf181861520Charles Davis return new MicrosoftCXXABI(Ctx); 245071cc7deffad608165b1ddd5263e8bf181861520Charles Davis} 246071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 247