/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/ItaniumCXXABI.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 6 | static const IdentifierInfo *findAnonymousUnionVarDeclName(const VarDecl& VD) { |
45 | 6 | const RecordType *RT = VD.getType()->getAs<RecordType>(); |
46 | 6 | assert(RT && "type of VarDecl is expected to be RecordType."); |
47 | 0 | assert(RT->getDecl()->isUnion() && "RecordType is expected to be a union."); |
48 | 6 | if (const FieldDecl *FD = RT->getDecl()->findFirstNamedDataMember()) { |
49 | 5 | return FD->getIdentifier(); |
50 | 5 | } |
51 | | |
52 | 1 | return nullptr; |
53 | 6 | } |
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 | 2 | Iterator(BindingArray::const_iterator It) : iterator_adaptor_base(It) {} |
68 | 1 | const IdentifierInfo *operator*() const { |
69 | 1 | return (*this->I)->getIdentifier(); |
70 | 1 | } |
71 | | }; |
72 | 1 | Iterator begin() const { return Iterator(Bindings.begin()); } |
73 | 1 | Iterator end() const { return Iterator(Bindings.end()); } |
74 | | }; |
75 | | } |
76 | | |
77 | | namespace llvm { |
78 | 144 | template<typename T> bool isDenseMapKeyEmpty(T V) { |
79 | 144 | return llvm::DenseMapInfo<T>::isEqual( |
80 | 144 | V, llvm::DenseMapInfo<T>::getEmptyKey()); |
81 | 144 | } |
82 | 6 | template<typename T> bool isDenseMapKeyTombstone(T V) { |
83 | 6 | return llvm::DenseMapInfo<T>::isEqual( |
84 | 6 | V, llvm::DenseMapInfo<T>::getTombstoneKey()); |
85 | 6 | } |
86 | | |
87 | | template<typename T> |
88 | 72 | Optional<bool> areDenseMapKeysEqualSpecialValues(T LHS, T RHS) { |
89 | 72 | bool LHSEmpty = isDenseMapKeyEmpty(LHS); |
90 | 72 | bool RHSEmpty = isDenseMapKeyEmpty(RHS); |
91 | 72 | if (LHSEmpty || RHSEmpty7 ) |
92 | 69 | return LHSEmpty && RHSEmpty65 ; |
93 | | |
94 | 3 | bool LHSTombstone = isDenseMapKeyTombstone(LHS); |
95 | 3 | bool RHSTombstone = isDenseMapKeyTombstone(RHS); |
96 | 3 | if (LHSTombstone || RHSTombstone) |
97 | 3 | return LHSTombstone && RHSTombstone0 ; |
98 | | |
99 | 0 | return None; |
100 | 3 | } |
101 | | |
102 | | template<> |
103 | | struct DenseMapInfo<DecompositionDeclName> { |
104 | | using ArrayInfo = llvm::DenseMapInfo<ArrayRef<const BindingDecl*>>; |
105 | 5 | static DecompositionDeclName getEmptyKey() { |
106 | 5 | return {ArrayInfo::getEmptyKey()}; |
107 | 5 | } |
108 | 3 | static DecompositionDeclName getTombstoneKey() { |
109 | 3 | return {ArrayInfo::getTombstoneKey()}; |
110 | 3 | } |
111 | 1 | static unsigned getHashValue(DecompositionDeclName Key) { |
112 | 1 | assert(!isEqual(Key, getEmptyKey()) && !isEqual(Key, getTombstoneKey())); |
113 | 0 | return llvm::hash_combine_range(Key.begin(), Key.end()); |
114 | 1 | } |
115 | 72 | static bool isEqual(DecompositionDeclName LHS, DecompositionDeclName RHS) { |
116 | 72 | if (Optional<bool> Result = areDenseMapKeysEqualSpecialValues( |
117 | 72 | LHS.Bindings, RHS.Bindings)) |
118 | 72 | return *Result; |
119 | | |
120 | 0 | return LHS.Bindings.size() == RHS.Bindings.size() && |
121 | 0 | std::equal(LHS.begin(), LHS.end(), RHS.begin()); |
122 | 72 | } |
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 | 37.3k | ItaniumNumberingContext(ItaniumMangleContext *Mangler) : Mangler(Mangler) {} |
141 | | |
142 | 5.17k | unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { |
143 | 5.17k | const CXXRecordDecl *Lambda = CallOperator->getParent(); |
144 | 5.17k | 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 | 0 | llvm::SmallString<128> LambdaSig; |
149 | 5.17k | llvm::raw_svector_ostream Out(LambdaSig); |
150 | 5.17k | Mangler->mangleLambdaSig(Lambda, Out); |
151 | | |
152 | 5.17k | return ++LambdaManglingNumbers[LambdaSig]; |
153 | 5.17k | } |
154 | | |
155 | 307 | unsigned getManglingNumber(const BlockDecl *BD) override { |
156 | 307 | return ++BlockManglingNumber; |
157 | 307 | } |
158 | | |
159 | 5.22k | unsigned getStaticLocalNumber(const VarDecl *VD) override { |
160 | 5.22k | return 0; |
161 | 5.22k | } |
162 | | |
163 | | /// Variable decls are numbered by identifier. |
164 | 5.22k | unsigned getManglingNumber(const VarDecl *VD, unsigned) override { |
165 | 5.22k | if (auto *DD = dyn_cast<DecompositionDecl>(VD)) { |
166 | 1 | DecompositionDeclName Name{DD->bindings()}; |
167 | 1 | return ++DecompsitionDeclManglingNumbers[Name]; |
168 | 1 | } |
169 | | |
170 | 5.22k | const IdentifierInfo *Identifier = VD->getIdentifier(); |
171 | 5.22k | if (!Identifier) { |
172 | | // VarDecl without an identifier represents an anonymous union |
173 | | // declaration. |
174 | 6 | Identifier = findAnonymousUnionVarDeclName(*VD); |
175 | 6 | } |
176 | 5.22k | return ++VarManglingNumbers[Identifier]; |
177 | 5.22k | } |
178 | | |
179 | 47.4k | unsigned getManglingNumber(const TagDecl *TD, unsigned) override { |
180 | 47.4k | return ++TagManglingNumbers[TD->getIdentifier()]; |
181 | 47.4k | } |
182 | | }; |
183 | | |
184 | | // A version of this for SYCL that makes sure that 'device' mangling context |
185 | | // matches the lambda mangling number, so that __builtin_sycl_unique_stable_name |
186 | | // can be consistently generated between a MS and Itanium host by just referring |
187 | | // to the device mangling number. |
188 | | class ItaniumSYCLNumberingContext : public ItaniumNumberingContext { |
189 | | llvm::DenseMap<const CXXMethodDecl *, unsigned> ManglingNumbers; |
190 | | using ManglingItr = decltype(ManglingNumbers)::iterator; |
191 | | |
192 | | public: |
193 | | ItaniumSYCLNumberingContext(ItaniumMangleContext *Mangler) |
194 | 37 | : ItaniumNumberingContext(Mangler) {} |
195 | | |
196 | 75 | unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { |
197 | 75 | unsigned Number = ItaniumNumberingContext::getManglingNumber(CallOperator); |
198 | 75 | std::pair<ManglingItr, bool> emplace_result = |
199 | 75 | ManglingNumbers.try_emplace(CallOperator, Number); |
200 | 75 | (void)emplace_result; |
201 | 75 | assert(emplace_result.second && "Lambda number set multiple times?"); |
202 | 0 | return Number; |
203 | 75 | } |
204 | | |
205 | | using ItaniumNumberingContext::getManglingNumber; |
206 | | |
207 | 75 | unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override { |
208 | 75 | ManglingItr Itr = ManglingNumbers.find(CallOperator); |
209 | 75 | assert(Itr != ManglingNumbers.end() && "Lambda not yet mangled?"); |
210 | | |
211 | 0 | return Itr->second; |
212 | 75 | } |
213 | | }; |
214 | | |
215 | | class ItaniumCXXABI : public CXXABI { |
216 | | private: |
217 | | std::unique_ptr<MangleContext> Mangler; |
218 | | protected: |
219 | | ASTContext &Context; |
220 | | public: |
221 | | ItaniumCXXABI(ASTContext &Ctx) |
222 | 69.9k | : Mangler(Ctx.createMangleContext()), Context(Ctx) {} |
223 | | |
224 | | MemberPointerInfo |
225 | 819 | getMemberPointerInfo(const MemberPointerType *MPT) const override { |
226 | 819 | const TargetInfo &Target = Context.getTargetInfo(); |
227 | 819 | TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0); |
228 | 819 | MemberPointerInfo MPI; |
229 | 819 | MPI.Width = Target.getTypeWidth(PtrDiff); |
230 | 819 | MPI.Align = Target.getTypeAlign(PtrDiff); |
231 | 819 | MPI.HasPadding = false; |
232 | 819 | if (MPT->isMemberFunctionPointer()) |
233 | 675 | MPI.Width *= 2; |
234 | 819 | return MPI; |
235 | 819 | } |
236 | | |
237 | 2.82M | CallingConv getDefaultMethodCallConv(bool isVariadic) const override { |
238 | 2.82M | const llvm::Triple &T = Context.getTargetInfo().getTriple(); |
239 | 2.82M | if (!isVariadic && T.isWindowsGNUEnvironment()2.81M && |
240 | 2.82M | T.getArch() == llvm::Triple::x867.33k ) |
241 | 4.05k | return CC_X86ThisCall; |
242 | 2.82M | return Context.getTargetInfo().getDefaultCallingConv(); |
243 | 2.82M | } |
244 | | |
245 | | // We cheat and just check that the class has a vtable pointer, and that it's |
246 | | // only big enough to have a vtable pointer and nothing more (or less). |
247 | 2.12k | bool isNearlyEmpty(const CXXRecordDecl *RD) const override { |
248 | | |
249 | | // Check that the class has a vtable pointer. |
250 | 2.12k | if (!RD->isDynamicClass()) |
251 | 683 | return false; |
252 | | |
253 | 1.44k | const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); |
254 | 1.44k | CharUnits PointerSize = |
255 | 1.44k | Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); |
256 | 1.44k | return Layout.getNonVirtualSize() == PointerSize; |
257 | 2.12k | } |
258 | | |
259 | | const CXXConstructorDecl * |
260 | 0 | getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override { |
261 | 0 | return nullptr; |
262 | 0 | } |
263 | | |
264 | | void addCopyConstructorForExceptionObject(CXXRecordDecl *RD, |
265 | 0 | CXXConstructorDecl *CD) override {} |
266 | | |
267 | | void addTypedefNameForUnnamedTagDecl(TagDecl *TD, |
268 | 151 | TypedefNameDecl *DD) override {} |
269 | | |
270 | 948k | TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override { |
271 | 948k | return nullptr; |
272 | 948k | } |
273 | | |
274 | | void addDeclaratorForUnnamedTagDecl(TagDecl *TD, |
275 | 10.5k | DeclaratorDecl *DD) override {} |
276 | | |
277 | 948k | DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override { |
278 | 948k | return nullptr; |
279 | 948k | } |
280 | | |
281 | | std::unique_ptr<MangleNumberingContext> |
282 | 37.3k | createMangleNumberingContext() const override { |
283 | 37.3k | if (Context.getLangOpts().isSYCL()) |
284 | 37 | return std::make_unique<ItaniumSYCLNumberingContext>( |
285 | 37 | cast<ItaniumMangleContext>(Mangler.get())); |
286 | 37.2k | return std::make_unique<ItaniumNumberingContext>( |
287 | 37.2k | cast<ItaniumMangleContext>(Mangler.get())); |
288 | 37.3k | } |
289 | | }; |
290 | | } |
291 | | |
292 | 69.9k | CXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) { |
293 | 69.9k | return new ItaniumCXXABI(Ctx); |
294 | 69.9k | } |
295 | | |
296 | | std::unique_ptr<MangleNumberingContext> |
297 | 16 | clang::createItaniumNumberingContext(MangleContext *Mangler) { |
298 | 16 | return std::make_unique<ItaniumNumberingContext>( |
299 | 16 | cast<ItaniumMangleContext>(Mangler)); |
300 | 16 | } |