1 //===------- ItaniumCXXABI.cpp - AST support for the Itanium 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 Itanium C++ ABI, which is 10 // documented at: 11 // http://www.codesourcery.com/public/cxx-abi/abi.html 12 // http://www.codesourcery.com/public/cxx-abi/abi-eh.html 13 // 14 // It also supports the closely-related ARM C++ ABI, documented at: 15 // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf 16 // 17 //===----------------------------------------------------------------------===// 18 19 #include "CXXABI.h" 20 #include "clang/AST/ASTContext.h" 21 #include "clang/AST/DeclCXX.h" 22 #include "clang/AST/Mangle.h" 23 #include "clang/AST/MangleNumberingContext.h" 24 #include "clang/AST/RecordLayout.h" 25 #include "clang/AST/Type.h" 26 #include "clang/Basic/TargetInfo.h" 27 #include "llvm/ADT/FoldingSet.h" 28 #include "llvm/ADT/iterator.h" 29 30 using namespace clang; 31 32 namespace { 33 34 /// According to Itanium C++ ABI 5.1.2: 35 /// the name of an anonymous union is considered to be 36 /// the name of the first named data member found by a pre-order, 37 /// depth-first, declaration-order walk of the data members of 38 /// the anonymous union. 39 /// If there is no such data member (i.e., if all of the data members 40 /// in the union are unnamed), then there is no way for a program to 41 /// refer to the anonymous union, and there is therefore no need to mangle its name. 42 /// 43 /// Returns the name of anonymous union VarDecl or nullptr if it is not found. 44 static const IdentifierInfo *findAnonymousUnionVarDeclName(const VarDecl& VD) { 45 const RecordType *RT = VD.getType()->getAs<RecordType>(); 46 assert(RT && "type of VarDecl is expected to be RecordType."); 47 assert(RT->getDecl()->isUnion() && "RecordType is expected to be a union."); 48 if (const FieldDecl *FD = RT->getDecl()->findFirstNamedDataMember()) { 49 return FD->getIdentifier(); 50 } 51 52 return nullptr; 53 } 54 55 /// The name of a decomposition declaration. 56 struct DecompositionDeclName { 57 using BindingArray = ArrayRef<const BindingDecl*>; 58 59 /// Representative example of a set of bindings with these names. 60 BindingArray Bindings; 61 62 /// Iterators over the sequence of identifiers in the name. 63 struct Iterator 64 : llvm::iterator_adaptor_base<Iterator, BindingArray::const_iterator, 65 std::random_access_iterator_tag, 66 const IdentifierInfo *> { 67 Iterator(BindingArray::const_iterator It) : iterator_adaptor_base(It) {} 68 const IdentifierInfo *operator*() const { 69 return (*this->I)->getIdentifier(); 70 } 71 }; 72 Iterator begin() const { return Iterator(Bindings.begin()); } 73 Iterator end() const { return Iterator(Bindings.end()); } 74 }; 75 } 76 77 namespace llvm { 78 template<typename T> bool isDenseMapKeyEmpty(T V) { 79 return llvm::DenseMapInfo<T>::isEqual( 80 V, llvm::DenseMapInfo<T>::getEmptyKey()); 81 } 82 template<typename T> bool isDenseMapKeyTombstone(T V) { 83 return llvm::DenseMapInfo<T>::isEqual( 84 V, llvm::DenseMapInfo<T>::getTombstoneKey()); 85 } 86 87 template<typename T> 88 Optional<bool> areDenseMapKeysEqualSpecialValues(T LHS, T RHS) { 89 bool LHSEmpty = isDenseMapKeyEmpty(LHS); 90 bool RHSEmpty = isDenseMapKeyEmpty(RHS); 91 if (LHSEmpty || RHSEmpty) 92 return LHSEmpty && RHSEmpty; 93 94 bool LHSTombstone = isDenseMapKeyTombstone(LHS); 95 bool RHSTombstone = isDenseMapKeyTombstone(RHS); 96 if (LHSTombstone || RHSTombstone) 97 return LHSTombstone && RHSTombstone; 98 99 return None; 100 } 101 102 template<> 103 struct DenseMapInfo<DecompositionDeclName> { 104 using ArrayInfo = llvm::DenseMapInfo<ArrayRef<const BindingDecl*>>; 105 static DecompositionDeclName getEmptyKey() { 106 return {ArrayInfo::getEmptyKey()}; 107 } 108 static DecompositionDeclName getTombstoneKey() { 109 return {ArrayInfo::getTombstoneKey()}; 110 } 111 static unsigned getHashValue(DecompositionDeclName Key) { 112 assert(!isEqual(Key, getEmptyKey()) && !isEqual(Key, getTombstoneKey())); 113 return llvm::hash_combine_range(Key.begin(), Key.end()); 114 } 115 static bool isEqual(DecompositionDeclName LHS, DecompositionDeclName RHS) { 116 if (Optional<bool> Result = areDenseMapKeysEqualSpecialValues( 117 LHS.Bindings, RHS.Bindings)) 118 return *Result; 119 120 return LHS.Bindings.size() == RHS.Bindings.size() && 121 std::equal(LHS.begin(), LHS.end(), RHS.begin()); 122 } 123 }; 124 } 125 126 namespace { 127 128 /// Keeps track of the mangled names of lambda expressions and block 129 /// literals within a particular context. 130 class ItaniumNumberingContext : public MangleNumberingContext { 131 ItaniumMangleContext *Mangler; 132 llvm::StringMap<unsigned> LambdaManglingNumbers; 133 unsigned BlockManglingNumber = 0; 134 llvm::DenseMap<const IdentifierInfo *, unsigned> VarManglingNumbers; 135 llvm::DenseMap<const IdentifierInfo *, unsigned> TagManglingNumbers; 136 llvm::DenseMap<DecompositionDeclName, unsigned> 137 DecompsitionDeclManglingNumbers; 138 139 public: 140 ItaniumNumberingContext(ItaniumMangleContext *Mangler) : Mangler(Mangler) {} 141 142 unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { 143 const CXXRecordDecl *Lambda = CallOperator->getParent(); 144 assert(Lambda->isLambda()); 145 146 // Computation of the <lambda-sig> is non-trivial and subtle. Rather than 147 // duplicating it here, just mangle the <lambda-sig> directly. 148 llvm::SmallString<128> LambdaSig; 149 llvm::raw_svector_ostream Out(LambdaSig); 150 Mangler->mangleLambdaSig(Lambda, Out); 151 152 return ++LambdaManglingNumbers[LambdaSig]; 153 } 154 155 unsigned getManglingNumber(const BlockDecl *BD) override { 156 return ++BlockManglingNumber; 157 } 158 159 unsigned getStaticLocalNumber(const VarDecl *VD) override { 160 return 0; 161 } 162 163 /// Variable decls are numbered by identifier. 164 unsigned getManglingNumber(const VarDecl *VD, unsigned) override { 165 if (auto *DD = dyn_cast<DecompositionDecl>(VD)) { 166 DecompositionDeclName Name{DD->bindings()}; 167 return ++DecompsitionDeclManglingNumbers[Name]; 168 } 169 170 const IdentifierInfo *Identifier = VD->getIdentifier(); 171 if (!Identifier) { 172 // VarDecl without an identifier represents an anonymous union 173 // declaration. 174 Identifier = findAnonymousUnionVarDeclName(*VD); 175 } 176 return ++VarManglingNumbers[Identifier]; 177 } 178 179 unsigned getManglingNumber(const TagDecl *TD, unsigned) override { 180 return ++TagManglingNumbers[TD->getIdentifier()]; 181 } 182 }; 183 184 class ItaniumCXXABI : public CXXABI { 185 private: 186 std::unique_ptr<MangleContext> Mangler; 187 protected: 188 ASTContext &Context; 189 public: 190 ItaniumCXXABI(ASTContext &Ctx) 191 : Mangler(Ctx.createMangleContext()), Context(Ctx) {} 192 193 MemberPointerInfo 194 getMemberPointerInfo(const MemberPointerType *MPT) const override { 195 const TargetInfo &Target = Context.getTargetInfo(); 196 TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0); 197 MemberPointerInfo MPI; 198 MPI.Width = Target.getTypeWidth(PtrDiff); 199 MPI.Align = Target.getTypeAlign(PtrDiff); 200 MPI.HasPadding = false; 201 if (MPT->isMemberFunctionPointer()) 202 MPI.Width *= 2; 203 return MPI; 204 } 205 206 CallingConv getDefaultMethodCallConv(bool isVariadic) const override { 207 const llvm::Triple &T = Context.getTargetInfo().getTriple(); 208 if (!isVariadic && T.isWindowsGNUEnvironment() && 209 T.getArch() == llvm::Triple::x86) 210 return CC_X86ThisCall; 211 return Context.getTargetInfo().getDefaultCallingConv(); 212 } 213 214 // We cheat and just check that the class has a vtable pointer, and that it's 215 // only big enough to have a vtable pointer and nothing more (or less). 216 bool isNearlyEmpty(const CXXRecordDecl *RD) const override { 217 218 // Check that the class has a vtable pointer. 219 if (!RD->isDynamicClass()) 220 return false; 221 222 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 223 CharUnits PointerSize = 224 Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 225 return Layout.getNonVirtualSize() == PointerSize; 226 } 227 228 const CXXConstructorDecl * 229 getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override { 230 return nullptr; 231 } 232 233 void addCopyConstructorForExceptionObject(CXXRecordDecl *RD, 234 CXXConstructorDecl *CD) override {} 235 236 void addTypedefNameForUnnamedTagDecl(TagDecl *TD, 237 TypedefNameDecl *DD) override {} 238 239 TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override { 240 return nullptr; 241 } 242 243 void addDeclaratorForUnnamedTagDecl(TagDecl *TD, 244 DeclaratorDecl *DD) override {} 245 246 DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override { 247 return nullptr; 248 } 249 250 std::unique_ptr<MangleNumberingContext> 251 createMangleNumberingContext() const override { 252 return std::make_unique<ItaniumNumberingContext>( 253 cast<ItaniumMangleContext>(Mangler.get())); 254 } 255 }; 256 } 257 258 CXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) { 259 return new ItaniumCXXABI(Ctx); 260 } 261 262 std::unique_ptr<MangleNumberingContext> 263 clang::createItaniumNumberingContext(MangleContext *Mangler) { 264 return std::make_unique<ItaniumNumberingContext>( 265 cast<ItaniumMangleContext>(Mangler)); 266 } 267