MicrosoftCXXABI.cpp revision 942f9fe11d3a9583eef6bc4ca2549b1f0d1694da
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" 1684e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner#include "clang/AST/Attr.h" 17071cc7deffad608165b1ddd5263e8bf181861520Charles Davis#include "clang/AST/ASTContext.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 Kleckner unsigned NumStaticLocals; 32942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 33942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Klecknerpublic: 34942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner MicrosoftNumberingContext() : NumStaticLocals(0) { } 35942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner 36942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner /// Static locals are numbered by source order. 37942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner virtual unsigned getManglingNumber(const VarDecl *VD) { 38942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner assert(VD->isStaticLocal()); 39942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner return ++NumStaticLocals; 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> 4984e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const; 50424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis 518f88a1dcc57cfe8580eb1558a783ad8499bfe8e0Timur Iskhodzhanov CallingConv getDefaultMethodCallConv(bool isVariadic) const { 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 58dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson bool isNearlyEmpty(const CXXRecordDecl *RD) const { 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 72942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner MangleNumberingContext *createMangleNumberingContext() const { 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 95a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramerstatic MSInheritanceModel MSInheritanceAttrToModel(attr::Kind Kind) { 964410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner switch (Kind) { 974410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner default: llvm_unreachable("expected MS inheritance attribute"); 98cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case attr::SingleInheritance: return MSIM_Single; 99cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case attr::MultipleInheritance: return MSIM_Multiple; 100cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case attr::VirtualInheritance: return MSIM_Virtual; 101cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case attr::UnspecifiedInheritance: return MSIM_Unspecified; 10284e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner } 1034410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner} 10484e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner 1054410489163931892b568f0a43bd49c430a3aa3f5Reid KlecknerMSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const { 106a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer if (Attr *IA = this->getAttr<MSInheritanceAttr>()) 1074410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner return MSInheritanceAttrToModel(IA->getKind()); 1084410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner // If there was no explicit attribute, the record must be defined already, and 1094410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner // we can figure out the inheritance model from its other properties. 1104410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner if (this->getNumVBases() > 0) 111cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner return MSIM_Virtual; 1124410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner if (usesMultipleInheritanceModel(this)) 113a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return this->isPolymorphic() ? MSIM_MultiplePolymorphic : MSIM_Multiple; 114a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return this->isPolymorphic() ? MSIM_SinglePolymorphic : MSIM_Single; 1154410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner} 1164410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner 1174410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// Returns the number of pointer and integer slots used to represent a member 1184410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// pointer in the MS C++ ABI. 1194410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 1204410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// Member function pointers have the following general form; however, fields 1214410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// are dropped as permitted (under the MSVC interpretation) by the inheritance 1224410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// model of the actual class. 1234410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 1244410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// struct { 1254410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // A pointer to the member function to call. If the member function is 1264410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // virtual, this will be a thunk that forwards to the appropriate vftable 1274410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // slot. 1284410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// void *FunctionPointerOrVirtualThunk; 1294410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 1304410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // An offset to add to the address of the vbtable pointer after (possibly) 1314410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // selecting the virtual base but before resolving and calling the function. 1324410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // Only needed if the class has any virtual bases or bases at a non-zero 1334410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // offset. 1344410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// int NonVirtualBaseAdjustment; 1354410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 1364410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // An offset within the vb-table that selects the virtual base containing 1374410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // the member. Loading from this offset produces a new offset that is 1384410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // added to the address of the vb-table pointer to produce the base. 1394410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// int VirtualBaseAdjustmentOffset; 1404410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// 1414410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // The offset of the vb-table pointer within the object. Only needed for 1424410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// // incomplete types. 143a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// int VBPtrOffset; 1444410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// }; 145a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerstatic std::pair<unsigned, unsigned> 146a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknergetMSMemberPointerSlots(const MemberPointerType *MPT) { 147a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 1484410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 1494410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned Ptrs; 1504410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned Ints = 0; 151a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MPT->isMemberFunctionPointer()) { 15284e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner // Member function pointers are a struct of a function pointer followed by a 15384e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner // variable number of ints depending on the inheritance model used. The 15484e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner // function pointer is a real function if it is non-virtual and a vftable 15584e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner // slot thunk if it is virtual. The ints select the object base passed for 15684e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner // the 'this' pointer. 1574410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner Ptrs = 1; // First slot is always a function pointer. 15884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner switch (Inheritance) { 159cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case MSIM_Unspecified: ++Ints; // VBTableOffset 160cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset 161a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner case MSIM_MultiplePolymorphic: 162cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case MSIM_Multiple: ++Ints; // NonVirtualBaseAdjustment 163a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner case MSIM_SinglePolymorphic: 164cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case MSIM_Single: break; // Nothing 16584e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner } 16684e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner } else { 16784e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner // Data pointers are an aggregate of ints. The first int is an offset 16884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner // followed by vbtable-related offsets. 1694410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner Ptrs = 0; 17084e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner switch (Inheritance) { 171cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case MSIM_Unspecified: ++Ints; // VBTableOffset 172cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset 173a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner case MSIM_MultiplePolymorphic: 174cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case MSIM_Multiple: // Nothing 175a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner case MSIM_SinglePolymorphic: 176cb428a1ac09dddf5ed3bf2a740f9ea31e9e11037Reid Kleckner case MSIM_Single: ++Ints; // Field offset 17784e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner } 17884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner } 1794410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner return std::make_pair(Ptrs, Ints); 1804410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner} 18184e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner 182a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramerstd::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign( 183a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer const MemberPointerType *MPT) const { 1844410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner const TargetInfo &Target = Context.getTargetInfo(); 1854410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner assert(Target.getTriple().getArch() == llvm::Triple::x86 || 1864410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner Target.getTriple().getArch() == llvm::Triple::x86_64); 1874410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned Ptrs, Ints; 188a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT); 1894410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner // The nominal struct is laid out with pointers followed by ints and aligned 1904410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner // to a pointer width if any are present and an int width otherwise. 1914410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned PtrSize = Target.getPointerWidth(0); 1924410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned IntSize = Target.getIntWidth(); 1934410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner uint64_t Width = Ptrs * PtrSize + Ints * IntSize; 1944410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner unsigned Align = Ptrs > 0 ? Target.getPointerAlign(0) : Target.getIntAlign(); 1954410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner Width = llvm::RoundUpToAlignment(Width, Align); 19684e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner return std::make_pair(Width, Align); 197071cc7deffad608165b1ddd5263e8bf181861520Charles Davis} 198071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 199071cc7deffad608165b1ddd5263e8bf181861520Charles DavisCXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) { 200071cc7deffad608165b1ddd5263e8bf181861520Charles Davis return new MicrosoftCXXABI(Ctx); 201071cc7deffad608165b1ddd5263e8bf181861520Charles Davis} 202071cc7deffad608165b1ddd5263e8bf181861520Charles Davis 203