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 { 31942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Klecknerpublic: 32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned getManglingNumber(const VarDecl *VD, 33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned MSLocalManglingNumber) override { 34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSLocalManglingNumber; 35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 36942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned getManglingNumber(const TagDecl *TD, 38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned MSLocalManglingNumber) override { 39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSLocalManglingNumber; 40942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner } 41942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner}; 42942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 43071cc7deffad608165b1ddd5263e8bf181861520Charles Davisclass MicrosoftCXXABI : public CXXABI { 44071cc7deffad608165b1ddd5263e8bf181861520Charles Davis ASTContext &Context; 45071cc7deffad608165b1ddd5263e8bf181861520Charles Davispublic: 46071cc7deffad608165b1ddd5263e8bf181861520Charles Davis MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { } 47071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 4884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner std::pair<uint64_t, unsigned> 49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override; 50424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis 51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CallingConv getDefaultMethodCallConv(bool isVariadic) const override { 52a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer if (!isVariadic && 53a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86) 54424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis return CC_X86ThisCall; 55a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer return CC_C; 56424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis } 57dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isNearlyEmpty(const CXXRecordDecl *RD) const override { 59dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson // FIXME: Audit the corners 60dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson if (!RD->isDynamicClass()) 61dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson return false; 62dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson 63dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 64dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson 65dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson // In the Microsoft ABI, classes can have one or two vtable pointers. 665c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck CharUnits PointerSize = 67bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 685c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck return Layout.getNonVirtualSize() == PointerSize || 695c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck Layout.getNonVirtualSize() == PointerSize * 2; 70dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson } 71942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MangleNumberingContext *createMangleNumberingContext() const override { 73942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner return new MicrosoftNumberingContext(); 74942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner } 75071cc7deffad608165b1ddd5263e8bf181861520Charles Davis}; 76071cc7deffad608165b1ddd5263e8bf181861520Charles Davis} 77071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 7884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner// getNumBases() seems to only give us the number of direct bases, and not the 7984e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner// total. This function tells us if we inherit from anybody that uses MI, or if 8084e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner// we have a non-primary base class, which uses the multiple inheritance model. 81a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramerstatic bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) { 8284e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner while (RD->getNumBases() > 0) { 8384e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner if (RD->getNumBases() > 1) 8484e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner return true; 8584e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner assert(RD->getNumBases() == 1); 86a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer const CXXRecordDecl *Base = 87a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer RD->bases_begin()->getType()->getAsCXXRecordDecl(); 8884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner if (RD->isPolymorphic() && !Base->isPolymorphic()) 8984e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner return true; 9084e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner RD = Base; 9184e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner } 9284e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner return false; 9384e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner} 9484e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner 95651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const { 96ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (!hasDefinition() || isParsingBaseSpecifiers()) 97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSInheritanceAttr::Keyword_unspecified_inheritance; 98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (getNumVBases() > 0) 99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSInheritanceAttr::Keyword_virtual_inheritance; 100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (usesMultipleInheritanceModel(this)) 101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSInheritanceAttr::Keyword_multiple_inheritance; 102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSInheritanceAttr::Keyword_single_inheritance; 1034410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner} 10484e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner 105651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMSInheritanceAttr::Spelling 106651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesCXXRecordDecl::getMSInheritanceModel() const { 107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>(); 108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!"); 109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return IA->getSemanticSpelling(); 110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 112651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const { 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>()) 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return VDA->getVtorDispMode(); 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode); 1164410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner} 1174410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner 1184410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// Returns the number of pointer and integer slots used to represent a member 1194410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// pointer in the MS C++ ABI. 1204410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 1214410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// Member function pointers have the following general form; however, fields 1224410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// are dropped as permitted (under the MSVC interpretation) by the inheritance 1234410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// model of the actual class. 1244410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 1254410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// struct { 1264410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // A pointer to the member function to call. If the member function is 1274410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // virtual, this will be a thunk that forwards to the appropriate vftable 1284410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // slot. 1294410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// void *FunctionPointerOrVirtualThunk; 1304410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 1314410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // An offset to add to the address of the vbtable pointer after (possibly) 1324410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // selecting the virtual base but before resolving and calling the function. 1334410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // Only needed if the class has any virtual bases or bases at a non-zero 1344410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // offset. 1354410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// int NonVirtualBaseAdjustment; 1364410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// // The offset of the vb-table pointer within the object. Only needed for 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// // incomplete types. 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// int VBPtrOffset; 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 1414410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // An offset within the vb-table that selects the virtual base containing 1424410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // the member. Loading from this offset produces a new offset that is 1434410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // added to the address of the vb-table pointer to produce the base. 1444410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// int VirtualBaseAdjustmentOffset; 1454410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// }; 146a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerstatic std::pair<unsigned, unsigned> 147a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknergetMSMemberPointerSlots(const MemberPointerType *MPT) { 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned Ptrs = 0; 1514410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned Ints = 0; 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MPT->isMemberFunctionPointer()) 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Ptrs = 1; 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Ints = 1; 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(), 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Inheritance)) 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Ints++; 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) 160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Ints++; 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance)) 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Ints++; 1634410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner return std::make_pair(Ptrs, Ints); 1644410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner} 16584e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner 166a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramerstd::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign( 167a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer const MemberPointerType *MPT) const { 1684410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner const TargetInfo &Target = Context.getTargetInfo(); 1694410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner assert(Target.getTriple().getArch() == llvm::Triple::x86 || 1704410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner Target.getTriple().getArch() == llvm::Triple::x86_64); 1714410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned Ptrs, Ints; 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT); 1734410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner // The nominal struct is laid out with pointers followed by ints and aligned 1744410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner // to a pointer width if any are present and an int width otherwise. 1754410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned PtrSize = Target.getPointerWidth(0); 1764410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned IntSize = Target.getIntWidth(); 1774410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner uint64_t Width = Ptrs * PtrSize + Ints * IntSize; 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned Align; 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // When MSVC does x86_32 record layout, it aligns aggregate member pointers to 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // function memptrs. 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Ptrs + Ints > 1 && Target.getTriple().getArch() == llvm::Triple::x86) 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Align = 8 * 8; 185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if (Ptrs) 186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Align = Target.getPointerAlign(0); 187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else 188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Align = Target.getIntAlign(); 189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Target.getTriple().getArch() == llvm::Triple::x86_64) 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Width = llvm::RoundUpToAlignment(Width, Align); 19284e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner return std::make_pair(Width, Align); 193071cc7deffad608165b1ddd5263e8bf181861520Charles Davis} 194071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 195071cc7deffad608165b1ddd5263e8bf181861520Charles DavisCXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) { 196071cc7deffad608165b1ddd5263e8bf181861520Charles Davis return new MicrosoftCXXABI(Ctx); 197071cc7deffad608165b1ddd5263e8bf181861520Charles Davis} 198071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 199