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