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 llvm::SmallDenseMap<std::pair<const CXXConstructorDecl *, unsigned>, Expr *> 71 CtorToDefaultArgExpr; 72 73 llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *> 74 UnnamedTagDeclToDeclaratorDecl; 75 llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *> 76 UnnamedTagDeclToTypedefNameDecl; 77 78 public: 79 MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { } 80 81 std::pair<uint64_t, unsigned> 82 getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override; 83 84 CallingConv getDefaultMethodCallConv(bool isVariadic) const override { 85 if (!isVariadic && 86 Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86) 87 return CC_X86ThisCall; 88 return CC_C; 89 } 90 91 bool isNearlyEmpty(const CXXRecordDecl *RD) const override { 92 llvm_unreachable("unapplicable to the MS ABI"); 93 } 94 95 void addDefaultArgExprForConstructor(const CXXConstructorDecl *CD, 96 unsigned ParmIdx, Expr *DAE) override { 97 CtorToDefaultArgExpr[std::make_pair(CD, ParmIdx)] = DAE; 98 } 99 100 Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD, 101 unsigned ParmIdx) override { 102 return CtorToDefaultArgExpr[std::make_pair(CD, ParmIdx)]; 103 } 104 105 const CXXConstructorDecl * 106 getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override { 107 return RecordToCopyCtor[RD]; 108 } 109 110 void 111 addCopyConstructorForExceptionObject(CXXRecordDecl *RD, 112 CXXConstructorDecl *CD) override { 113 assert(CD != nullptr); 114 assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD); 115 RecordToCopyCtor[RD] = CD; 116 } 117 118 void addTypedefNameForUnnamedTagDecl(TagDecl *TD, 119 TypedefNameDecl *DD) override { 120 TD = TD->getCanonicalDecl(); 121 DD = cast<TypedefNameDecl>(DD->getCanonicalDecl()); 122 TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD]; 123 if (!I) 124 I = DD; 125 } 126 127 TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override { 128 return UnnamedTagDeclToTypedefNameDecl.lookup( 129 const_cast<TagDecl *>(TD->getCanonicalDecl())); 130 } 131 132 void addDeclaratorForUnnamedTagDecl(TagDecl *TD, 133 DeclaratorDecl *DD) override { 134 TD = TD->getCanonicalDecl(); 135 DD = cast<DeclaratorDecl>(DD->getCanonicalDecl()); 136 DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD]; 137 if (!I) 138 I = DD; 139 } 140 141 DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override { 142 return UnnamedTagDeclToDeclaratorDecl.lookup( 143 const_cast<TagDecl *>(TD->getCanonicalDecl())); 144 } 145 146 MangleNumberingContext *createMangleNumberingContext() const override { 147 return new MicrosoftNumberingContext(); 148 } 149 }; 150 } 151 152 // getNumBases() seems to only give us the number of direct bases, and not the 153 // total. This function tells us if we inherit from anybody that uses MI, or if 154 // we have a non-primary base class, which uses the multiple inheritance model. 155 static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) { 156 while (RD->getNumBases() > 0) { 157 if (RD->getNumBases() > 1) 158 return true; 159 assert(RD->getNumBases() == 1); 160 const CXXRecordDecl *Base = 161 RD->bases_begin()->getType()->getAsCXXRecordDecl(); 162 if (RD->isPolymorphic() && !Base->isPolymorphic()) 163 return true; 164 RD = Base; 165 } 166 return false; 167 } 168 169 MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const { 170 if (!hasDefinition() || isParsingBaseSpecifiers()) 171 return MSInheritanceAttr::Keyword_unspecified_inheritance; 172 if (getNumVBases() > 0) 173 return MSInheritanceAttr::Keyword_virtual_inheritance; 174 if (usesMultipleInheritanceModel(this)) 175 return MSInheritanceAttr::Keyword_multiple_inheritance; 176 return MSInheritanceAttr::Keyword_single_inheritance; 177 } 178 179 MSInheritanceAttr::Spelling 180 CXXRecordDecl::getMSInheritanceModel() const { 181 MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>(); 182 assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!"); 183 return IA->getSemanticSpelling(); 184 } 185 186 MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const { 187 if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>()) 188 return VDA->getVtorDispMode(); 189 return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode); 190 } 191 192 // Returns the number of pointer and integer slots used to represent a member 193 // pointer in the MS C++ ABI. 194 // 195 // Member function pointers have the following general form; however, fields 196 // are dropped as permitted (under the MSVC interpretation) by the inheritance 197 // model of the actual class. 198 // 199 // struct { 200 // // A pointer to the member function to call. If the member function is 201 // // virtual, this will be a thunk that forwards to the appropriate vftable 202 // // slot. 203 // void *FunctionPointerOrVirtualThunk; 204 // 205 // // An offset to add to the address of the vbtable pointer after 206 // // (possibly) selecting the virtual base but before resolving and calling 207 // // the function. 208 // // Only needed if the class has any virtual bases or bases at a non-zero 209 // // offset. 210 // int NonVirtualBaseAdjustment; 211 // 212 // // The offset of the vb-table pointer within the object. Only needed for 213 // // incomplete types. 214 // int VBPtrOffset; 215 // 216 // // An offset within the vb-table that selects the virtual base containing 217 // // the member. Loading from this offset produces a new offset that is 218 // // added to the address of the vb-table pointer to produce the base. 219 // int VirtualBaseAdjustmentOffset; 220 // }; 221 static std::pair<unsigned, unsigned> 222 getMSMemberPointerSlots(const MemberPointerType *MPT) { 223 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); 224 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); 225 unsigned Ptrs = 0; 226 unsigned Ints = 0; 227 if (MPT->isMemberFunctionPointer()) 228 Ptrs = 1; 229 else 230 Ints = 1; 231 if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(), 232 Inheritance)) 233 Ints++; 234 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) 235 Ints++; 236 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance)) 237 Ints++; 238 return std::make_pair(Ptrs, Ints); 239 } 240 241 std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign( 242 const MemberPointerType *MPT) const { 243 // The nominal struct is laid out with pointers followed by ints and aligned 244 // to a pointer width if any are present and an int width otherwise. 245 const TargetInfo &Target = Context.getTargetInfo(); 246 unsigned PtrSize = Target.getPointerWidth(0); 247 unsigned IntSize = Target.getIntWidth(); 248 249 unsigned Ptrs, Ints; 250 std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT); 251 uint64_t Width = Ptrs * PtrSize + Ints * IntSize; 252 unsigned Align; 253 254 // When MSVC does x86_32 record layout, it aligns aggregate member pointers to 255 // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for 256 // function memptrs. 257 if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit()) 258 Align = 64; 259 else if (Ptrs) 260 Align = Target.getPointerAlign(0); 261 else 262 Align = Target.getIntAlign(); 263 264 if (Target.getTriple().isArch64Bit()) 265 Width = llvm::RoundUpToAlignment(Width, Align); 266 return std::make_pair(Width, Align); 267 } 268 269 CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) { 270 return new MicrosoftCXXABI(Ctx); 271 } 272 273