1*f4a2713aSLionel Sambuc //===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc // 10*f4a2713aSLionel Sambuc // This provides C++ AST support targeting the Microsoft Visual C++ 11*f4a2713aSLionel Sambuc // ABI. 12*f4a2713aSLionel Sambuc // 13*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 14*f4a2713aSLionel Sambuc 15*f4a2713aSLionel Sambuc #include "CXXABI.h" 16*f4a2713aSLionel Sambuc #include "clang/AST/Attr.h" 17*f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h" 18*f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h" 19*f4a2713aSLionel Sambuc #include "clang/AST/MangleNumberingContext.h" 20*f4a2713aSLionel Sambuc #include "clang/AST/RecordLayout.h" 21*f4a2713aSLionel Sambuc #include "clang/AST/Type.h" 22*f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h" 23*f4a2713aSLionel Sambuc 24*f4a2713aSLionel Sambuc using namespace clang; 25*f4a2713aSLionel Sambuc 26*f4a2713aSLionel Sambuc namespace { 27*f4a2713aSLionel Sambuc 28*f4a2713aSLionel Sambuc /// \brief Numbers things which need to correspond across multiple TUs. 29*f4a2713aSLionel Sambuc /// Typically these are things like static locals, lambdas, or blocks. 30*f4a2713aSLionel Sambuc class MicrosoftNumberingContext : public MangleNumberingContext { 31*f4a2713aSLionel Sambuc unsigned NumStaticLocals; 32*f4a2713aSLionel Sambuc 33*f4a2713aSLionel Sambuc public: 34*f4a2713aSLionel Sambuc MicrosoftNumberingContext() : NumStaticLocals(0) { } 35*f4a2713aSLionel Sambuc 36*f4a2713aSLionel Sambuc /// Static locals are numbered by source order. 37*f4a2713aSLionel Sambuc virtual unsigned getManglingNumber(const VarDecl *VD) { 38*f4a2713aSLionel Sambuc assert(VD->isStaticLocal()); 39*f4a2713aSLionel Sambuc return ++NumStaticLocals; 40*f4a2713aSLionel Sambuc } 41*f4a2713aSLionel Sambuc }; 42*f4a2713aSLionel Sambuc 43*f4a2713aSLionel Sambuc class MicrosoftCXXABI : public CXXABI { 44*f4a2713aSLionel Sambuc ASTContext &Context; 45*f4a2713aSLionel Sambuc public: 46*f4a2713aSLionel Sambuc MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { } 47*f4a2713aSLionel Sambuc 48*f4a2713aSLionel Sambuc std::pair<uint64_t, unsigned> 49*f4a2713aSLionel Sambuc getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const; 50*f4a2713aSLionel Sambuc 51*f4a2713aSLionel Sambuc CallingConv getDefaultMethodCallConv(bool isVariadic) const { 52*f4a2713aSLionel Sambuc if (!isVariadic && 53*f4a2713aSLionel Sambuc Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86) 54*f4a2713aSLionel Sambuc return CC_X86ThisCall; 55*f4a2713aSLionel Sambuc return CC_C; 56*f4a2713aSLionel Sambuc } 57*f4a2713aSLionel Sambuc 58*f4a2713aSLionel Sambuc bool isNearlyEmpty(const CXXRecordDecl *RD) const { 59*f4a2713aSLionel Sambuc // FIXME: Audit the corners 60*f4a2713aSLionel Sambuc if (!RD->isDynamicClass()) 61*f4a2713aSLionel Sambuc return false; 62*f4a2713aSLionel Sambuc 63*f4a2713aSLionel Sambuc const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 64*f4a2713aSLionel Sambuc 65*f4a2713aSLionel Sambuc // In the Microsoft ABI, classes can have one or two vtable pointers. 66*f4a2713aSLionel Sambuc CharUnits PointerSize = 67*f4a2713aSLionel Sambuc Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 68*f4a2713aSLionel Sambuc return Layout.getNonVirtualSize() == PointerSize || 69*f4a2713aSLionel Sambuc Layout.getNonVirtualSize() == PointerSize * 2; 70*f4a2713aSLionel Sambuc } 71*f4a2713aSLionel Sambuc 72*f4a2713aSLionel Sambuc MangleNumberingContext *createMangleNumberingContext() const { 73*f4a2713aSLionel Sambuc return new MicrosoftNumberingContext(); 74*f4a2713aSLionel Sambuc } 75*f4a2713aSLionel Sambuc }; 76*f4a2713aSLionel Sambuc } 77*f4a2713aSLionel Sambuc 78*f4a2713aSLionel Sambuc // getNumBases() seems to only give us the number of direct bases, and not the 79*f4a2713aSLionel Sambuc // total. This function tells us if we inherit from anybody that uses MI, or if 80*f4a2713aSLionel Sambuc // we have a non-primary base class, which uses the multiple inheritance model. 81*f4a2713aSLionel Sambuc static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) { 82*f4a2713aSLionel Sambuc while (RD->getNumBases() > 0) { 83*f4a2713aSLionel Sambuc if (RD->getNumBases() > 1) 84*f4a2713aSLionel Sambuc return true; 85*f4a2713aSLionel Sambuc assert(RD->getNumBases() == 1); 86*f4a2713aSLionel Sambuc const CXXRecordDecl *Base = 87*f4a2713aSLionel Sambuc RD->bases_begin()->getType()->getAsCXXRecordDecl(); 88*f4a2713aSLionel Sambuc if (RD->isPolymorphic() && !Base->isPolymorphic()) 89*f4a2713aSLionel Sambuc return true; 90*f4a2713aSLionel Sambuc RD = Base; 91*f4a2713aSLionel Sambuc } 92*f4a2713aSLionel Sambuc return false; 93*f4a2713aSLionel Sambuc } 94*f4a2713aSLionel Sambuc 95*f4a2713aSLionel Sambuc static MSInheritanceModel MSInheritanceAttrToModel(attr::Kind Kind) { 96*f4a2713aSLionel Sambuc switch (Kind) { 97*f4a2713aSLionel Sambuc default: llvm_unreachable("expected MS inheritance attribute"); 98*f4a2713aSLionel Sambuc case attr::SingleInheritance: return MSIM_Single; 99*f4a2713aSLionel Sambuc case attr::MultipleInheritance: return MSIM_Multiple; 100*f4a2713aSLionel Sambuc case attr::VirtualInheritance: return MSIM_Virtual; 101*f4a2713aSLionel Sambuc case attr::UnspecifiedInheritance: return MSIM_Unspecified; 102*f4a2713aSLionel Sambuc } 103*f4a2713aSLionel Sambuc } 104*f4a2713aSLionel Sambuc 105*f4a2713aSLionel Sambuc MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const { 106*f4a2713aSLionel Sambuc if (Attr *IA = this->getAttr<MSInheritanceAttr>()) 107*f4a2713aSLionel Sambuc return MSInheritanceAttrToModel(IA->getKind()); 108*f4a2713aSLionel Sambuc // If there was no explicit attribute, the record must be defined already, and 109*f4a2713aSLionel Sambuc // we can figure out the inheritance model from its other properties. 110*f4a2713aSLionel Sambuc if (this->getNumVBases() > 0) 111*f4a2713aSLionel Sambuc return MSIM_Virtual; 112*f4a2713aSLionel Sambuc if (usesMultipleInheritanceModel(this)) 113*f4a2713aSLionel Sambuc return this->isPolymorphic() ? MSIM_MultiplePolymorphic : MSIM_Multiple; 114*f4a2713aSLionel Sambuc return this->isPolymorphic() ? MSIM_SinglePolymorphic : MSIM_Single; 115*f4a2713aSLionel Sambuc } 116*f4a2713aSLionel Sambuc 117*f4a2713aSLionel Sambuc // Returns the number of pointer and integer slots used to represent a member 118*f4a2713aSLionel Sambuc // pointer in the MS C++ ABI. 119*f4a2713aSLionel Sambuc // 120*f4a2713aSLionel Sambuc // Member function pointers have the following general form; however, fields 121*f4a2713aSLionel Sambuc // are dropped as permitted (under the MSVC interpretation) by the inheritance 122*f4a2713aSLionel Sambuc // model of the actual class. 123*f4a2713aSLionel Sambuc // 124*f4a2713aSLionel Sambuc // struct { 125*f4a2713aSLionel Sambuc // // A pointer to the member function to call. If the member function is 126*f4a2713aSLionel Sambuc // // virtual, this will be a thunk that forwards to the appropriate vftable 127*f4a2713aSLionel Sambuc // // slot. 128*f4a2713aSLionel Sambuc // void *FunctionPointerOrVirtualThunk; 129*f4a2713aSLionel Sambuc // 130*f4a2713aSLionel Sambuc // // An offset to add to the address of the vbtable pointer after (possibly) 131*f4a2713aSLionel Sambuc // // selecting the virtual base but before resolving and calling the function. 132*f4a2713aSLionel Sambuc // // Only needed if the class has any virtual bases or bases at a non-zero 133*f4a2713aSLionel Sambuc // // offset. 134*f4a2713aSLionel Sambuc // int NonVirtualBaseAdjustment; 135*f4a2713aSLionel Sambuc // 136*f4a2713aSLionel Sambuc // // An offset within the vb-table that selects the virtual base containing 137*f4a2713aSLionel Sambuc // // the member. Loading from this offset produces a new offset that is 138*f4a2713aSLionel Sambuc // // added to the address of the vb-table pointer to produce the base. 139*f4a2713aSLionel Sambuc // int VirtualBaseAdjustmentOffset; 140*f4a2713aSLionel Sambuc // 141*f4a2713aSLionel Sambuc // // The offset of the vb-table pointer within the object. Only needed for 142*f4a2713aSLionel Sambuc // // incomplete types. 143*f4a2713aSLionel Sambuc // int VBPtrOffset; 144*f4a2713aSLionel Sambuc // }; 145*f4a2713aSLionel Sambuc static std::pair<unsigned, unsigned> 146*f4a2713aSLionel Sambuc getMSMemberPointerSlots(const MemberPointerType *MPT) { 147*f4a2713aSLionel Sambuc const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 148*f4a2713aSLionel Sambuc MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 149*f4a2713aSLionel Sambuc unsigned Ptrs; 150*f4a2713aSLionel Sambuc unsigned Ints = 0; 151*f4a2713aSLionel Sambuc if (MPT->isMemberFunctionPointer()) { 152*f4a2713aSLionel Sambuc // Member function pointers are a struct of a function pointer followed by a 153*f4a2713aSLionel Sambuc // variable number of ints depending on the inheritance model used. The 154*f4a2713aSLionel Sambuc // function pointer is a real function if it is non-virtual and a vftable 155*f4a2713aSLionel Sambuc // slot thunk if it is virtual. The ints select the object base passed for 156*f4a2713aSLionel Sambuc // the 'this' pointer. 157*f4a2713aSLionel Sambuc Ptrs = 1; // First slot is always a function pointer. 158*f4a2713aSLionel Sambuc switch (Inheritance) { 159*f4a2713aSLionel Sambuc case MSIM_Unspecified: ++Ints; // VBTableOffset 160*f4a2713aSLionel Sambuc case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset 161*f4a2713aSLionel Sambuc case MSIM_MultiplePolymorphic: 162*f4a2713aSLionel Sambuc case MSIM_Multiple: ++Ints; // NonVirtualBaseAdjustment 163*f4a2713aSLionel Sambuc case MSIM_SinglePolymorphic: 164*f4a2713aSLionel Sambuc case MSIM_Single: break; // Nothing 165*f4a2713aSLionel Sambuc } 166*f4a2713aSLionel Sambuc } else { 167*f4a2713aSLionel Sambuc // Data pointers are an aggregate of ints. The first int is an offset 168*f4a2713aSLionel Sambuc // followed by vbtable-related offsets. 169*f4a2713aSLionel Sambuc Ptrs = 0; 170*f4a2713aSLionel Sambuc switch (Inheritance) { 171*f4a2713aSLionel Sambuc case MSIM_Unspecified: ++Ints; // VBTableOffset 172*f4a2713aSLionel Sambuc case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset 173*f4a2713aSLionel Sambuc case MSIM_MultiplePolymorphic: 174*f4a2713aSLionel Sambuc case MSIM_Multiple: // Nothing 175*f4a2713aSLionel Sambuc case MSIM_SinglePolymorphic: 176*f4a2713aSLionel Sambuc case MSIM_Single: ++Ints; // Field offset 177*f4a2713aSLionel Sambuc } 178*f4a2713aSLionel Sambuc } 179*f4a2713aSLionel Sambuc return std::make_pair(Ptrs, Ints); 180*f4a2713aSLionel Sambuc } 181*f4a2713aSLionel Sambuc 182*f4a2713aSLionel Sambuc std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign( 183*f4a2713aSLionel Sambuc const MemberPointerType *MPT) const { 184*f4a2713aSLionel Sambuc const TargetInfo &Target = Context.getTargetInfo(); 185*f4a2713aSLionel Sambuc assert(Target.getTriple().getArch() == llvm::Triple::x86 || 186*f4a2713aSLionel Sambuc Target.getTriple().getArch() == llvm::Triple::x86_64); 187*f4a2713aSLionel Sambuc unsigned Ptrs, Ints; 188*f4a2713aSLionel Sambuc llvm::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT); 189*f4a2713aSLionel Sambuc // The nominal struct is laid out with pointers followed by ints and aligned 190*f4a2713aSLionel Sambuc // to a pointer width if any are present and an int width otherwise. 191*f4a2713aSLionel Sambuc unsigned PtrSize = Target.getPointerWidth(0); 192*f4a2713aSLionel Sambuc unsigned IntSize = Target.getIntWidth(); 193*f4a2713aSLionel Sambuc uint64_t Width = Ptrs * PtrSize + Ints * IntSize; 194*f4a2713aSLionel Sambuc unsigned Align = Ptrs > 0 ? Target.getPointerAlign(0) : Target.getIntAlign(); 195*f4a2713aSLionel Sambuc Width = llvm::RoundUpToAlignment(Width, Align); 196*f4a2713aSLionel Sambuc return std::make_pair(Width, Align); 197*f4a2713aSLionel Sambuc } 198*f4a2713aSLionel Sambuc 199*f4a2713aSLionel Sambuc CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) { 200*f4a2713aSLionel Sambuc return new MicrosoftCXXABI(Ctx); 201*f4a2713aSLionel Sambuc } 202*f4a2713aSLionel Sambuc 203