1 //===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This provides C++ AST support targeting the Microsoft Visual C++ 11 // ABI. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "CXXABI.h" 16 #include "clang/AST/ASTContext.h" 17 #include "clang/AST/Attr.h" 18 #include "clang/AST/DeclCXX.h" 19 #include "clang/AST/MangleNumberingContext.h" 20 #include "clang/AST/RecordLayout.h" 21 #include "clang/AST/Type.h" 22 #include "clang/Basic/TargetInfo.h" 23 24 using namespace clang; 25 26 namespace { 27 28 /// \brief Numbers things which need to correspond across multiple TUs. 29 /// Typically these are things like static locals, lambdas, or blocks. 30 class MicrosoftNumberingContext : public MangleNumberingContext { 31 llvm::DenseMap<const Type *, unsigned> ManglingNumbers; 32 unsigned LambdaManglingNumber; 33 unsigned StaticLocalNumber; 34 unsigned StaticThreadlocalNumber; 35 36 public: 37 MicrosoftNumberingContext() 38 : MangleNumberingContext(), LambdaManglingNumber(0), 39 StaticLocalNumber(0), StaticThreadlocalNumber(0) {} 40 41 unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { 42 return ++LambdaManglingNumber; 43 } 44 45 unsigned getManglingNumber(const BlockDecl *BD) override { 46 const Type *Ty = nullptr; 47 return ++ManglingNumbers[Ty]; 48 } 49 50 unsigned getStaticLocalNumber(const VarDecl *VD) override { 51 if (VD->getTLSKind()) 52 return ++StaticThreadlocalNumber; 53 return ++StaticLocalNumber; 54 } 55 56 unsigned getManglingNumber(const VarDecl *VD, 57 unsigned MSLocalManglingNumber) override { 58 return MSLocalManglingNumber; 59 } 60 61 unsigned getManglingNumber(const TagDecl *TD, 62 unsigned MSLocalManglingNumber) override { 63 return MSLocalManglingNumber; 64 } 65 }; 66 67 class MicrosoftCXXABI : public CXXABI { 68 ASTContext &Context; 69 llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor; 70 71 llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *> 72 UnnamedTagDeclToDeclaratorDecl; 73 llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *> 74 UnnamedTagDeclToTypedefNameDecl; 75 76 public: 77 MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { } 78 79 MemberPointerInfo 80 getMemberPointerInfo(const MemberPointerType *MPT) const override; 81 82 CallingConv getDefaultMethodCallConv(bool isVariadic) const override { 83 if (!isVariadic && 84 Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86) 85 return CC_X86ThisCall; 86 return CC_C; 87 } 88 89 bool isNearlyEmpty(const CXXRecordDecl *RD) const override { 90 llvm_unreachable("unapplicable to the MS ABI"); 91 } 92 93 const CXXConstructorDecl * 94 getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override { 95 return RecordToCopyCtor[RD]; 96 } 97 98 void 99 addCopyConstructorForExceptionObject(CXXRecordDecl *RD, 100 CXXConstructorDecl *CD) override { 101 assert(CD != nullptr); 102 assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD); 103 RecordToCopyCtor[RD] = CD; 104 } 105 106 void addTypedefNameForUnnamedTagDecl(TagDecl *TD, 107 TypedefNameDecl *DD) override { 108 TD = TD->getCanonicalDecl(); 109 DD = cast<TypedefNameDecl>(DD->getCanonicalDecl()); 110 TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD]; 111 if (!I) 112 I = DD; 113 } 114 115 TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override { 116 return UnnamedTagDeclToTypedefNameDecl.lookup( 117 const_cast<TagDecl *>(TD->getCanonicalDecl())); 118 } 119 120 void addDeclaratorForUnnamedTagDecl(TagDecl *TD, 121 DeclaratorDecl *DD) override { 122 TD = TD->getCanonicalDecl(); 123 DD = cast<DeclaratorDecl>(DD->getCanonicalDecl()); 124 DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD]; 125 if (!I) 126 I = DD; 127 } 128 129 DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override { 130 return UnnamedTagDeclToDeclaratorDecl.lookup( 131 const_cast<TagDecl *>(TD->getCanonicalDecl())); 132 } 133 134 std::unique_ptr<MangleNumberingContext> 135 createMangleNumberingContext() const override { 136 return llvm::make_unique<MicrosoftNumberingContext>(); 137 } 138 }; 139 } 140 141 // getNumBases() seems to only give us the number of direct bases, and not the 142 // total. This function tells us if we inherit from anybody that uses MI, or if 143 // we have a non-primary base class, which uses the multiple inheritance model. 144 static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) { 145 while (RD->getNumBases() > 0) { 146 if (RD->getNumBases() > 1) 147 return true; 148 assert(RD->getNumBases() == 1); 149 const CXXRecordDecl *Base = 150 RD->bases_begin()->getType()->getAsCXXRecordDecl(); 151 if (RD->isPolymorphic() && !Base->isPolymorphic()) 152 return true; 153 RD = Base; 154 } 155 return false; 156 } 157 158 MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const { 159 if (!hasDefinition() || isParsingBaseSpecifiers()) 160 return MSInheritanceAttr::Keyword_unspecified_inheritance; 161 if (getNumVBases() > 0) 162 return MSInheritanceAttr::Keyword_virtual_inheritance; 163 if (usesMultipleInheritanceModel(this)) 164 return MSInheritanceAttr::Keyword_multiple_inheritance; 165 return MSInheritanceAttr::Keyword_single_inheritance; 166 } 167 168 MSInheritanceAttr::Spelling 169 CXXRecordDecl::getMSInheritanceModel() const { 170 MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>(); 171 assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!"); 172 return IA->getSemanticSpelling(); 173 } 174 175 MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const { 176 if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>()) 177 return VDA->getVtorDispMode(); 178 return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode); 179 } 180 181 // Returns the number of pointer and integer slots used to represent a member 182 // pointer in the MS C++ ABI. 183 // 184 // Member function pointers have the following general form; however, fields 185 // are dropped as permitted (under the MSVC interpretation) by the inheritance 186 // model of the actual class. 187 // 188 // struct { 189 // // A pointer to the member function to call. If the member function is 190 // // virtual, this will be a thunk that forwards to the appropriate vftable 191 // // slot. 192 // void *FunctionPointerOrVirtualThunk; 193 // 194 // // An offset to add to the address of the vbtable pointer after 195 // // (possibly) selecting the virtual base but before resolving and calling 196 // // the function. 197 // // Only needed if the class has any virtual bases or bases at a non-zero 198 // // offset. 199 // int NonVirtualBaseAdjustment; 200 // 201 // // The offset of the vb-table pointer within the object. Only needed for 202 // // incomplete types. 203 // int VBPtrOffset; 204 // 205 // // An offset within the vb-table that selects the virtual base containing 206 // // the member. Loading from this offset produces a new offset that is 207 // // added to the address of the vb-table pointer to produce the base. 208 // int VirtualBaseAdjustmentOffset; 209 // }; 210 static std::pair<unsigned, unsigned> 211 getMSMemberPointerSlots(const MemberPointerType *MPT) { 212 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); 213 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); 214 unsigned Ptrs = 0; 215 unsigned Ints = 0; 216 if (MPT->isMemberFunctionPointer()) 217 Ptrs = 1; 218 else 219 Ints = 1; 220 if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(), 221 Inheritance)) 222 Ints++; 223 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) 224 Ints++; 225 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance)) 226 Ints++; 227 return std::make_pair(Ptrs, Ints); 228 } 229 230 CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo( 231 const MemberPointerType *MPT) const { 232 // The nominal struct is laid out with pointers followed by ints and aligned 233 // to a pointer width if any are present and an int width otherwise. 234 const TargetInfo &Target = Context.getTargetInfo(); 235 unsigned PtrSize = Target.getPointerWidth(0); 236 unsigned IntSize = Target.getIntWidth(); 237 238 unsigned Ptrs, Ints; 239 std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT); 240 MemberPointerInfo MPI; 241 MPI.HasPadding = false; 242 MPI.Width = Ptrs * PtrSize + Ints * IntSize; 243 244 // When MSVC does x86_32 record layout, it aligns aggregate member pointers to 245 // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for 246 // function memptrs. 247 if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit()) 248 MPI.Align = 64; 249 else if (Ptrs) 250 MPI.Align = Target.getPointerAlign(0); 251 else 252 MPI.Align = Target.getIntAlign(); 253 254 if (Target.getTriple().isArch64Bit()) { 255 MPI.Width = llvm::alignTo(MPI.Width, MPI.Align); 256 MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize); 257 } 258 return MPI; 259 } 260 261 CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) { 262 return new MicrosoftCXXABI(Ctx); 263 } 264 265