/Volumes/compiler/apple/swift/lib/AST/ASTMangler.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- ASTMangler.cpp - Swift AST symbol mangling -----------------------===// |
2 | | // |
3 | | // This source file is part of the Swift.org open source project |
4 | | // |
5 | | // Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors |
6 | | // Licensed under Apache License v2.0 with Runtime Library Exception |
7 | | // |
8 | | // See https://swift.org/LICENSE.txt for license information |
9 | | // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | // |
13 | | // This file implements declaration name mangling in Swift. |
14 | | // |
15 | | //===----------------------------------------------------------------------===// |
16 | | |
17 | | #include "swift/AST/ASTMangler.h" |
18 | | #include "swift/AST/ASTContext.h" |
19 | | #include "swift/AST/ASTVisitor.h" |
20 | | #include "swift/AST/AutoDiff.h" |
21 | | #include "swift/AST/Decl.h" |
22 | | #include "swift/AST/ExistentialLayout.h" |
23 | | #include "swift/AST/Expr.h" |
24 | | #include "swift/AST/FileUnit.h" |
25 | | #include "swift/AST/GenericSignature.h" |
26 | | #include "swift/AST/Initializer.h" |
27 | | #include "swift/AST/LazyResolver.h" |
28 | | #include "swift/AST/MacroDiscriminatorContext.h" |
29 | | #include "swift/AST/Module.h" |
30 | | #include "swift/AST/Ownership.h" |
31 | | #include "swift/AST/ParameterList.h" |
32 | | #include "swift/AST/PrettyStackTrace.h" |
33 | | #include "swift/AST/ProtocolConformance.h" |
34 | | #include "swift/AST/ProtocolConformanceRef.h" |
35 | | #include "swift/AST/SILLayout.h" |
36 | | #include "swift/AST/TypeCheckRequests.h" |
37 | | #include "swift/Basic/Defer.h" |
38 | | #include "swift/Basic/SourceManager.h" |
39 | | #include "swift/ClangImporter/ClangImporter.h" |
40 | | #include "swift/Demangling/Demangler.h" |
41 | | #include "swift/Demangling/ManglingMacros.h" |
42 | | #include "swift/Demangling/ManglingUtils.h" |
43 | | #include "swift/Strings.h" |
44 | | #include "clang/AST/ASTContext.h" |
45 | | #include "clang/AST/Attr.h" |
46 | | #include "clang/AST/Decl.h" |
47 | | #include "clang/AST/DeclObjC.h" |
48 | | #include "clang/AST/DeclTemplate.h" |
49 | | #include "clang/AST/Mangle.h" |
50 | | #include "clang/Basic/CharInfo.h" |
51 | | #include "llvm/ADT/DenseMap.h" |
52 | | #include "llvm/ADT/SmallString.h" |
53 | | #include "llvm/ADT/STLExtras.h" |
54 | | #include "llvm/ADT/StringRef.h" |
55 | | #include "llvm/Support/CommandLine.h" |
56 | | #include "llvm/Support/ErrorHandling.h" |
57 | | #include "llvm/Support/SaveAndRestore.h" |
58 | | #include "llvm/Support/raw_ostream.h" |
59 | | |
60 | | #include <memory> |
61 | | |
62 | | using namespace swift; |
63 | | using namespace swift::Mangle; |
64 | | |
65 | 675k | static StringRef getCodeForAccessorKind(AccessorKind kind) { |
66 | 675k | switch (kind) { |
67 | 456k | case AccessorKind::Get: |
68 | 456k | return "g"; |
69 | 114k | case AccessorKind::Set: |
70 | 114k | return "s"; |
71 | 378 | case AccessorKind::WillSet: |
72 | 378 | return "w"; |
73 | 555 | case AccessorKind::DidSet: |
74 | 555 | return "W"; |
75 | 4.27k | case AccessorKind::Read: |
76 | 4.27k | return "r"; |
77 | 84.8k | case AccessorKind::Modify: |
78 | 84.8k | return "M"; |
79 | 807 | case AccessorKind::Address: |
80 | | // 'l' is for location. 'A' was taken. |
81 | 807 | return "lu"; |
82 | 14.0k | case AccessorKind::MutableAddress: |
83 | 14.0k | return "au"; |
84 | 537 | case AccessorKind::Init: |
85 | 537 | return "i"; |
86 | 675k | } |
87 | 0 | llvm_unreachable("bad accessor kind"); |
88 | 0 | } |
89 | | |
90 | | std::string ASTMangler::mangleClosureEntity(const AbstractClosureExpr *closure, |
91 | 83.5k | SymbolKind SKind) { |
92 | 83.5k | beginMangling(); |
93 | 83.5k | appendClosureEntity(closure); |
94 | 83.5k | appendSymbolKind(SKind); |
95 | 83.5k | return finalize(); |
96 | 83.5k | } |
97 | | |
98 | 874k | std::string ASTMangler::mangleEntity(const ValueDecl *decl, SymbolKind SKind) { |
99 | 874k | beginMangling(); |
100 | 874k | appendEntity(decl); |
101 | 874k | appendSymbolKind(SKind); |
102 | 874k | return finalize(); |
103 | 874k | } |
104 | | |
105 | | std::string ASTMangler::mangleDestructorEntity(const DestructorDecl *decl, |
106 | | bool isDeallocating, |
107 | 737k | SymbolKind SKind) { |
108 | 737k | beginMangling(); |
109 | 737k | appendDestructorEntity(decl, isDeallocating); |
110 | 737k | appendSymbolKind(SKind); |
111 | 737k | return finalize(); |
112 | 737k | } |
113 | | |
114 | | std::string ASTMangler::mangleConstructorEntity(const ConstructorDecl *ctor, |
115 | | bool isAllocating, |
116 | 224k | SymbolKind SKind) { |
117 | 224k | beginMangling(); |
118 | 224k | appendConstructorEntity(ctor, isAllocating); |
119 | 224k | appendSymbolKind(SKind); |
120 | 224k | return finalize(); |
121 | 224k | } |
122 | | |
123 | | std::string ASTMangler::mangleIVarInitDestroyEntity(const ClassDecl *decl, |
124 | | bool isDestroyer, |
125 | 16.8k | SymbolKind SKind) { |
126 | 16.8k | beginMangling(); |
127 | 16.8k | appendContext(decl, decl->getAlternateModuleName()); |
128 | 16.8k | appendOperator(isDestroyer ? "fE" : "fe"); |
129 | 16.8k | appendSymbolKind(SKind); |
130 | 16.8k | return finalize(); |
131 | 16.8k | } |
132 | | |
133 | | std::string ASTMangler::mangleAccessorEntity(AccessorKind kind, |
134 | | const AbstractStorageDecl *decl, |
135 | | bool isStatic, |
136 | 13.5k | SymbolKind SKind) { |
137 | 13.5k | beginMangling(); |
138 | 13.5k | appendAccessorEntity(getCodeForAccessorKind(kind), decl, isStatic); |
139 | 13.5k | appendSymbolKind(SKind); |
140 | 13.5k | return finalize(); |
141 | 13.5k | } |
142 | | |
143 | | std::string ASTMangler::mangleGlobalGetterEntity(const ValueDecl *decl, |
144 | 0 | SymbolKind SKind) { |
145 | 0 | assert(isa<VarDecl>(decl) && "Only variables can have global getters"); |
146 | 0 | beginMangling(); |
147 | 0 | appendEntity(decl, "vG", /*isStatic*/false); |
148 | 0 | appendSymbolKind(SKind); |
149 | 0 | return finalize(); |
150 | 0 | } |
151 | | |
152 | | std::string ASTMangler::mangleDefaultArgumentEntity(const DeclContext *func, |
153 | | unsigned index, |
154 | 55.3k | SymbolKind SKind) { |
155 | 55.3k | beginMangling(); |
156 | 55.3k | appendDefaultArgumentEntity(func, index); |
157 | 55.3k | appendSymbolKind(SKind); |
158 | 55.3k | return finalize(); |
159 | 55.3k | } |
160 | | |
161 | | std::string ASTMangler::mangleInitializerEntity(const VarDecl *var, |
162 | 32.4k | SymbolKind SKind) { |
163 | 32.4k | beginMangling(); |
164 | 32.4k | appendInitializerEntity(var); |
165 | 32.4k | appendSymbolKind(SKind); |
166 | 32.4k | return finalize(); |
167 | 32.4k | } |
168 | | |
169 | | std::string ASTMangler::mangleBackingInitializerEntity(const VarDecl *var, |
170 | 599 | SymbolKind SKind) { |
171 | 599 | beginMangling(); |
172 | 599 | appendBackingInitializerEntity(var); |
173 | 599 | appendSymbolKind(SKind); |
174 | 599 | return finalize(); |
175 | 599 | } |
176 | | |
177 | | std::string ASTMangler::mangleInitFromProjectedValueEntity(const VarDecl *var, |
178 | 66 | SymbolKind SKind) { |
179 | 66 | beginMangling(); |
180 | 66 | appendInitFromProjectedValueEntity(var); |
181 | 66 | appendSymbolKind(SKind); |
182 | 66 | return finalize(); |
183 | 66 | } |
184 | | |
185 | 97.2k | std::string ASTMangler::mangleNominalType(const NominalTypeDecl *decl) { |
186 | 97.2k | beginMangling(); |
187 | 97.2k | appendAnyGenericType(decl); |
188 | 97.2k | return finalize(); |
189 | 97.2k | } |
190 | | |
191 | | std::string ASTMangler::mangleVTableThunk(const FuncDecl *Base, |
192 | 924 | const FuncDecl *Derived) { |
193 | 924 | beginMangling(); |
194 | | |
195 | 924 | appendEntity(Derived); |
196 | 924 | appendEntity(Base); |
197 | 924 | appendOperator("TV"); |
198 | | |
199 | 924 | return finalize(); |
200 | 924 | } |
201 | | |
202 | | std::string ASTMangler::mangleConstructorVTableThunk( |
203 | | const ConstructorDecl *Base, |
204 | | const ConstructorDecl *Derived, |
205 | 351 | bool isAllocating) { |
206 | 351 | beginMangling(); |
207 | | |
208 | 351 | appendConstructorEntity(Derived, isAllocating); |
209 | 351 | appendConstructorEntity(Base, isAllocating); |
210 | 351 | appendOperator("TV"); |
211 | | |
212 | 351 | return finalize(); |
213 | 351 | } |
214 | | |
215 | 254k | std::string ASTMangler::mangleWitnessTable(const RootProtocolConformance *C) { |
216 | 254k | beginMangling(); |
217 | 254k | if (isa<NormalProtocolConformance>(C)) { |
218 | 254k | appendProtocolConformance(C); |
219 | 254k | appendOperator("WP"); |
220 | 254k | } else if (isa<SelfProtocolConformance>(C)) { |
221 | 150 | appendProtocolName(cast<SelfProtocolConformance>(C)->getProtocol()); |
222 | 150 | appendOperator("WS"); |
223 | 150 | } else { |
224 | 0 | llvm_unreachable("mangling unknown conformance kind"); |
225 | 0 | } |
226 | 254k | return finalize(); |
227 | 254k | } |
228 | | |
229 | | std::string ASTMangler::mangleWitnessThunk( |
230 | | const ProtocolConformance *Conformance, |
231 | 365k | const ValueDecl *Requirement) { |
232 | 365k | beginMangling(); |
233 | | // Concrete witness thunks get a special mangling. |
234 | 365k | if (Conformance) { |
235 | 365k | if (!isa<SelfProtocolConformance>(Conformance)) { |
236 | 365k | appendProtocolConformance(Conformance); |
237 | 365k | } |
238 | 365k | } |
239 | | |
240 | 365k | if (auto ctor = dyn_cast<ConstructorDecl>(Requirement)) { |
241 | 33.3k | appendConstructorEntity(ctor, /*isAllocating=*/true); |
242 | 331k | } else { |
243 | 331k | assert(isa<FuncDecl>(Requirement) && "expected function"); |
244 | 0 | appendEntity(cast<FuncDecl>(Requirement)); |
245 | 331k | } |
246 | | |
247 | 365k | if (Conformance) { |
248 | 365k | if (isa<SelfProtocolConformance>(Conformance)) { |
249 | 36 | appendOperator("TS"); |
250 | 365k | } else { |
251 | 365k | appendOperator("TW"); |
252 | 365k | } |
253 | 365k | } |
254 | | |
255 | 365k | return finalize(); |
256 | 365k | } |
257 | | |
258 | | std::string ASTMangler::mangleClosureWitnessThunk( |
259 | | const ProtocolConformance *Conformance, |
260 | 0 | const AbstractClosureExpr *Closure) { |
261 | 0 | beginMangling(); |
262 | 0 | appendProtocolConformance(Conformance); |
263 | 0 | appendClosureEntity(Closure); |
264 | 0 | appendOperator("TW"); |
265 | 0 | return finalize(); |
266 | 0 | } |
267 | | |
268 | 41.7k | std::string ASTMangler::mangleGlobalVariableFull(const VarDecl *decl) { |
269 | | // Clang globals get mangled using Clang's mangler. |
270 | 41.7k | if (auto clangDecl = |
271 | 41.7k | dyn_cast_or_null<clang::DeclaratorDecl>(decl->getClangDecl())) { |
272 | 834 | if (auto asmLabel = clangDecl->getAttr<clang::AsmLabelAttr>()) { |
273 | 0 | Buffer << '\01' << asmLabel->getLabel(); |
274 | 834 | } else { |
275 | 834 | if (clangDecl->getDeclContext()->isTranslationUnit()) { |
276 | 702 | Buffer << clangDecl->getName(); |
277 | 702 | } else { |
278 | 132 | std::unique_ptr<clang::MangleContext> mangler( |
279 | 132 | decl->getClangDecl()->getASTContext().createMangleContext()); |
280 | 132 | mangler->mangleName(clangDecl, Buffer); |
281 | 132 | } |
282 | 834 | } |
283 | 834 | return finalize(); |
284 | 834 | } |
285 | 40.9k | beginMangling(); |
286 | 40.9k | appendEntity(decl); |
287 | 40.9k | return finalize(); |
288 | 41.7k | } |
289 | | |
290 | | std::string ASTMangler::mangleKeyPathGetterThunkHelper( |
291 | | const AbstractStorageDecl *property, |
292 | | GenericSignature signature, |
293 | | CanType baseType, |
294 | | SubstitutionMap subs, |
295 | 22.4k | ResilienceExpansion expansion) { |
296 | 22.4k | beginMangling(); |
297 | 22.4k | appendEntity(property); |
298 | 22.4k | if (signature) |
299 | 3.16k | appendGenericSignature(signature); |
300 | 22.4k | appendType(baseType, signature); |
301 | 22.4k | if (isa<SubscriptDecl>(property)) { |
302 | | // Subscripts can be generic, and different key paths could capture the same |
303 | | // subscript at different generic arguments. |
304 | 3.75k | for (auto sub : subs.getReplacementTypes()) { |
305 | 2.13k | sub = sub->mapTypeOutOfContext(); |
306 | | |
307 | | // FIXME: This seems wrong. We used to just mangle opened archetypes as |
308 | | // their interface type. Let's make that explicit now. |
309 | 2.20k | sub = sub.transformRec([](Type t) -> llvm::Optional<Type> { |
310 | 2.20k | if (auto *openedExistential = t->getAs<OpenedArchetypeType>()) |
311 | 15 | return openedExistential->getInterfaceType(); |
312 | 2.19k | return llvm::None; |
313 | 2.20k | }); |
314 | | |
315 | 2.13k | appendType(sub->getCanonicalType(), signature); |
316 | 2.13k | } |
317 | 3.75k | } |
318 | 22.4k | appendOperator("TK"); |
319 | 22.4k | if (expansion == ResilienceExpansion::Minimal) |
320 | 150 | appendOperator("q"); |
321 | 22.4k | return finalize(); |
322 | 22.4k | } |
323 | | |
324 | | std::string ASTMangler::mangleKeyPathSetterThunkHelper( |
325 | | const AbstractStorageDecl *property, |
326 | | GenericSignature signature, |
327 | | CanType baseType, |
328 | | SubstitutionMap subs, |
329 | 20.9k | ResilienceExpansion expansion) { |
330 | 20.9k | beginMangling(); |
331 | 20.9k | appendEntity(property); |
332 | 20.9k | if (signature) |
333 | 2.95k | appendGenericSignature(signature); |
334 | 20.9k | appendType(baseType, signature); |
335 | 20.9k | if (isa<SubscriptDecl>(property)) { |
336 | | // Subscripts can be generic, and different key paths could capture the same |
337 | | // subscript at different generic arguments. |
338 | 3.28k | for (auto sub : subs.getReplacementTypes()) { |
339 | 1.66k | sub = sub->mapTypeOutOfContext(); |
340 | | |
341 | | // FIXME: This seems wrong. We used to just mangle opened archetypes as |
342 | | // their interface type. Let's make that explicit now. |
343 | 1.68k | sub = sub.transformRec([](Type t) -> llvm::Optional<Type> { |
344 | 1.68k | if (auto *openedExistential = t->getAs<OpenedArchetypeType>()) |
345 | 3 | return openedExistential->getInterfaceType(); |
346 | 1.68k | return llvm::None; |
347 | 1.68k | }); |
348 | | |
349 | 1.66k | appendType(sub->getCanonicalType(), signature); |
350 | 1.66k | } |
351 | 3.28k | } |
352 | 20.9k | appendOperator("Tk"); |
353 | 20.9k | if (expansion == ResilienceExpansion::Minimal) |
354 | 30 | appendOperator("q"); |
355 | 20.9k | return finalize(); |
356 | 20.9k | } |
357 | | |
358 | | std::string ASTMangler::mangleKeyPathEqualsHelper(ArrayRef<CanType> indices, |
359 | | GenericSignature signature, |
360 | 864 | ResilienceExpansion expansion) { |
361 | 864 | beginMangling(); |
362 | 864 | for (auto &index : indices) |
363 | 981 | appendType(index, nullptr); |
364 | 864 | if (signature) |
365 | 210 | appendGenericSignature(signature); |
366 | 864 | appendOperator("TH"); |
367 | 864 | if (expansion == ResilienceExpansion::Minimal) |
368 | 84 | appendOperator("q"); |
369 | 864 | return finalize(); |
370 | 864 | } |
371 | | |
372 | | std::string ASTMangler::mangleKeyPathHashHelper(ArrayRef<CanType> indices, |
373 | | GenericSignature signature, |
374 | 864 | ResilienceExpansion expansion) { |
375 | 864 | beginMangling(); |
376 | 864 | for (auto &index : indices) |
377 | 981 | appendType(index, nullptr); |
378 | 864 | if (signature) |
379 | 210 | appendGenericSignature(signature); |
380 | 864 | appendOperator("Th"); |
381 | 864 | if (expansion == ResilienceExpansion::Minimal) |
382 | 84 | appendOperator("q"); |
383 | 864 | return finalize(); |
384 | 864 | } |
385 | | |
386 | | std::string ASTMangler::mangleGlobalInit(const PatternBindingDecl *pd, |
387 | | unsigned pbdEntry, |
388 | 8.51k | bool isInitFunc) { |
389 | 8.51k | beginMangling(); |
390 | | |
391 | 8.51k | Pattern *pattern = pd->getPattern(pbdEntry); |
392 | 8.51k | bool first = true; |
393 | 8.54k | pattern->forEachVariable([&](VarDecl *D) { |
394 | 8.54k | if (first) { |
395 | 8.51k | appendContextOf(D); |
396 | 8.51k | first = false; |
397 | 8.51k | } |
398 | 8.54k | appendDeclName(D); |
399 | 8.54k | appendListSeparator(); |
400 | 8.54k | }); |
401 | 8.51k | assert(!first && "no variables in pattern binding?!"); |
402 | | |
403 | 8.51k | if (isInitFunc) { |
404 | 4.25k | appendOperator("WZ"); |
405 | 4.25k | } else { |
406 | 4.25k | appendOperator("Wz"); |
407 | 4.25k | } |
408 | | |
409 | 8.51k | return finalize(); |
410 | 8.51k | } |
411 | | |
412 | | std::string ASTMangler::mangleReabstractionThunkHelper( |
413 | | CanSILFunctionType ThunkType, |
414 | | Type FromType, |
415 | | Type ToType, |
416 | | Type SelfType, |
417 | | Type GlobalActorBound, |
418 | 23.8k | ModuleDecl *Module) { |
419 | 23.8k | Mod = Module; |
420 | 23.8k | assert(ThunkType->getPatternSubstitutions().empty() && "not implemented"); |
421 | 0 | GenericSignature GenSig = ThunkType->getInvocationGenericSignature(); |
422 | | |
423 | 23.8k | beginMangling(); |
424 | 23.8k | appendType(FromType, GenSig); |
425 | 23.8k | appendType(ToType, GenSig); |
426 | 23.8k | if (SelfType) |
427 | 90 | appendType(SelfType, GenSig); |
428 | | |
429 | 23.8k | if (GenSig) |
430 | 2.80k | appendGenericSignature(GenSig); |
431 | | |
432 | 23.8k | if (SelfType) |
433 | 90 | appendOperator("Ty"); |
434 | 23.7k | else |
435 | 23.7k | appendOperator("TR"); |
436 | | |
437 | 23.8k | if (GlobalActorBound) { |
438 | 24 | appendType(GlobalActorBound, GenSig); |
439 | 24 | appendOperator("TU"); |
440 | 24 | } |
441 | | |
442 | 23.8k | return finalize(); |
443 | 23.8k | } |
444 | | |
445 | | std::string ASTMangler::mangleObjCAsyncCompletionHandlerImpl( |
446 | | CanSILFunctionType BlockType, CanType ResultType, CanGenericSignature Sig, |
447 | 249 | llvm::Optional<bool> ErrorOnZero, bool predefined) { |
448 | 249 | beginMangling(); |
449 | 249 | appendType(BlockType, Sig); |
450 | 249 | appendType(ResultType, Sig); |
451 | 249 | if (Sig) |
452 | 30 | appendGenericSignature(Sig); |
453 | 249 | if (ErrorOnZero) |
454 | 27 | appendOperator(predefined ? "TZ" : "Tz", Index(*ErrorOnZero + 1)); |
455 | 222 | else |
456 | 222 | appendOperator(predefined ? "TZ" : "Tz", Index(0)); |
457 | 249 | return finalize(); |
458 | 249 | } |
459 | | |
460 | | std::string ASTMangler::mangleAutoDiffDerivativeFunction( |
461 | | const AbstractFunctionDecl *originalAFD, |
462 | | AutoDiffDerivativeFunctionKind kind, |
463 | | const AutoDiffConfig &config, |
464 | 1.67k | bool isVTableThunk) { |
465 | 1.67k | beginManglingWithAutoDiffOriginalFunction(originalAFD); |
466 | 1.67k | appendAutoDiffFunctionParts( |
467 | 1.67k | isVTableThunk ? "TJV" : "TJ", getAutoDiffFunctionKind(kind), config); |
468 | 1.67k | return finalize(); |
469 | 1.67k | } |
470 | | |
471 | | std::string ASTMangler::mangleAutoDiffLinearMap( |
472 | | const AbstractFunctionDecl *originalAFD, AutoDiffLinearMapKind kind, |
473 | 36 | const AutoDiffConfig &config) { |
474 | 36 | beginManglingWithAutoDiffOriginalFunction(originalAFD); |
475 | 36 | appendAutoDiffFunctionParts("TJ", getAutoDiffFunctionKind(kind), config); |
476 | 36 | return finalize(); |
477 | 36 | } |
478 | | |
479 | | void ASTMangler::beginManglingWithAutoDiffOriginalFunction( |
480 | 1.90k | const AbstractFunctionDecl *afd) { |
481 | 1.90k | if (auto *attr = afd->getAttrs().getAttribute<SILGenNameAttr>()) { |
482 | 64 | beginManglingWithoutPrefix(); |
483 | 64 | appendOperator(attr->Name); |
484 | 64 | return; |
485 | 64 | } |
486 | | |
487 | 1.83k | auto beginManglingClangDecl = [&](const clang::NamedDecl *decl) { |
488 | 0 | beginManglingWithoutPrefix(); |
489 | 0 | appendOperator(decl->getName()); |
490 | 0 | }; |
491 | | |
492 | | // For imported Clang declarations, use the Clang name in order to match how |
493 | | // DifferentiationMangler handles these. |
494 | 1.83k | if (auto clangDecl = getClangDeclForMangling(afd)) { |
495 | 0 | beginManglingClangDecl(clangDecl); |
496 | 0 | return; |
497 | 1.83k | } else if (auto typedefType = getTypeDefForCXXCFOptionsDefinition(afd)) { |
498 | 0 | beginManglingClangDecl(typedefType->getDecl()); |
499 | 0 | return; |
500 | 0 | } |
501 | 1.83k | beginMangling(); |
502 | 1.83k | if (auto *cd = dyn_cast<ConstructorDecl>(afd)) |
503 | 212 | appendConstructorEntity(cd, /*isAllocating*/ !cd->isConvenienceInit()); |
504 | 1.62k | else |
505 | 1.62k | appendEntity(afd); |
506 | 1.83k | } |
507 | | |
508 | | void ASTMangler::appendAutoDiffFunctionParts(StringRef op, |
509 | | AutoDiffFunctionKind kind, |
510 | 2.43k | const AutoDiffConfig &config) { |
511 | 2.43k | if (auto sig = config.derivativeGenericSignature) |
512 | 528 | appendGenericSignature(sig); |
513 | 2.43k | auto kindCode = (char)kind; |
514 | 2.43k | appendOperator(op, StringRef(&kindCode, 1)); |
515 | 2.43k | appendIndexSubset(config.parameterIndices); |
516 | 2.43k | appendOperator("p"); |
517 | 2.43k | appendIndexSubset(config.resultIndices); |
518 | 2.43k | appendOperator("r"); |
519 | 2.43k | } |
520 | | |
521 | | std::string ASTMangler::mangleAutoDiffSelfReorderingReabstractionThunk( |
522 | | CanType fromType, CanType toType, GenericSignature signature, |
523 | 152 | AutoDiffLinearMapKind linearMapKind) { |
524 | 152 | beginMangling(); |
525 | 152 | appendType(fromType, signature); |
526 | 152 | appendType(toType, signature); |
527 | 152 | if (signature) |
528 | 16 | appendGenericSignature(signature); |
529 | 152 | auto kindCode = (char)getAutoDiffFunctionKind(linearMapKind); |
530 | 152 | appendOperator("TJO", StringRef(&kindCode, 1)); |
531 | 152 | return finalize(); |
532 | 152 | } |
533 | | |
534 | | /// Mangle the index subset. |
535 | 10.8k | void ASTMangler::appendIndexSubset(IndexSubset *indices) { |
536 | 10.8k | Buffer << indices->getString(); |
537 | 10.8k | } |
538 | | |
539 | | static NodePointer mangleSILDifferentiabilityWitnessAsNode( |
540 | | StringRef originalName, DifferentiabilityKind kind, |
541 | 18.2k | const AutoDiffConfig &config, Demangler &demangler) { |
542 | 18.2k | auto *diffWitnessNode = demangler.createNode( |
543 | 18.2k | Node::Kind::DifferentiabilityWitness); |
544 | 18.2k | auto origNode = demangler.demangleSymbol(originalName); |
545 | 18.2k | assert(origNode->getKind() == Node::Kind::Global); |
546 | 0 | for (auto *child : *origNode) |
547 | 18.2k | diffWitnessNode->addChild(child, demangler); |
548 | 18.2k | diffWitnessNode->addChild( |
549 | 18.2k | demangler.createNode( |
550 | 18.2k | Node::Kind::Index, |
551 | 18.2k | (Node::IndexType)getMangledDifferentiabilityKind(kind)), |
552 | 18.2k | demangler); |
553 | 18.2k | diffWitnessNode->addChild( |
554 | 18.2k | demangler.createNode( |
555 | 18.2k | Node::Kind::IndexSubset, config.parameterIndices->getString()), |
556 | 18.2k | demangler); |
557 | 18.2k | diffWitnessNode->addChild( |
558 | 18.2k | demangler.createNode( |
559 | 18.2k | Node::Kind::IndexSubset, config.resultIndices->getString()), |
560 | 18.2k | demangler); |
561 | 18.2k | if (auto genSig = config.derivativeGenericSignature) { |
562 | 4.46k | ASTMangler genSigMangler; |
563 | 4.46k | auto genSigSymbol = genSigMangler.mangleGenericSignature(genSig); |
564 | 4.46k | auto demangledGenSig = demangler.demangleSymbol(genSigSymbol); |
565 | 4.46k | assert(demangledGenSig); |
566 | 0 | for (auto *child : *demangledGenSig) |
567 | 4.46k | diffWitnessNode->addChild(child, demangler); |
568 | 4.46k | } |
569 | 0 | return diffWitnessNode; |
570 | 18.2k | } |
571 | | |
572 | | std::string ASTMangler::mangleSILDifferentiabilityWitness(StringRef originalName, |
573 | | DifferentiabilityKind kind, |
574 | 20.2k | const AutoDiffConfig &config) { |
575 | | // If the original name was a mangled name, differentiability witnesses must |
576 | | // be mangled as node because they contain generic signatures which may repeat |
577 | | // entities in the original function name. Mangling as node will make sure the |
578 | | // substitutions are mangled correctly. |
579 | 20.2k | if (isMangledName(originalName)) { |
580 | 18.2k | Demangler demangler; |
581 | 18.2k | auto *node = mangleSILDifferentiabilityWitnessAsNode( |
582 | 18.2k | originalName, kind, config, demangler); |
583 | 18.2k | auto mangling = mangleNode(node); |
584 | 18.2k | if (!mangling.isSuccess()) { |
585 | 0 | llvm_unreachable("unexpected mangling failure"); |
586 | 0 | } |
587 | 18.2k | return mangling.result(); |
588 | 18.2k | } |
589 | 1.95k | beginManglingWithoutPrefix(); |
590 | 1.95k | appendOperator(originalName); |
591 | 1.95k | if (auto genSig = config.derivativeGenericSignature) |
592 | 584 | appendGenericSignature(genSig); |
593 | 1.95k | auto diffKindCode = (char)getMangledDifferentiabilityKind(kind); |
594 | 1.95k | appendOperator("WJ", StringRef(&diffKindCode, 1)); |
595 | 1.95k | appendIndexSubset(config.parameterIndices); |
596 | 1.95k | appendOperator("p"); |
597 | 1.95k | appendIndexSubset(config.resultIndices); |
598 | 1.95k | appendOperator("r"); |
599 | 1.95k | return finalize(); |
600 | 20.2k | } |
601 | | |
602 | | std::string ASTMangler::mangleAutoDiffGeneratedDeclaration( |
603 | | AutoDiffGeneratedDeclarationKind declKind, StringRef origFnName, |
604 | | unsigned bbId, AutoDiffLinearMapKind linearMapKind, |
605 | 8.60k | const AutoDiffConfig &config) { |
606 | 8.60k | beginManglingWithoutPrefix(); |
607 | | |
608 | 8.60k | Buffer << "_AD__" << origFnName << "_bb" + std::to_string(bbId); |
609 | 8.60k | switch (declKind) { |
610 | 0 | case AutoDiffGeneratedDeclarationKind::LinearMapStruct: |
611 | 0 | switch (linearMapKind) { |
612 | 0 | case AutoDiffLinearMapKind::Differential: |
613 | 0 | Buffer << "__DF__"; |
614 | 0 | break; |
615 | 0 | case AutoDiffLinearMapKind::Pullback: |
616 | 0 | Buffer << "__PB__"; |
617 | 0 | break; |
618 | 0 | } |
619 | 0 | break; |
620 | 8.60k | case AutoDiffGeneratedDeclarationKind::BranchingTraceEnum: |
621 | 8.60k | switch (linearMapKind) { |
622 | 1.35k | case AutoDiffLinearMapKind::Differential: |
623 | 1.35k | Buffer << "__Succ__"; |
624 | 1.35k | break; |
625 | 7.25k | case AutoDiffLinearMapKind::Pullback: |
626 | 7.25k | Buffer << "__Pred__"; |
627 | 7.25k | break; |
628 | 8.60k | } |
629 | 8.60k | break; |
630 | 8.60k | } |
631 | 8.60k | Buffer << config.mangle(); |
632 | 8.60k | if (config.derivativeGenericSignature) { |
633 | 1.54k | Buffer << '_'; |
634 | 1.54k | appendGenericSignature(config.derivativeGenericSignature); |
635 | 1.54k | } |
636 | | |
637 | 8.60k | auto result = Storage.str().str(); |
638 | 8.60k | Storage.clear(); |
639 | 8.60k | return result; |
640 | 8.60k | } |
641 | | |
642 | | // In order for the remangler to work correctly, it must agree with |
643 | | // AST mangler on the substitution scheme. The AST mangler will use a |
644 | | // substitution if a mangled type is identical to a previous type. |
645 | | // |
646 | | // In the DWARF mangling, we don't canonicalize types. Therefore, any |
647 | | // two types that differ by sugar must have distinct manglings. If this |
648 | | // invariant is not maintained, then demangling and remangling a type |
649 | | // will no longer be idempotent. |
650 | | // |
651 | | // Since we don't have a distinct mangling for sugared generic |
652 | | // parameter types, we must desugar them here. |
653 | 689k | static Type getTypeForDWARFMangling(Type t) { |
654 | 689k | return t.subst( |
655 | 689k | [](SubstitutableType *t) -> Type { |
656 | 114k | if (t->isRootParameterPack()) { |
657 | 519 | return PackType::getSingletonPackExpansion(t->getCanonicalType()); |
658 | 519 | } |
659 | 113k | return t->getCanonicalType(); |
660 | 114k | }, |
661 | 689k | MakeAbstractConformanceForGenericType(), |
662 | 689k | SubstFlags::AllowLoweredTypes); |
663 | 689k | } |
664 | | |
665 | 302k | std::string ASTMangler::mangleTypeForDebugger(Type Ty, GenericSignature sig) { |
666 | 302k | PrettyStackTraceType prettyStackTrace(Ty->getASTContext(), |
667 | 302k | "mangling type for debugger", Ty); |
668 | | |
669 | 302k | DWARFMangling = true; |
670 | 302k | RespectOriginallyDefinedIn = false; |
671 | 302k | OptimizeProtocolNames = false; |
672 | 302k | beginMangling(); |
673 | | |
674 | 302k | Ty = getTypeForDWARFMangling(Ty); |
675 | | |
676 | 302k | appendType(Ty, sig); |
677 | 302k | appendOperator("D"); |
678 | 302k | return finalize(); |
679 | 302k | } |
680 | | |
681 | 558 | std::string ASTMangler::mangleTypeForTypeName(Type type) { |
682 | 558 | beginManglingWithoutPrefix(); |
683 | 558 | appendType(type, nullptr); |
684 | 558 | return finalize(); |
685 | 558 | } |
686 | | |
687 | 0 | std::string ASTMangler::mangleDeclType(const ValueDecl *decl) { |
688 | 0 | DWARFMangling = true; |
689 | 0 | RespectOriginallyDefinedIn = false; |
690 | 0 | beginMangling(); |
691 | | |
692 | 0 | appendDeclType(decl); |
693 | 0 | appendOperator("D"); |
694 | 0 | return finalize(); |
695 | 0 | } |
696 | | |
697 | | #ifdef USE_NEW_MANGLING_FOR_OBJC_RUNTIME_NAMES |
698 | | static bool isPrivate(const NominalTypeDecl *Nominal) { |
699 | | return Nominal->getFormalAccess() <= AccessLevel::FilePrivate; |
700 | | } |
701 | | #endif |
702 | | |
703 | 46.8k | std::string ASTMangler::mangleObjCRuntimeName(const NominalTypeDecl *Nominal) { |
704 | | #ifdef USE_NEW_MANGLING_FOR_OBJC_RUNTIME_NAMES |
705 | | // Using the new mangling for ObjC runtime names (except for top-level |
706 | | // classes). This is currently disabled to support old archives. |
707 | | // TODO: re-enable this as we switch to the new mangling for ObjC names. |
708 | | DeclContext *Ctx = Nominal->getDeclContext(); |
709 | | |
710 | | if (Ctx->isModuleScopeContext() && !isPrivate(Nominal)) { |
711 | | // Use the old mangling for non-private top-level classes and protocols. |
712 | | // This is what the ObjC runtime needs to demangle. |
713 | | // TODO: Use new mangling scheme as soon as the ObjC runtime |
714 | | // can demangle it. |
715 | | // |
716 | | // Don't use word-substitutions and punycode encoding. |
717 | | MaxNumWords = 0; |
718 | | UsePunycode = false; |
719 | | UseSubstitutions = false; |
720 | | Buffer << "_Tt"; |
721 | | bool isProto = false; |
722 | | if (isa<ClassDecl>(Nominal)) { |
723 | | Buffer << 'C'; |
724 | | } else { |
725 | | isProto = true; |
726 | | assert(isa<ProtocolDecl>(Nominal)); |
727 | | Buffer << 'P'; |
728 | | } |
729 | | appendModule(Ctx->getParentModule(), StringRef()); |
730 | | appendIdentifier(Nominal->getName().str()); |
731 | | if (isProto) |
732 | | Buffer << '_'; |
733 | | return finalize(); |
734 | | } |
735 | | // For all other cases, we can use the new mangling. |
736 | | beginMangling(); |
737 | | appendAnyGenericType(Nominal); |
738 | | return finalize(); |
739 | | #else |
740 | | // Use the old mangling for ObjC runtime names. |
741 | 46.8k | beginMangling(); |
742 | 46.8k | appendAnyGenericType(Nominal); |
743 | 46.8k | std::string NewName = finalize(); |
744 | 46.8k | Demangle::Demangler Dem; |
745 | 46.8k | Demangle::Node *Root = Dem.demangleSymbol(NewName); |
746 | 46.8k | assert(Root->getKind() == Node::Kind::Global); |
747 | 0 | Node *NomTy = Root->getFirstChild(); |
748 | 46.8k | if (NomTy->getKind() == Node::Kind::Protocol) { |
749 | | // Protocol types are mangled as protocol lists. |
750 | 1.62k | Node *PTy = Dem.createNode(Node::Kind::Type); |
751 | 1.62k | PTy->addChild(NomTy, Dem); |
752 | 1.62k | Node *TList = Dem.createNode(Node::Kind::TypeList); |
753 | 1.62k | TList->addChild(PTy, Dem); |
754 | 1.62k | NomTy = Dem.createNode(Node::Kind::ProtocolList); |
755 | 1.62k | NomTy->addChild(TList, Dem); |
756 | 1.62k | } |
757 | | // Add a TypeMangling node at the top |
758 | 46.8k | Node *Ty = Dem.createNode(Node::Kind::Type); |
759 | 46.8k | Ty->addChild(NomTy, Dem); |
760 | 46.8k | Node *TyMangling = Dem.createNode(Node::Kind::TypeMangling); |
761 | 46.8k | TyMangling->addChild(Ty, Dem); |
762 | 46.8k | Node *NewGlobal = Dem.createNode(Node::Kind::Global); |
763 | 46.8k | NewGlobal->addChild(TyMangling, Dem); |
764 | 46.8k | auto mangling = mangleNodeOld(NewGlobal); |
765 | 46.8k | if (!mangling.isSuccess()) { |
766 | 0 | llvm_unreachable("unexpected mangling failure"); |
767 | 0 | } |
768 | 46.8k | return mangling.result(); |
769 | 46.8k | #endif |
770 | 46.8k | } |
771 | | |
772 | 75.0k | std::string ASTMangler::mangleTypeAsContextUSR(const NominalTypeDecl *type) { |
773 | 75.0k | beginManglingWithoutPrefix(); |
774 | 75.0k | llvm::SaveAndRestore<bool> allowUnnamedRAII(AllowNamelessEntities, true); |
775 | 75.0k | appendContext(type, type->getAlternateModuleName()); |
776 | 75.0k | return finalize(); |
777 | 75.0k | } |
778 | | |
779 | 387k | std::string ASTMangler::mangleTypeAsUSR(Type Ty) { |
780 | 387k | DWARFMangling = true; |
781 | 387k | RespectOriginallyDefinedIn = false; |
782 | 387k | beginMangling(); |
783 | | |
784 | 387k | Ty = getTypeForDWARFMangling(Ty); |
785 | | |
786 | 387k | if (auto *fnType = Ty->getAs<AnyFunctionType>()) { |
787 | 856 | appendFunction(fnType, nullptr); |
788 | 386k | } else { |
789 | 386k | appendType(Ty, nullptr); |
790 | 386k | } |
791 | | |
792 | 387k | appendOperator("D"); |
793 | 387k | return finalize(); |
794 | 387k | } |
795 | | |
796 | 910k | void ASTMangler::appendAnyDecl(const ValueDecl *Decl) { |
797 | 910k | if (auto Ctor = dyn_cast<ConstructorDecl>(Decl)) { |
798 | 64.0k | appendConstructorEntity(Ctor, /*isAllocating=*/false); |
799 | 846k | } else if (auto Dtor = dyn_cast<DestructorDecl>(Decl)) { |
800 | 525 | appendDestructorEntity(Dtor, /*isDeallocating=*/false); |
801 | 845k | } else if (auto GTD = dyn_cast<GenericTypeDecl>(Decl)) { |
802 | 228k | appendAnyGenericType(GTD); |
803 | 616k | } else if (isa<AssociatedTypeDecl>(Decl)) { |
804 | 12.0k | appendContextOf(Decl); |
805 | 12.0k | appendDeclName(Decl); |
806 | 12.0k | appendOperator("Qa"); |
807 | 604k | } else { |
808 | 604k | appendEntity(Decl); |
809 | 604k | } |
810 | 910k | } |
811 | | |
812 | | std::string |
813 | | ASTMangler::mangleAnyDecl(const ValueDecl *Decl, |
814 | | bool prefix, |
815 | 910k | bool respectOriginallyDefinedIn) { |
816 | 910k | DWARFMangling = true; |
817 | 910k | RespectOriginallyDefinedIn = respectOriginallyDefinedIn; |
818 | 910k | if (prefix) { |
819 | 95.1k | beginMangling(); |
820 | 815k | } else { |
821 | 815k | beginManglingWithoutPrefix(); |
822 | 815k | } |
823 | 910k | llvm::SaveAndRestore<bool> allowUnnamedRAII(AllowNamelessEntities, true); |
824 | | |
825 | 910k | appendAnyDecl(Decl); |
826 | | |
827 | | // We have a custom prefix, so finalize() won't verify for us. If we're not |
828 | | // in invalid code (coming from an IDE caller) verify manually. |
829 | 910k | if (!Decl->isInvalid()) |
830 | 908k | verify(Storage.str()); |
831 | 910k | return finalize(); |
832 | 910k | } |
833 | | |
834 | | std::string ASTMangler::mangleDeclAsUSR(const ValueDecl *Decl, |
835 | 815k | StringRef USRPrefix) { |
836 | 815k | return (llvm::Twine(USRPrefix) + mangleAnyDecl(Decl, false)).str(); |
837 | 815k | } |
838 | | |
839 | | std::string ASTMangler::mangleAccessorEntityAsUSR(AccessorKind kind, |
840 | | const AbstractStorageDecl *decl, |
841 | | StringRef USRPrefix, |
842 | 17.1k | bool isStatic) { |
843 | 17.1k | beginManglingWithoutPrefix(); |
844 | 17.1k | llvm::SaveAndRestore<bool> allowUnnamedRAII(AllowNamelessEntities, true); |
845 | 17.1k | Buffer << USRPrefix; |
846 | 17.1k | appendAccessorEntity(getCodeForAccessorKind(kind), decl, isStatic); |
847 | | // We have a custom prefix, so finalize() won't verify for us. If we're not |
848 | | // in invalid code (coming from an IDE caller) verify manually. |
849 | 17.1k | if (!decl->isInvalid()) |
850 | 17.0k | verify(Storage.str().drop_front(USRPrefix.size())); |
851 | 17.1k | return finalize(); |
852 | 17.1k | } |
853 | | |
854 | 1.16k | std::string ASTMangler::mangleLocalTypeDecl(const TypeDecl *type) { |
855 | 1.16k | beginManglingWithoutPrefix(); |
856 | 1.16k | AllowNamelessEntities = true; |
857 | 1.16k | OptimizeProtocolNames = false; |
858 | | |
859 | | // Local types are not ABI anyway. To avoid problems with the ASTDemangler, |
860 | | // don't respect @_originallyDefinedIn here, since we don't respect it |
861 | | // when mangling DWARF types for debug info. |
862 | 1.16k | RespectOriginallyDefinedIn = false; |
863 | | |
864 | 1.16k | if (auto GTD = dyn_cast<GenericTypeDecl>(type)) { |
865 | 1.16k | appendAnyGenericType(GTD); |
866 | 1.16k | } else { |
867 | 0 | assert(isa<AssociatedTypeDecl>(type)); |
868 | 0 | appendContextOf(type); |
869 | 0 | appendDeclName(type); |
870 | 0 | appendOperator("Qa"); |
871 | 0 | } |
872 | | |
873 | 0 | return finalize(); |
874 | 1.16k | } |
875 | | |
876 | 2.83k | std::string ASTMangler::mangleOpaqueTypeDecl(const OpaqueTypeDecl *decl) { |
877 | 2.83k | return mangleOpaqueTypeDecl(decl->getNamingDecl()); |
878 | 2.83k | } |
879 | | |
880 | 436k | std::string ASTMangler::mangleOpaqueTypeDecl(const ValueDecl *decl) { |
881 | 436k | OptimizeProtocolNames = false; |
882 | | |
883 | 436k | beginMangling(); |
884 | 436k | appendEntity(decl); |
885 | 436k | return finalize(); |
886 | 436k | } |
887 | | |
888 | 7.39k | std::string ASTMangler::mangleGenericSignature(const GenericSignature sig) { |
889 | 7.39k | beginMangling(); |
890 | 7.39k | appendGenericSignature(sig); |
891 | 7.39k | return finalize(); |
892 | 7.39k | } |
893 | | |
894 | 87 | std::string ASTMangler::mangleHasSymbolQuery(const ValueDecl *Decl) { |
895 | 87 | beginMangling(); |
896 | | |
897 | 87 | if (auto Ctor = dyn_cast<ConstructorDecl>(Decl)) { |
898 | 6 | appendConstructorEntity(Ctor, /*isAllocating=*/false); |
899 | 81 | } else if (auto Dtor = dyn_cast<DestructorDecl>(Decl)) { |
900 | 0 | appendDestructorEntity(Dtor, /*isDeallocating=*/false); |
901 | 81 | } else if (auto GTD = dyn_cast<GenericTypeDecl>(Decl)) { |
902 | 6 | appendAnyGenericType(GTD); |
903 | 75 | } else if (isa<AssociatedTypeDecl>(Decl)) { |
904 | 0 | appendContextOf(Decl); |
905 | 0 | appendDeclName(Decl); |
906 | 0 | appendOperator("Qa"); |
907 | 75 | } else { |
908 | 75 | appendEntity(Decl); |
909 | 75 | } |
910 | | |
911 | 87 | appendSymbolKind(ASTMangler::SymbolKind::HasSymbolQuery); |
912 | | |
913 | 87 | return finalize(); |
914 | 87 | } |
915 | | |
916 | 2.03M | void ASTMangler::appendSymbolKind(SymbolKind SKind) { |
917 | 2.03M | switch (SKind) { |
918 | 2.00M | case SymbolKind::Default: return; |
919 | 2.37k | case SymbolKind::DynamicThunk: return appendOperator("TD"); |
920 | 20.6k | case SymbolKind::SwiftAsObjCThunk: return appendOperator("To"); |
921 | 4.20k | case SymbolKind::ObjCAsSwiftThunk: return appendOperator("TO"); |
922 | 984 | case SymbolKind::DistributedThunk: return appendOperator("TE"); |
923 | 0 | case SymbolKind::DistributedAccessor: return appendOperator("TF"); |
924 | 0 | case SymbolKind::AccessibleFunctionRecord: return appendOperator("HF"); |
925 | 1.31k | case SymbolKind::BackDeploymentThunk: return appendOperator("Twb"); |
926 | 585 | case SymbolKind::BackDeploymentFallback: return appendOperator("TwB"); |
927 | 87 | case SymbolKind::HasSymbolQuery: return appendOperator("TwS"); |
928 | 2.03M | } |
929 | 2.03M | } |
930 | | |
931 | | static bool getUnnamedParamIndex(const ParameterList *ParamList, |
932 | | const ParamDecl *D, |
933 | 87 | unsigned &UnnamedIndex) { |
934 | 120 | for (auto Param : *ParamList) { |
935 | 120 | if (!Param->hasName()) { |
936 | 102 | if (Param == D) |
937 | 87 | return true; |
938 | 15 | ++UnnamedIndex; |
939 | 15 | } |
940 | 120 | } |
941 | 0 | return false; |
942 | 87 | } |
943 | | |
944 | 87 | static unsigned getUnnamedParamIndex(const ParamDecl *D) { |
945 | 87 | ParameterList *ParamList; |
946 | 87 | auto *DC = D->getDeclContext(); |
947 | 87 | if (isa<AbstractClosureExpr>(DC)) { |
948 | 9 | ParamList = cast<AbstractClosureExpr>(DC)->getParameters(); |
949 | 78 | } else { |
950 | 78 | ParamList = getParameterList(cast<ValueDecl>(DC->getAsDecl())); |
951 | 78 | } |
952 | | |
953 | 87 | unsigned UnnamedIndex = 0; |
954 | 87 | if (getUnnamedParamIndex(ParamList, D, UnnamedIndex)) |
955 | 87 | return UnnamedIndex; |
956 | | |
957 | 0 | llvm_unreachable("param not found"); |
958 | 0 | } |
959 | | |
960 | 13.1M | static StringRef getPrivateDiscriminatorIfNecessary(const Decl *decl) { |
961 | 13.1M | if (!decl->isOutermostPrivateOrFilePrivateScope()) |
962 | 12.8M | return StringRef(); |
963 | | |
964 | | // Mangle non-local private declarations with a textual discriminator |
965 | | // based on their enclosing file. |
966 | 271k | auto topLevelSubcontext = decl->getDeclContext()->getModuleScopeContext(); |
967 | 271k | auto fileUnit = cast<FileUnit>(topLevelSubcontext); |
968 | | |
969 | 271k | Identifier discriminator = |
970 | 271k | fileUnit->getDiscriminatorForPrivateDecl(decl); |
971 | 271k | assert(!discriminator.empty()); |
972 | 0 | assert(!isNonAscii(discriminator.str()) && |
973 | 271k | "discriminator contains non-ASCII characters"); |
974 | 0 | (void)&isNonAscii; |
975 | 271k | assert(!clang::isDigit(discriminator.str().front()) && |
976 | 271k | "not a valid identifier"); |
977 | 0 | return discriminator.str(); |
978 | 13.1M | } |
979 | | |
980 | | /// If the declaration is an @objc protocol defined in Swift and the |
981 | | /// Objective-C name has been overridden from the default, return the |
982 | | /// specified name. |
983 | | /// |
984 | | /// \param useObjCProtocolNames When false, always returns \c None. |
985 | | static llvm::Optional<std::string> |
986 | | getOverriddenSwiftProtocolObjCName(const ValueDecl *decl, |
987 | 26.7M | bool useObjCProtocolNames) { |
988 | 26.7M | if (!useObjCProtocolNames) |
989 | 26.7M | return llvm::None; |
990 | | |
991 | 1.59k | auto proto = dyn_cast<ProtocolDecl>(decl); |
992 | 1.59k | if (!proto) |
993 | 612 | return llvm::None; |
994 | | |
995 | 978 | if (!proto->isObjC()) |
996 | 228 | return llvm::None; |
997 | | |
998 | | // If there is an 'objc' attribute with a name, use that name. |
999 | 750 | if (auto objc = proto->getAttrs().getAttribute<ObjCAttr>()) { |
1000 | 750 | if (auto name = objc->getName()) { |
1001 | 24 | llvm::SmallString<4> buffer; |
1002 | 24 | return std::string(name->getString(buffer)); |
1003 | 24 | } |
1004 | 750 | } |
1005 | | |
1006 | 726 | return llvm::None; |
1007 | 750 | } |
1008 | | |
1009 | 12.8M | void ASTMangler::appendDeclName(const ValueDecl *decl, DeclBaseName name) { |
1010 | 12.8M | if (name.empty()) |
1011 | 12.8M | name = decl->getBaseName(); |
1012 | 12.8M | assert(!name.isSpecial() && "Cannot print special names"); |
1013 | | |
1014 | 0 | auto *synthesizedTypeAttr = |
1015 | 12.8M | decl->getAttrs().getAttribute<ClangImporterSynthesizedTypeAttr>(); |
1016 | | |
1017 | 12.8M | if (synthesizedTypeAttr) { |
1018 | 4.44k | assert(!isDigit(synthesizedTypeAttr->originalTypeName[0]) && |
1019 | 4.44k | "synthesized type's original name must be a valid Swift identifier"); |
1020 | 0 | appendIdentifier(synthesizedTypeAttr->originalTypeName); |
1021 | 12.8M | } else if (name.isOperator()) { |
1022 | 320k | appendIdentifier(translateOperator(name.getIdentifier().str())); |
1023 | 320k | switch (decl->getAttrs().getUnaryOperatorKind()) { |
1024 | 16.7k | case UnaryOperatorKind::Prefix: |
1025 | 16.7k | appendOperator("op"); |
1026 | 16.7k | break; |
1027 | 354 | case UnaryOperatorKind::Postfix: |
1028 | 354 | appendOperator("oP"); |
1029 | 354 | break; |
1030 | 303k | case UnaryOperatorKind::None: |
1031 | 303k | appendOperator("oi"); |
1032 | 303k | break; |
1033 | 320k | } |
1034 | 12.5M | } else if (auto objCName = |
1035 | 12.5M | getOverriddenSwiftProtocolObjCName(decl, UseObjCRuntimeNames)) { |
1036 | | // @objc Swift protocols should be mangled as Objective-C protocols, |
1037 | | // so append the Objective-C runtime name. |
1038 | 12 | appendIdentifier(*objCName); |
1039 | 12.5M | } else if (!name.empty()) { |
1040 | 12.5M | appendIdentifier(name.getIdentifier().str()); |
1041 | 12.5M | } else { |
1042 | 87 | assert(AllowNamelessEntities && "attempt to mangle unnamed decl"); |
1043 | | // Fall back to an unlikely name, so that we still generate a valid |
1044 | | // mangled name. |
1045 | 0 | appendIdentifier("_"); |
1046 | 87 | } |
1047 | | |
1048 | 12.8M | if (decl->getDeclContext()->isLocalContext()) { |
1049 | 132k | if (auto *paramDecl = dyn_cast<ParamDecl>(decl)) { |
1050 | 1.90k | if (!decl->hasName()) { |
1051 | | // Mangle unnamed params with their ordering. |
1052 | 87 | return appendOperator("L", Index(getUnnamedParamIndex(paramDecl))); |
1053 | 87 | } |
1054 | 1.90k | } |
1055 | | // Mangle local declarations with a numeric discriminator. |
1056 | 132k | return appendOperator("L", Index(decl->getLocalDiscriminator())); |
1057 | 132k | } |
1058 | | |
1059 | 12.6M | if (synthesizedTypeAttr) { |
1060 | 4.44k | StringRef relatedEntityKind = synthesizedTypeAttr->getManglingName(); |
1061 | 4.44k | assert(relatedEntityKind.size() == 1 && |
1062 | 4.44k | "'L' operator only supports a single letter payload"); |
1063 | 0 | assert(((relatedEntityKind[0] >= 'a' && relatedEntityKind[0] <= 'j') || |
1064 | 4.44k | (relatedEntityKind[0] >= 'A' && relatedEntityKind[0] <= 'J')) && |
1065 | 4.44k | "Only [a-jA-J] are reserved for related entity kinds"); |
1066 | 0 | return appendOperatorParam("L", relatedEntityKind); |
1067 | 4.44k | } |
1068 | | |
1069 | 12.6M | StringRef privateDiscriminator = getPrivateDiscriminatorIfNecessary(decl); |
1070 | 12.6M | if (!privateDiscriminator.empty()) { |
1071 | 266k | appendIdentifier(privateDiscriminator.str()); |
1072 | 266k | return appendOperator("LL"); |
1073 | 266k | } |
1074 | 12.6M | } |
1075 | | |
1076 | 44.4k | static const char *getMetatypeRepresentationOp(MetatypeRepresentation Rep) { |
1077 | 44.4k | switch (Rep) { |
1078 | 18.9k | case MetatypeRepresentation::Thin: |
1079 | 18.9k | return "t"; |
1080 | 25.3k | case MetatypeRepresentation::Thick: |
1081 | 25.3k | return "T"; |
1082 | 105 | case MetatypeRepresentation::ObjC: |
1083 | 105 | return "o"; |
1084 | 44.4k | } |
1085 | | |
1086 | 0 | llvm_unreachable("Unhandled MetatypeRepresentation in switch."); |
1087 | 0 | } |
1088 | | |
1089 | 240k | static char getParamConvention(ParameterConvention conv) { |
1090 | | // @in and @out are mangled the same because they're put in |
1091 | | // different places. |
1092 | 240k | switch (conv) { |
1093 | 424 | case ParameterConvention::Indirect_In: return 'i'; |
1094 | 21.7k | case ParameterConvention::Indirect_Inout: return 'l'; |
1095 | 0 | case ParameterConvention::Indirect_InoutAliasable: return 'b'; |
1096 | 43.2k | case ParameterConvention::Indirect_In_Guaranteed: return 'n'; |
1097 | 203 | case ParameterConvention::Direct_Owned: return 'x'; |
1098 | 64.7k | case ParameterConvention::Direct_Unowned: return 'y'; |
1099 | 109k | case ParameterConvention::Direct_Guaranteed: return 'g'; |
1100 | 0 | case ParameterConvention::Pack_Owned: return 'v'; |
1101 | 0 | case ParameterConvention::Pack_Inout: return 'm'; |
1102 | 39 | case ParameterConvention::Pack_Guaranteed: return 'p'; |
1103 | 240k | } |
1104 | 0 | llvm_unreachable("bad parameter convention"); |
1105 | 0 | } |
1106 | | |
1107 | | /// Whether to mangle the given type as generic. |
1108 | 11.0M | static bool shouldMangleAsGeneric(Type type) { |
1109 | 11.0M | if (!type) |
1110 | 0 | return false; |
1111 | | |
1112 | 11.0M | if (auto typeAlias = dyn_cast<TypeAliasType>(type.getPointer())) |
1113 | 0 | return !typeAlias->getSubstitutionMap().empty(); |
1114 | | |
1115 | 11.0M | return type->isSpecialized(); |
1116 | 11.0M | } |
1117 | | |
1118 | 5.44k | void ASTMangler::appendOpaqueDeclName(const OpaqueTypeDecl *opaqueDecl) { |
1119 | 5.44k | if (canSymbolicReference(opaqueDecl)) { |
1120 | 492 | appendSymbolicReference(opaqueDecl); |
1121 | 4.95k | } else if (auto namingDecl = opaqueDecl->getNamingDecl()) { |
1122 | | // Set this to true temporarily, even if we're doing DWARF |
1123 | | // mangling for debug info, where it is false. Otherwise, |
1124 | | // the mangled opaque result type name will not be able to |
1125 | | // be looked up, since we rely on an exact match with the |
1126 | | // ABI name. |
1127 | 4.95k | llvm::SaveAndRestore<bool> savedRespectOriginallyDefinedIn( |
1128 | 4.95k | RespectOriginallyDefinedIn, true); |
1129 | | |
1130 | 4.95k | appendEntity(namingDecl); |
1131 | 4.95k | appendOperator("QO"); |
1132 | 4.95k | } else { |
1133 | 0 | llvm_unreachable("todo: independent opaque type decls"); |
1134 | 0 | } |
1135 | 5.44k | } |
1136 | | |
1137 | | void ASTMangler::appendExistentialLayout( |
1138 | | const ExistentialLayout &layout, GenericSignature sig, |
1139 | 582k | const ValueDecl *forDecl) { |
1140 | 582k | bool First = true; |
1141 | 582k | bool DroppedRequiresClass = false; |
1142 | 582k | bool SawRequiresClass = false; |
1143 | 582k | for (auto proto : layout.getProtocols()) { |
1144 | | // If we aren't allowed to emit marker protocols, suppress them here. |
1145 | 376k | if (!AllowMarkerProtocols && proto->isMarkerProtocol()) { |
1146 | 129 | if (proto->requiresClass()) |
1147 | 3 | DroppedRequiresClass = true; |
1148 | | |
1149 | 129 | continue; |
1150 | 129 | } |
1151 | | |
1152 | 376k | if (proto->requiresClass()) |
1153 | 22.7k | SawRequiresClass = true; |
1154 | | |
1155 | 376k | appendProtocolName(proto); |
1156 | 376k | appendListSeparator(First); |
1157 | 376k | } |
1158 | 582k | if (First) |
1159 | 210k | appendOperator("y"); |
1160 | | |
1161 | 582k | if (auto superclass = layout.explicitSuperclass) { |
1162 | 1.53k | appendType(superclass, sig, forDecl); |
1163 | 1.53k | return appendOperator("Xc"); |
1164 | 580k | } else if (layout.hasExplicitAnyObject || |
1165 | 580k | (DroppedRequiresClass && !SawRequiresClass)) { |
1166 | 39.8k | return appendOperator("Xl"); |
1167 | 39.8k | } |
1168 | 540k | return appendOperator("p"); |
1169 | 582k | } |
1170 | | |
1171 | | /// Mangle a type into the buffer. |
1172 | | /// |
1173 | | void ASTMangler::appendType(Type type, GenericSignature sig, |
1174 | 15.2M | const ValueDecl *forDecl) { |
1175 | 15.2M | assert((DWARFMangling || type->isCanonical()) && |
1176 | 15.2M | "expecting canonical types when not mangling for the debugger"); |
1177 | 0 | TypeBase *tybase = type.getPointer(); |
1178 | 15.2M | switch (type->getKind()) { |
1179 | 0 | case TypeKind::TypeVariable: |
1180 | 0 | llvm_unreachable("mangling type variable"); |
1181 | |
|
1182 | 0 | case TypeKind::Module: |
1183 | 0 | llvm_unreachable("Cannot mangle module type yet"); |
1184 | |
|
1185 | 2.45k | case TypeKind::Error: |
1186 | 2.83k | case TypeKind::Unresolved: |
1187 | 2.83k | case TypeKind::Placeholder: |
1188 | 2.83k | appendOperator("Xe"); |
1189 | 2.83k | return; |
1190 | | |
1191 | | // We don't care about these types being a bit verbose because we |
1192 | | // don't expect them to come up that often in API names. |
1193 | 3.03k | case TypeKind::BuiltinFloat: |
1194 | 3.03k | switch (cast<BuiltinFloatType>(tybase)->getFPKind()) { |
1195 | 342 | case BuiltinFloatType::IEEE16: appendOperator("Bf16_"); return; |
1196 | 741 | case BuiltinFloatType::IEEE32: appendOperator("Bf32_"); return; |
1197 | 1.89k | case BuiltinFloatType::IEEE64: appendOperator("Bf64_"); return; |
1198 | 60 | case BuiltinFloatType::IEEE80: appendOperator("Bf80_"); return; |
1199 | 0 | case BuiltinFloatType::IEEE128: appendOperator("Bf128_"); return; |
1200 | 0 | case BuiltinFloatType::PPC128: llvm_unreachable("ppc128 not supported"); |
1201 | 3.03k | } |
1202 | 0 | llvm_unreachable("bad floating-point kind"); |
1203 | 58.2k | case TypeKind::BuiltinInteger: { |
1204 | 58.2k | auto width = cast<BuiltinIntegerType>(tybase)->getWidth(); |
1205 | 58.2k | if (width.isFixedWidth()) |
1206 | 33.0k | appendOperator("Bi", Index(width.getFixedWidth() + 1)); |
1207 | 25.1k | else if (width.isPointerWidth()) |
1208 | 25.1k | appendOperator("Bw"); |
1209 | 0 | else |
1210 | 0 | llvm_unreachable("impossible width value"); |
1211 | 58.2k | return; |
1212 | 0 | } |
1213 | 18.8k | case TypeKind::BuiltinIntegerLiteral: |
1214 | 18.8k | return appendOperator("BI"); |
1215 | 51 | case TypeKind::BuiltinJob: |
1216 | 51 | return appendOperator("Bj"); |
1217 | 1.78k | case TypeKind::BuiltinExecutor: |
1218 | 1.78k | return appendOperator("Be"); |
1219 | 387 | case TypeKind::BuiltinDefaultActorStorage: |
1220 | 387 | return appendOperator("BD"); |
1221 | 12 | case TypeKind::BuiltinNonDefaultDistributedActorStorage: |
1222 | 12 | return appendOperator("Bd"); |
1223 | 0 | case TypeKind::BuiltinPackIndex: |
1224 | 0 | return appendOperator("BP"); |
1225 | 29.4k | case TypeKind::BuiltinRawPointer: |
1226 | 29.4k | return appendOperator("Bp"); |
1227 | 273 | case TypeKind::BuiltinRawUnsafeContinuation: |
1228 | 273 | return appendOperator("Bc"); |
1229 | 5.45k | case TypeKind::BuiltinNativeObject: |
1230 | 5.45k | return appendOperator("Bo"); |
1231 | 1.04k | case TypeKind::BuiltinBridgeObject: |
1232 | 1.04k | return appendOperator("Bb"); |
1233 | 141 | case TypeKind::BuiltinUnsafeValueBuffer: |
1234 | 141 | return appendOperator("BB"); |
1235 | 0 | case TypeKind::SILToken: |
1236 | 0 | return appendOperator("Bt"); |
1237 | 8.43k | case TypeKind::BuiltinVector: |
1238 | 8.43k | appendType(cast<BuiltinVectorType>(tybase)->getElementType(), sig, |
1239 | 8.43k | forDecl); |
1240 | | // The mangling calls for using the actual element count, which we have |
1241 | | // to adjust by 1 in order to mangle it as an index. |
1242 | 8.43k | return appendOperator("Bv", |
1243 | 8.43k | Index(cast<BuiltinVectorType>(tybase)->getNumElements() + 1)); |
1244 | 1.75k | case TypeKind::TypeAlias: { |
1245 | 1.75k | assert(DWARFMangling && "sugared types are only legal for the debugger"); |
1246 | 0 | auto aliasTy = cast<TypeAliasType>(tybase); |
1247 | | |
1248 | | // It's not possible to mangle the context of the builtin module. |
1249 | | // For the DWARF output we want to mangle the type alias + context, |
1250 | | // unless the type alias references a builtin type. |
1251 | 1.75k | auto underlyingType = aliasTy->getSinglyDesugaredType(); |
1252 | 1.75k | TypeAliasDecl *decl = aliasTy->getDecl(); |
1253 | 1.75k | if (decl->getModuleContext() == decl->getASTContext().TheBuiltinModule) { |
1254 | 96 | return appendType(underlyingType, sig, forDecl); |
1255 | 96 | } |
1256 | | |
1257 | 1.65k | if (decl->getDeclaredInterfaceType() |
1258 | 1.65k | .subst(aliasTy->getSubstitutionMap()).getPointer() |
1259 | 1.65k | != aliasTy) { |
1260 | 3 | return appendType(underlyingType, sig, forDecl); |
1261 | 3 | } |
1262 | | |
1263 | 1.65k | if (aliasTy->getSubstitutionMap()) { |
1264 | | // Try to mangle the entire name as a substitution. |
1265 | 249 | if (tryMangleTypeSubstitution(tybase, sig)) |
1266 | 12 | return; |
1267 | | |
1268 | 237 | appendAnyGenericType(decl); |
1269 | 237 | bool isFirstArgList = true; |
1270 | 237 | appendBoundGenericArgs(type, sig, isFirstArgList, forDecl); |
1271 | 237 | appendRetroactiveConformances(type, sig); |
1272 | 237 | appendOperator("G"); |
1273 | 237 | addTypeSubstitution(type, sig); |
1274 | 237 | return; |
1275 | 249 | } |
1276 | | |
1277 | 1.40k | return appendAnyGenericType(decl); |
1278 | 1.65k | } |
1279 | | |
1280 | 3.16k | case TypeKind::PackExpansion: { |
1281 | 3.16k | auto expansionTy = cast<PackExpansionType>(tybase); |
1282 | 3.16k | appendType(expansionTy->getPatternType(), sig, forDecl); |
1283 | 3.16k | appendType(expansionTy->getCountType(), sig, forDecl); |
1284 | 3.16k | appendOperator("Qp"); |
1285 | 3.16k | return; |
1286 | 1.65k | } |
1287 | | |
1288 | 3 | case TypeKind::PackElement: { |
1289 | 3 | auto elementType = cast<PackElementType>(tybase); |
1290 | 3 | appendType(elementType->getPackType(), sig, forDecl); |
1291 | | // If this ever changes, just mangle level 0 as a plain type parameter. |
1292 | 3 | assert(elementType->getLevel() > 0); |
1293 | 0 | appendOperator("Qe", Index(elementType->getLevel() - 1)); |
1294 | | |
1295 | 3 | return; |
1296 | 1.65k | } |
1297 | | |
1298 | 4.26k | case TypeKind::Pack: { |
1299 | 4.26k | auto packTy = cast<PackType>(tybase); |
1300 | | |
1301 | 4.26k | if (packTy->getNumElements() == 0) |
1302 | 591 | appendOperator("y"); |
1303 | 3.67k | else { |
1304 | 3.67k | bool firstField = true; |
1305 | 7.03k | for (auto element : packTy->getElementTypes()) { |
1306 | 7.03k | appendType(element, sig, forDecl); |
1307 | 7.03k | appendListSeparator(firstField); |
1308 | 7.03k | } |
1309 | 3.67k | } |
1310 | 4.26k | appendOperator("QP"); |
1311 | 4.26k | return; |
1312 | 1.65k | } |
1313 | | |
1314 | 180 | case TypeKind::SILPack: { |
1315 | 180 | auto packTy = cast<SILPackType>(tybase); |
1316 | | |
1317 | 180 | if (packTy->getNumElements() == 0) |
1318 | 12 | appendOperator("y"); |
1319 | 168 | else { |
1320 | 168 | bool firstField = true; |
1321 | 198 | for (auto element : packTy->getElementTypes()) { |
1322 | 198 | appendType(element, sig, forDecl); |
1323 | 198 | appendListSeparator(firstField); |
1324 | 198 | } |
1325 | 168 | } |
1326 | 180 | appendOperator("QS"); |
1327 | 180 | Buffer << (packTy->isElementAddress() ? 'i' : 'd'); |
1328 | 180 | return; |
1329 | 1.65k | } |
1330 | | |
1331 | 75 | case TypeKind::Paren: |
1332 | 75 | assert(DWARFMangling && "sugared types are only legal for the debugger"); |
1333 | 0 | appendType(cast<ParenType>(tybase)->getUnderlyingType(), sig, forDecl); |
1334 | 75 | appendOperator("XSp"); |
1335 | 75 | return; |
1336 | | |
1337 | 117 | case TypeKind::ArraySlice: |
1338 | 117 | assert(DWARFMangling && "sugared types are only legal for the debugger"); |
1339 | 0 | appendType(cast<ArraySliceType>(tybase)->getBaseType(), sig, forDecl); |
1340 | 117 | appendOperator("XSa"); |
1341 | 117 | return; |
1342 | | |
1343 | 0 | case TypeKind::VariadicSequence: |
1344 | 0 | assert(DWARFMangling && "sugared types are only legal for the debugger"); |
1345 | 0 | appendType(cast<VariadicSequenceType>(tybase)->getBaseType(), sig, forDecl); |
1346 | 0 | appendOperator("XSa"); |
1347 | 0 | return; |
1348 | | |
1349 | 348 | case TypeKind::Optional: |
1350 | 348 | assert(DWARFMangling && "sugared types are only legal for the debugger"); |
1351 | 0 | appendType(cast<OptionalType>(tybase)->getBaseType(), sig, forDecl); |
1352 | 348 | appendOperator("XSq"); |
1353 | 348 | return; |
1354 | | |
1355 | 63 | case TypeKind::Dictionary: |
1356 | 63 | assert(DWARFMangling && "sugared types are only legal for the debugger"); |
1357 | 0 | appendType(cast<DictionaryType>(tybase)->getKeyType(), sig, forDecl); |
1358 | 63 | appendType(cast<DictionaryType>(tybase)->getValueType(), sig, forDecl); |
1359 | 63 | appendOperator("XSD"); |
1360 | 63 | return; |
1361 | | |
1362 | 41.7k | case TypeKind::ExistentialMetatype: { |
1363 | 41.7k | ExistentialMetatypeType *EMT = cast<ExistentialMetatypeType>(tybase); |
1364 | | |
1365 | | // ExtendedExistentialTypeShapes consider existential metatypes to |
1366 | | // be part of the existential, so if we're symbolically referencing |
1367 | | // shapes, we need to handle that at this level. |
1368 | 41.7k | if (EMT->hasParameterizedExistential()) { |
1369 | 240 | auto referent = SymbolicReferent::forExtendedExistentialTypeShape(EMT); |
1370 | 240 | if (canSymbolicReference(referent)) { |
1371 | 18 | appendSymbolicExtendedExistentialType(referent, EMT, sig, forDecl); |
1372 | 18 | return; |
1373 | 18 | } |
1374 | 240 | } |
1375 | | |
1376 | 41.7k | if (EMT->getInstanceType()->isExistentialType() && |
1377 | 41.7k | EMT->hasParameterizedExistential()) |
1378 | 168 | appendConstrainedExistential(EMT->getInstanceType(), sig, forDecl); |
1379 | 41.5k | else |
1380 | 41.5k | appendType(EMT->getInstanceType(), sig, forDecl); |
1381 | | |
1382 | 41.7k | if (EMT->hasRepresentation()) { |
1383 | 1.33k | appendOperator("Xm", |
1384 | 1.33k | getMetatypeRepresentationOp(EMT->getRepresentation())); |
1385 | 40.4k | } else { |
1386 | 40.4k | appendOperator("Xp"); |
1387 | 40.4k | } |
1388 | 41.7k | return; |
1389 | 41.7k | } |
1390 | 204k | case TypeKind::Metatype: { |
1391 | 204k | MetatypeType *MT = cast<MetatypeType>(tybase); |
1392 | 204k | appendType(MT->getInstanceType(), sig, forDecl); |
1393 | 204k | if (MT->hasRepresentation()) { |
1394 | 43.0k | appendOperator("XM", |
1395 | 43.0k | getMetatypeRepresentationOp(MT->getRepresentation())); |
1396 | 161k | } else { |
1397 | 161k | appendOperator("m"); |
1398 | 161k | } |
1399 | 204k | return; |
1400 | 41.7k | } |
1401 | 0 | case TypeKind::LValue: |
1402 | 0 | llvm_unreachable("@lvalue types should not occur in function interfaces"); |
1403 | |
|
1404 | 0 | case TypeKind::Inverse: |
1405 | 0 | llvm_unreachable("inverse types should not appear in interfaces"); |
1406 | |
|
1407 | 0 | case TypeKind::InOut: |
1408 | 0 | appendType(cast<InOutType>(tybase)->getObjectType(), sig, forDecl); |
1409 | 0 | return appendOperator("z"); |
1410 | | |
1411 | 0 | #define REF_STORAGE(Name, ...) \ |
1412 | 867 | case TypeKind::Name##Storage: \ |
1413 | 867 | appendType(cast<Name##StorageType>(tybase)->getReferentType(), sig, forDecl); \ |
1414 | 867 | return appendOperator(manglingOf(ReferenceOwnership::Name)); |
1415 | 0 | #include "swift/AST/ReferenceStorage.def" |
1416 | | |
1417 | 138k | case TypeKind::Tuple: |
1418 | 138k | appendTypeList(type, sig, forDecl); |
1419 | 138k | return appendOperator("t"); |
1420 | | |
1421 | 364k | case TypeKind::Protocol: { |
1422 | 364k | return appendExistentialLayout( |
1423 | 364k | ExistentialLayout(CanProtocolType(cast<ProtocolType>(tybase))), |
1424 | 364k | sig, forDecl); |
1425 | 0 | } |
1426 | | |
1427 | 216k | case TypeKind::ProtocolComposition: { |
1428 | 216k | auto *PCT = cast<ProtocolCompositionType>(tybase); |
1429 | 216k | if (PCT->hasParameterizedExistential()) |
1430 | 0 | return appendConstrainedExistential(PCT, sig, forDecl); |
1431 | | |
1432 | | // We mangle ProtocolType and ProtocolCompositionType using the |
1433 | | // same production: |
1434 | 216k | auto layout = PCT->getExistentialLayout(); |
1435 | 216k | return appendExistentialLayout(layout, sig, forDecl); |
1436 | 216k | } |
1437 | | |
1438 | 45 | case TypeKind::ParameterizedProtocol: |
1439 | 45 | return appendConstrainedExistential(tybase, sig, forDecl); |
1440 | | |
1441 | 301k | case TypeKind::Existential: { |
1442 | 301k | auto *ET = cast<ExistentialType>(tybase); |
1443 | 301k | if (ET->hasParameterizedExistential()) { |
1444 | 1.08k | auto referent = SymbolicReferent::forExtendedExistentialTypeShape(ET); |
1445 | 1.08k | if (canSymbolicReference(referent)) { |
1446 | 63 | appendSymbolicExtendedExistentialType(referent, ET, sig, forDecl); |
1447 | 63 | return; |
1448 | 63 | } |
1449 | | |
1450 | 1.01k | return appendConstrainedExistential(ET->getConstraintType(), sig, |
1451 | 1.01k | forDecl); |
1452 | 1.08k | } |
1453 | 300k | return appendType(ET->getConstraintType(), sig, forDecl); |
1454 | 301k | } |
1455 | | |
1456 | 131k | case TypeKind::UnboundGeneric: |
1457 | 703k | case TypeKind::Class: |
1458 | 1.20M | case TypeKind::Enum: |
1459 | 7.46M | case TypeKind::Struct: |
1460 | 7.54M | case TypeKind::BoundGenericClass: |
1461 | 8.21M | case TypeKind::BoundGenericEnum: |
1462 | 11.0M | case TypeKind::BoundGenericStruct: |
1463 | 11.0M | case TypeKind::BuiltinTuple: { |
1464 | 11.0M | GenericTypeDecl *Decl; |
1465 | 11.0M | if (auto typeAlias = dyn_cast<TypeAliasType>(type.getPointer())) |
1466 | 0 | Decl = typeAlias->getDecl(); |
1467 | 11.0M | else |
1468 | 11.0M | Decl = type->getAnyGeneric(); |
1469 | 11.0M | if (shouldMangleAsGeneric(type)) { |
1470 | | // Try to mangle the entire name as a substitution. |
1471 | 3.72M | if (tryMangleTypeSubstitution(tybase, sig)) |
1472 | 374k | return; |
1473 | | |
1474 | 3.34M | if (Decl->isStdlibDecl() && Decl->getName().str() == "Optional") { |
1475 | 593k | auto GenArgs = type->castTo<BoundGenericType>()->getGenericArgs(); |
1476 | 593k | assert(GenArgs.size() == 1); |
1477 | 0 | appendType(GenArgs[0], sig, forDecl); |
1478 | 593k | appendOperator("Sg"); |
1479 | 2.75M | } else { |
1480 | 2.75M | appendAnyGenericType(Decl); |
1481 | 2.75M | bool isFirstArgList = true; |
1482 | 2.75M | appendBoundGenericArgs(type, sig, isFirstArgList, forDecl); |
1483 | 2.75M | appendRetroactiveConformances(type, sig); |
1484 | 2.75M | appendOperator("G"); |
1485 | 2.75M | } |
1486 | 0 | addTypeSubstitution(type, sig); |
1487 | 3.34M | return; |
1488 | 3.72M | } |
1489 | 7.36M | appendAnyGenericType(type->getAnyGeneric()); |
1490 | 7.36M | return; |
1491 | 11.0M | } |
1492 | | |
1493 | 110k | case TypeKind::SILFunction: |
1494 | 110k | return appendImplFunctionType(cast<SILFunctionType>(tybase), sig, |
1495 | 110k | forDecl); |
1496 | | |
1497 | | // type ::= archetype |
1498 | 0 | case TypeKind::PrimaryArchetype: |
1499 | 0 | case TypeKind::PackArchetype: |
1500 | 0 | case TypeKind::ElementArchetype: |
1501 | 0 | case TypeKind::OpenedArchetype: |
1502 | 0 | llvm_unreachable("Cannot mangle free-standing archetypes"); |
1503 | |
|
1504 | 14.8k | case TypeKind::OpaqueTypeArchetype: { |
1505 | 14.8k | auto opaqueType = cast<OpaqueTypeArchetypeType>(tybase); |
1506 | 14.8k | auto opaqueDecl = opaqueType->getDecl(); |
1507 | 14.8k | return appendOpaqueTypeArchetype( |
1508 | 14.8k | opaqueType, opaqueDecl, opaqueType->getSubstitutions(), sig, forDecl); |
1509 | 0 | } |
1510 | | |
1511 | 2.00k | case TypeKind::DynamicSelf: { |
1512 | 2.00k | auto dynamicSelf = cast<DynamicSelfType>(tybase); |
1513 | 2.00k | if (dynamicSelf->getSelfType()->getAnyNominal()) { |
1514 | 2.00k | appendType(dynamicSelf->getSelfType(), sig, forDecl); |
1515 | 2.00k | return appendOperator("XD"); |
1516 | 2.00k | } |
1517 | 0 | return appendType(dynamicSelf->getSelfType(), sig, forDecl); |
1518 | 2.00k | } |
1519 | | |
1520 | 0 | case TypeKind::GenericFunction: { |
1521 | 0 | auto genFunc = cast<GenericFunctionType>(tybase); |
1522 | 0 | appendFunctionType(genFunc, genFunc->getGenericSignature(), |
1523 | 0 | /*autoclosure*/ false, forDecl); |
1524 | 0 | appendGenericSignature(genFunc->getGenericSignature()); |
1525 | 0 | appendOperator("u"); |
1526 | 0 | return; |
1527 | 2.00k | } |
1528 | | |
1529 | 1.87M | case TypeKind::GenericTypeParam: { |
1530 | 1.87M | auto paramTy = cast<GenericTypeParamType>(tybase); |
1531 | | // If this assertion fires, it probably means the type being mangled here |
1532 | | // didn't go through getTypeForDWARFMangling(). |
1533 | 1.87M | assert(paramTy->getDecl() == nullptr && |
1534 | 1.87M | "cannot mangle non-canonical generic parameter"); |
1535 | | // A special mangling for the very first generic parameter. This shows up |
1536 | | // frequently because it corresponds to 'Self' in protocol requirement |
1537 | | // generic signatures. |
1538 | 1.87M | if (paramTy->getDepth() == 0 && paramTy->getIndex() == 0) |
1539 | 1.35M | return appendOperator("x"); |
1540 | | |
1541 | 523k | return appendOpWithGenericParamIndex("q", paramTy); |
1542 | 1.87M | } |
1543 | | |
1544 | 487k | case TypeKind::DependentMember: { |
1545 | 487k | auto *DepTy = cast<DependentMemberType>(tybase); |
1546 | 487k | if (tryMangleTypeSubstitution(DepTy, sig)) |
1547 | 79.3k | return; |
1548 | | |
1549 | 408k | bool isAssocTypeAtDepth = false; |
1550 | 408k | if (GenericTypeParamType *gpBase = appendAssocType(DepTy, sig, |
1551 | 408k | isAssocTypeAtDepth)) { |
1552 | 408k | if (gpBase->getDepth() == 0 && gpBase->getIndex() == 0) { |
1553 | 340k | appendOperator(isAssocTypeAtDepth ? "QZ" : "Qz"); |
1554 | 340k | } else { |
1555 | 67.7k | appendOpWithGenericParamIndex(isAssocTypeAtDepth ? "QY" : "Qy", |
1556 | 67.7k | gpBase); |
1557 | 67.7k | } |
1558 | 408k | } else { |
1559 | | // Dependent members of non-generic-param types are not canonical, but |
1560 | | // we may still want to mangle them for debugging or indexing purposes. |
1561 | 0 | appendType(DepTy->getBase(), sig, forDecl); |
1562 | 0 | appendIdentifier(DepTy->getName().str()); |
1563 | 0 | appendOperator("Qa"); |
1564 | 0 | } |
1565 | 408k | addTypeSubstitution(DepTy, sig); |
1566 | 408k | return; |
1567 | 487k | } |
1568 | | |
1569 | 224k | case TypeKind::Function: |
1570 | 224k | appendFunctionType(cast<FunctionType>(tybase), sig, |
1571 | 224k | /*autoclosure*/ false, |
1572 | 224k | forDecl); |
1573 | 224k | return; |
1574 | | |
1575 | 196 | case TypeKind::SILBox: { |
1576 | 196 | auto box = cast<SILBoxType>(tybase); |
1577 | 196 | auto layout = box->getLayout(); |
1578 | 196 | bool firstField = true; |
1579 | 196 | for (auto &field : layout->getFields()) { |
1580 | 196 | appendType(field.getLoweredType(), sig, forDecl); |
1581 | 196 | if (field.isMutable()) { |
1582 | | // Use the `inout` mangling to represent a mutable field. |
1583 | 193 | appendOperator("z"); |
1584 | 193 | } |
1585 | 196 | appendListSeparator(firstField); |
1586 | 196 | } |
1587 | 196 | if (firstField) |
1588 | 0 | appendOperator("y"); |
1589 | | |
1590 | 196 | if (auto sig = layout->getGenericSignature()) { |
1591 | 48 | bool firstType = true; |
1592 | 54 | for (Type type : box->getSubstitutions().getReplacementTypes()) { |
1593 | 54 | appendType(type, sig, forDecl); |
1594 | 54 | appendListSeparator(firstType); |
1595 | 54 | } |
1596 | 48 | if (firstType) |
1597 | 0 | appendOperator("y"); |
1598 | | |
1599 | 48 | appendGenericSignature(sig); |
1600 | 48 | appendOperator("XX"); |
1601 | 148 | } else { |
1602 | 148 | appendOperator("Xx"); |
1603 | 148 | } |
1604 | | |
1605 | 196 | return; |
1606 | 487k | } |
1607 | 0 | case TypeKind::SILMoveOnlyWrapped: |
1608 | | // If we hit this, we just mangle the underlying name and move on. |
1609 | 0 | llvm_unreachable("should never be mangled?"); |
1610 | 0 | case TypeKind::SILBlockStorage: |
1611 | 0 | llvm_unreachable("should never be mangled"); |
1612 | 15.2M | } |
1613 | 0 | llvm_unreachable("bad type kind"); |
1614 | 0 | } |
1615 | | |
1616 | | GenericTypeParamType *ASTMangler::appendAssocType(DependentMemberType *DepTy, |
1617 | | GenericSignature sig, |
1618 | 567k | bool &isAssocTypeAtDepth) { |
1619 | 567k | auto base = DepTy->getBase()->getCanonicalType(); |
1620 | | // 't_0_0.Member' |
1621 | 567k | if (auto gpBase = dyn_cast<GenericTypeParamType>(base)) { |
1622 | 557k | appendAssociatedTypeName(DepTy, sig); |
1623 | 557k | isAssocTypeAtDepth = false; |
1624 | 557k | return gpBase; |
1625 | 557k | } |
1626 | | |
1627 | | // 't_0_0.Member.Member...' |
1628 | 9.78k | SmallVector<DependentMemberType*, 2> path; |
1629 | 9.78k | path.push_back(DepTy); |
1630 | 20.0k | while (auto dmBase = dyn_cast<DependentMemberType>(base)) { |
1631 | 10.2k | path.push_back(dmBase); |
1632 | 10.2k | base = dmBase.getBase(); |
1633 | 10.2k | } |
1634 | 9.78k | if (auto gpRoot = dyn_cast<GenericTypeParamType>(base)) { |
1635 | 9.78k | bool first = true; |
1636 | 20.0k | for (auto *member : llvm::reverse(path)) { |
1637 | 20.0k | appendAssociatedTypeName(member, sig); |
1638 | 20.0k | appendListSeparator(first); |
1639 | 20.0k | } |
1640 | 9.78k | isAssocTypeAtDepth = true; |
1641 | 9.78k | return gpRoot; |
1642 | 9.78k | } |
1643 | 0 | return nullptr; |
1644 | 9.78k | } |
1645 | | |
1646 | | void ASTMangler::appendOpWithGenericParamIndex( |
1647 | | StringRef Op, const GenericTypeParamType *paramTy, |
1648 | 1.50M | bool baseIsProtocolSelf) { |
1649 | 1.50M | llvm::SmallVector<char, 8> OpBuf(Op.begin(), Op.end()); |
1650 | 1.50M | if (paramTy->getDepth() > 0) { |
1651 | 453k | OpBuf.push_back('d'); |
1652 | 453k | return appendOperator(StringRef(OpBuf.data(), OpBuf.size()), |
1653 | 453k | Index(paramTy->getDepth() - 1), |
1654 | 453k | Index(paramTy->getIndex())); |
1655 | 453k | } |
1656 | 1.05M | if (paramTy->getIndex() == 0) { |
1657 | 581k | if (baseIsProtocolSelf) { |
1658 | 1.56k | OpBuf.push_back('s'); |
1659 | 579k | } else { |
1660 | 579k | OpBuf.push_back('z'); |
1661 | 579k | } |
1662 | 581k | return appendOperator(StringRef(OpBuf.data(), OpBuf.size())); |
1663 | 581k | } |
1664 | 471k | appendOperator(Op, Index(paramTy->getIndex() - 1)); |
1665 | 471k | } |
1666 | | |
1667 | | void ASTMangler::appendFlatGenericArgs(SubstitutionMap subs, |
1668 | | GenericSignature sig, |
1669 | 10.2k | const ValueDecl *forDecl) { |
1670 | 10.2k | appendOperator("y"); |
1671 | | |
1672 | 21.6k | for (auto replacement : subs.getReplacementTypes()) { |
1673 | 21.6k | if (replacement->hasArchetype()) |
1674 | 0 | replacement = replacement->mapTypeOutOfContext(); |
1675 | 21.6k | appendType(replacement, sig, forDecl); |
1676 | 21.6k | } |
1677 | 10.2k | } |
1678 | | |
1679 | | unsigned ASTMangler::appendBoundGenericArgs(DeclContext *dc, |
1680 | | GenericSignature sig, |
1681 | | SubstitutionMap subs, |
1682 | | bool &isFirstArgList, |
1683 | 4.91k | const ValueDecl *forDecl) { |
1684 | 4.91k | auto decl = dc->getInnermostDeclarationDeclContext(); |
1685 | 4.91k | if (!decl) return 0; |
1686 | | |
1687 | | // For a non-protocol extension declaration, use the nominal type declaration |
1688 | | // instead. |
1689 | | // |
1690 | | // This is important when extending a nested type, because the generic |
1691 | | // parameters will line up with the (semantic) nesting of the nominal type. |
1692 | 3.00k | if (auto ext = dyn_cast<ExtensionDecl>(decl)) |
1693 | 183 | decl = ext->getSelfNominalTypeDecl(); |
1694 | | |
1695 | | // Handle the generic arguments of the parent. |
1696 | 3.00k | unsigned currentGenericParamIdx = |
1697 | 3.00k | appendBoundGenericArgs(decl->getDeclContext(), sig, subs, isFirstArgList, |
1698 | 3.00k | forDecl); |
1699 | | |
1700 | | // If this is potentially a generic context, emit a generic argument list. |
1701 | 3.00k | if (auto genericContext = decl->getAsGenericContext()) { |
1702 | 3.00k | if (isFirstArgList) { |
1703 | 1.90k | appendOperator("y"); |
1704 | 1.90k | isFirstArgList = false; |
1705 | 1.90k | } else { |
1706 | 1.10k | appendOperator("_"); |
1707 | 1.10k | } |
1708 | | |
1709 | | // If we are generic at this level, emit all of the replacements at |
1710 | | // this level. |
1711 | 3.00k | bool treatAsGeneric; |
1712 | 3.00k | if (auto opaque = dyn_cast<OpaqueTypeDecl>(decl)) { |
1713 | | // For opaque type declarations, the generic parameters of the opaque |
1714 | | // type declaration are not part of the mangling, so check whether the |
1715 | | // naming declaration has generic parameters. |
1716 | 1.66k | auto namedGenericContext = opaque->getNamingDecl()->getAsGenericContext(); |
1717 | 1.66k | treatAsGeneric = namedGenericContext && namedGenericContext->isGeneric(); |
1718 | 1.66k | } else { |
1719 | 1.34k | treatAsGeneric = genericContext->isGeneric(); |
1720 | 1.34k | } |
1721 | 3.00k | if (treatAsGeneric) { |
1722 | 621 | auto genericParams = subs.getGenericSignature().getGenericParams(); |
1723 | 621 | unsigned depth = genericParams[currentGenericParamIdx]->getDepth(); |
1724 | 621 | auto replacements = subs.getReplacementTypes(); |
1725 | 621 | for (unsigned lastGenericParamIdx = genericParams.size(); |
1726 | 1.59k | (currentGenericParamIdx != lastGenericParamIdx && |
1727 | 1.59k | genericParams[currentGenericParamIdx]->getDepth() == depth); |
1728 | 972 | ++currentGenericParamIdx) { |
1729 | 972 | Type replacementType = replacements[currentGenericParamIdx]; |
1730 | 972 | if (replacementType->hasArchetype()) |
1731 | 0 | replacementType = replacementType->mapTypeOutOfContext(); |
1732 | | |
1733 | 972 | appendType(replacementType, sig, forDecl); |
1734 | 972 | } |
1735 | 621 | } |
1736 | 3.00k | } |
1737 | | |
1738 | 3.00k | return currentGenericParamIdx; |
1739 | 4.91k | } |
1740 | | |
1741 | | void ASTMangler::appendBoundGenericArgs(Type type, GenericSignature sig, |
1742 | | bool &isFirstArgList, |
1743 | 2.91M | const ValueDecl *forDecl) { |
1744 | 2.91M | TypeBase *typePtr = type.getPointer(); |
1745 | 2.91M | ArrayRef<Type> genericArgs; |
1746 | 2.91M | if (auto *typeAlias = dyn_cast<TypeAliasType>(typePtr)) { |
1747 | 237 | appendBoundGenericArgs(typeAlias->getDecl(), sig, |
1748 | 237 | typeAlias->getSubstitutionMap(), |
1749 | 237 | isFirstArgList, forDecl); |
1750 | 237 | return; |
1751 | 237 | } |
1752 | | |
1753 | 2.91M | if (auto *unboundType = dyn_cast<UnboundGenericType>(typePtr)) { |
1754 | 0 | if (Type parent = unboundType->getParent()) |
1755 | 0 | appendBoundGenericArgs(parent->getDesugaredType(), sig, isFirstArgList, |
1756 | 0 | forDecl); |
1757 | 2.91M | } else if (auto *nominalType = dyn_cast<NominalType>(typePtr)) { |
1758 | 159k | if (Type parent = nominalType->getParent()) |
1759 | 104k | appendBoundGenericArgs(parent->getDesugaredType(), sig, isFirstArgList, |
1760 | 104k | forDecl); |
1761 | 2.76M | } else { |
1762 | 2.76M | auto boundType = cast<BoundGenericType>(typePtr); |
1763 | 2.76M | genericArgs = boundType->getGenericArgs(); |
1764 | 2.76M | if (Type parent = boundType->getParent()) { |
1765 | 59.5k | GenericTypeDecl *decl = boundType->getAnyGeneric(); |
1766 | 59.5k | if (!getSpecialManglingContext(decl, UseObjCRuntimeNames)) |
1767 | 59.5k | appendBoundGenericArgs(parent->getDesugaredType(), sig, isFirstArgList, |
1768 | 59.5k | forDecl); |
1769 | 59.5k | } |
1770 | 2.76M | } |
1771 | 2.91M | if (isFirstArgList) { |
1772 | 2.75M | appendOperator("y"); |
1773 | 2.75M | isFirstArgList = false; |
1774 | 2.75M | } else { |
1775 | 163k | appendOperator("_"); |
1776 | 163k | } |
1777 | 2.92M | for (Type arg : genericArgs) { |
1778 | 2.92M | appendType(arg, sig, forDecl); |
1779 | 2.92M | } |
1780 | 2.91M | } |
1781 | | |
1782 | 1.77k | static bool conformanceHasIdentity(const RootProtocolConformance *root) { |
1783 | 1.77k | auto conformance = dyn_cast<NormalProtocolConformance>(root); |
1784 | 1.77k | if (!conformance) { |
1785 | 3 | assert(isa<SelfProtocolConformance>(root) || |
1786 | 3 | isa<BuiltinProtocolConformance>(root)); |
1787 | 0 | return true; |
1788 | 3 | } |
1789 | | |
1790 | | // Synthesized non-unique conformances all get collapsed together at run time. |
1791 | 1.77k | if (conformance->isSynthesizedNonUnique()) |
1792 | 375 | return false; |
1793 | | |
1794 | | // Objective-C protocol conformances are checked by the ObjC runtime. |
1795 | 1.39k | if (conformance->getProtocol()->isObjC()) |
1796 | 0 | return false; |
1797 | | |
1798 | 1.39k | return true; |
1799 | 1.39k | } |
1800 | | |
1801 | | /// Determine whether the given protocol conformance is itself retroactive, |
1802 | | /// meaning that there might be multiple conflicting conformances of the |
1803 | | /// same type to the same protocol. |
1804 | 593k | static bool isRetroactiveConformance(const RootProtocolConformance *root) { |
1805 | 593k | auto conformance = dyn_cast<NormalProtocolConformance>(root); |
1806 | 593k | if (!conformance) { |
1807 | 8.22k | assert(isa<SelfProtocolConformance>(root) || |
1808 | 8.22k | isa<BuiltinProtocolConformance>(root)); |
1809 | 0 | return false; // self-conformances are never retroactive. nor are builtin. |
1810 | 8.22k | } |
1811 | | |
1812 | | // Don't consider marker protocols at all. |
1813 | 585k | if (conformance->getProtocol()->isMarkerProtocol()) |
1814 | 0 | return false; |
1815 | | |
1816 | 585k | return conformance->isRetroactive(); |
1817 | 585k | } |
1818 | | |
1819 | | /// Determine whether the given protocol conformance contains a retroactive |
1820 | | /// protocol conformance anywhere in it. |
1821 | | static bool containsRetroactiveConformance( |
1822 | | const ProtocolConformance *conformance, |
1823 | 592k | ModuleDecl *module) { |
1824 | | // If the root conformance is retroactive, it's retroactive. |
1825 | 592k | const RootProtocolConformance *rootConformance = |
1826 | 592k | conformance->getRootConformance(); |
1827 | 592k | if (isRetroactiveConformance(rootConformance) && |
1828 | 592k | conformanceHasIdentity(rootConformance)) |
1829 | 303 | return true; |
1830 | | |
1831 | | // If the conformance is conditional and any of the substitutions used to |
1832 | | // satisfy the conditions are retroactive, it's retroactive. |
1833 | 592k | auto subMap = conformance->getSubstitutionMap(); |
1834 | 592k | for (auto requirement : rootConformance->getConditionalRequirements()) { |
1835 | 14.5k | if (requirement.getKind() != RequirementKind::Conformance) |
1836 | 3.92k | continue; |
1837 | 10.6k | ProtocolDecl *proto = requirement.getProtocolDecl(); |
1838 | 10.6k | auto conformance = subMap.lookupConformance( |
1839 | 10.6k | requirement.getFirstType()->getCanonicalType(), proto); |
1840 | 10.6k | if (conformance.isInvalid()) { |
1841 | | // This should only happen when mangling invalid ASTs, but that happens |
1842 | | // for indexing purposes. |
1843 | 0 | continue; |
1844 | 0 | } |
1845 | 10.6k | if (conformance.isConcrete() && |
1846 | 10.6k | containsRetroactiveConformance(conformance.getConcrete(), module)) { |
1847 | 15 | return true; |
1848 | 15 | } |
1849 | 10.6k | } |
1850 | | |
1851 | 592k | return false; |
1852 | 592k | } |
1853 | | |
1854 | | void ASTMangler::appendRetroactiveConformances(SubstitutionMap subMap, |
1855 | | GenericSignature sig, |
1856 | 2.76M | ModuleDecl *fromModule) { |
1857 | 2.76M | if (subMap.empty()) return; |
1858 | | |
1859 | 2.76M | unsigned numProtocolRequirements = 0; |
1860 | 2.76M | for (auto conformance : subMap.getConformances()) { |
1861 | 928k | if (conformance.isInvalid()) |
1862 | 36 | continue; |
1863 | | |
1864 | 928k | if (conformance.getRequirement()->isMarkerProtocol()) |
1865 | 34.1k | continue; |
1866 | | |
1867 | 894k | SWIFT_DEFER { |
1868 | 894k | ++numProtocolRequirements; |
1869 | 894k | }; |
1870 | | |
1871 | | // Ignore abstract conformances. |
1872 | 894k | if (!conformance.isConcrete()) |
1873 | 311k | continue; |
1874 | | |
1875 | | // Skip non-retroactive conformances. |
1876 | 582k | if (!containsRetroactiveConformance(conformance.getConcrete(), fromModule)) |
1877 | 582k | continue; |
1878 | | |
1879 | 303 | appendConcreteProtocolConformance(conformance.getConcrete(), sig); |
1880 | 303 | appendOperator("g", Index(numProtocolRequirements)); |
1881 | 303 | } |
1882 | 2.76M | } |
1883 | | |
1884 | 2.75M | void ASTMangler::appendRetroactiveConformances(Type type, GenericSignature sig) { |
1885 | | // Dig out the substitution map to use. |
1886 | 2.75M | SubstitutionMap subMap; |
1887 | 2.75M | ModuleDecl *module; |
1888 | 2.75M | if (auto typeAlias = dyn_cast<TypeAliasType>(type.getPointer())) { |
1889 | 237 | module = Mod ? Mod : typeAlias->getDecl()->getModuleContext(); |
1890 | 237 | subMap = typeAlias->getSubstitutionMap(); |
1891 | 2.75M | } else { |
1892 | 2.75M | if (type->hasUnboundGenericType()) |
1893 | 9 | return; |
1894 | | |
1895 | 2.75M | auto nominal = type->getAnyNominal(); |
1896 | 2.75M | if (!nominal) return; |
1897 | | |
1898 | 2.75M | module = Mod ? Mod : nominal->getModuleContext(); |
1899 | 2.75M | subMap = type->getContextSubstitutionMap(module, nominal); |
1900 | 2.75M | } |
1901 | | |
1902 | 2.75M | appendRetroactiveConformances(subMap, sig, module); |
1903 | 2.75M | } |
1904 | | |
1905 | | void ASTMangler::appendSymbolicExtendedExistentialType( |
1906 | | SymbolicReferent shapeReferent, |
1907 | | Type type, |
1908 | | GenericSignature sig, |
1909 | 81 | const ValueDecl *forDecl) { |
1910 | 81 | assert(shapeReferent.getKind() == |
1911 | 81 | SymbolicReferent::ExtendedExistentialTypeShape); |
1912 | 0 | assert(canSymbolicReference(shapeReferent)); |
1913 | 0 | assert(type->isAnyExistentialType()); |
1914 | | |
1915 | | // type ::= symbolic-extended-existential-type-shape |
1916 | | // type* retroactive-conformance* 'Xj' |
1917 | | |
1918 | 0 | appendSymbolicReference(shapeReferent); |
1919 | | |
1920 | 81 | auto genInfo = ExistentialTypeGeneralization::get(type); |
1921 | 81 | if (genInfo.Generalization) { |
1922 | 81 | for (auto argType : genInfo.Generalization.getReplacementTypes()) |
1923 | 108 | appendType(argType, sig, forDecl); |
1924 | | |
1925 | | // What module should be used here? The existential isn't anchored |
1926 | | // to any given module; we should just treat conformances as |
1927 | | // retroactive if they're "objectively" retroactive. |
1928 | 81 | appendRetroactiveConformances(genInfo.Generalization, sig, |
1929 | 81 | /*from module*/ nullptr); |
1930 | 81 | } |
1931 | | |
1932 | 81 | appendOperator("Xj"); |
1933 | 81 | } |
1934 | | |
1935 | | static llvm::Optional<char> |
1936 | 132k | getParamDifferentiability(SILParameterDifferentiability diffKind) { |
1937 | 132k | switch (diffKind) { |
1938 | 131k | case swift::SILParameterDifferentiability::DifferentiableOrNotApplicable: |
1939 | 131k | return llvm::None; |
1940 | 112 | case swift::SILParameterDifferentiability::NotDifferentiable: |
1941 | 112 | return 'w'; |
1942 | 132k | } |
1943 | 0 | llvm_unreachable("bad parameter differentiability"); |
1944 | 0 | } |
1945 | | |
1946 | 119k | static char getResultConvention(ResultConvention conv) { |
1947 | 119k | switch (conv) { |
1948 | 40.1k | case ResultConvention::Indirect: return 'r'; |
1949 | 30.5k | case ResultConvention::Owned: return 'o'; |
1950 | 48.6k | case ResultConvention::Unowned: return 'd'; |
1951 | 0 | case ResultConvention::UnownedInnerPointer: return 'u'; |
1952 | 198 | case ResultConvention::Autoreleased: return 'a'; |
1953 | 45 | case ResultConvention::Pack: return 'k'; |
1954 | 119k | } |
1955 | 0 | llvm_unreachable("bad result convention"); |
1956 | 0 | } |
1957 | | |
1958 | | static llvm::Optional<char> |
1959 | 117k | getResultDifferentiability(SILResultDifferentiability diffKind) { |
1960 | 117k | switch (diffKind) { |
1961 | 117k | case swift::SILResultDifferentiability::DifferentiableOrNotApplicable: |
1962 | 117k | return llvm::None; |
1963 | 0 | case swift::SILResultDifferentiability::NotDifferentiable: |
1964 | 0 | return 'w'; |
1965 | 117k | } |
1966 | 0 | llvm_unreachable("bad result differentiability"); |
1967 | 0 | } |
1968 | | |
1969 | | void ASTMangler::appendImplFunctionType(SILFunctionType *fn, |
1970 | | GenericSignature outerGenericSig, |
1971 | 110k | const ValueDecl *forDecl) { |
1972 | | |
1973 | 110k | llvm::SmallVector<char, 32> OpArgs; |
1974 | | |
1975 | 110k | if (fn->getPatternSubstitutions()) { |
1976 | 10.2k | OpArgs.push_back('s'); |
1977 | 10.2k | } |
1978 | 110k | if (fn->getInvocationSubstitutions()) { |
1979 | 0 | OpArgs.push_back('I'); |
1980 | 0 | } |
1981 | | |
1982 | 110k | if (fn->isPolymorphic() && fn->isPseudogeneric()) |
1983 | 0 | OpArgs.push_back('P'); |
1984 | | |
1985 | 110k | if (!fn->isNoEscape()) |
1986 | 91.9k | OpArgs.push_back('e'); |
1987 | | |
1988 | | // Differentiability kind. |
1989 | 110k | auto diffKind = fn->getExtInfo().getDifferentiabilityKind(); |
1990 | 110k | if (diffKind != DifferentiabilityKind::NonDifferentiable) { |
1991 | 605 | OpArgs.push_back((char)getMangledDifferentiabilityKind(diffKind)); |
1992 | 605 | } |
1993 | | |
1994 | | // <impl-callee-convention> |
1995 | 110k | if (fn->getExtInfo().hasContext()) { |
1996 | 95.1k | OpArgs.push_back(getParamConvention(fn->getCalleeConvention())); |
1997 | 95.1k | } else { |
1998 | 15.7k | OpArgs.push_back('t'); |
1999 | 15.7k | } |
2000 | | |
2001 | 110k | bool mangleClangType = fn->getASTContext().LangOpts.UseClangFunctionTypes && |
2002 | 110k | fn->hasNonDerivableClangType(); |
2003 | | |
2004 | 110k | auto appendClangTypeToVec = [this, fn](auto &Vec) { |
2005 | 0 | llvm::raw_svector_ostream OpArgsOS(Vec); |
2006 | 0 | appendClangType(fn, OpArgsOS); |
2007 | 0 | }; |
2008 | | |
2009 | 110k | switch (fn->getRepresentation()) { |
2010 | 93.3k | case SILFunctionTypeRepresentation::Thick: |
2011 | 94.7k | case SILFunctionTypeRepresentation::Thin: |
2012 | 94.7k | break; |
2013 | 1.80k | case SILFunctionTypeRepresentation::Block: |
2014 | 1.80k | if (!mangleClangType) { |
2015 | 1.80k | OpArgs.push_back('B'); |
2016 | 1.80k | break; |
2017 | 1.80k | } |
2018 | 0 | OpArgs.push_back('z'); |
2019 | 0 | OpArgs.push_back('B'); |
2020 | 0 | appendClangTypeToVec(OpArgs); |
2021 | 0 | break; |
2022 | 0 | case SILFunctionTypeRepresentation::CXXMethod: |
2023 | 90 | case SILFunctionTypeRepresentation::CFunctionPointer: |
2024 | 90 | if (!mangleClangType) { |
2025 | 90 | OpArgs.push_back('C'); |
2026 | 90 | break; |
2027 | 90 | } |
2028 | 0 | OpArgs.push_back('z'); |
2029 | 0 | OpArgs.push_back('C'); |
2030 | 0 | appendClangTypeToVec(OpArgs); |
2031 | 0 | break; |
2032 | 0 | case SILFunctionTypeRepresentation::ObjCMethod: |
2033 | 0 | OpArgs.push_back('O'); |
2034 | 0 | break; |
2035 | 12.1k | case SILFunctionTypeRepresentation::Method: |
2036 | 12.1k | OpArgs.push_back('M'); |
2037 | 12.1k | break; |
2038 | 0 | case SILFunctionTypeRepresentation::Closure: |
2039 | 0 | OpArgs.push_back('K'); |
2040 | 0 | break; |
2041 | 2.22k | case SILFunctionTypeRepresentation::WitnessMethod: |
2042 | 2.22k | OpArgs.push_back('W'); |
2043 | 2.22k | break; |
2044 | 0 | case SILFunctionTypeRepresentation::KeyPathAccessorGetter: |
2045 | 0 | case SILFunctionTypeRepresentation::KeyPathAccessorSetter: |
2046 | 0 | case SILFunctionTypeRepresentation::KeyPathAccessorEquals: |
2047 | 0 | case SILFunctionTypeRepresentation::KeyPathAccessorHash: |
2048 | | // KeyPath accessors are mangled separately based on their index types |
2049 | | // by mangleKeyPathGetterThunkHelper, and so on. |
2050 | 0 | llvm_unreachable("key path accessors should not mangle its function type"); |
2051 | 110k | } |
2052 | | |
2053 | | // Coroutine kind. This is mangled in all pointer auth modes. |
2054 | 110k | switch (fn->getCoroutineKind()) { |
2055 | 98.0k | case SILCoroutineKind::None: |
2056 | 98.0k | break; |
2057 | 12.9k | case SILCoroutineKind::YieldOnce: |
2058 | 12.9k | OpArgs.push_back('A'); |
2059 | 12.9k | break; |
2060 | 0 | case SILCoroutineKind::YieldMany: |
2061 | 0 | OpArgs.push_back('G'); |
2062 | 0 | break; |
2063 | 110k | } |
2064 | | |
2065 | | // Concurrent functions. |
2066 | 110k | if (fn->isSendable()) { |
2067 | 1.94k | OpArgs.push_back('h'); |
2068 | 1.94k | } |
2069 | | |
2070 | | // Asynchronous functions. |
2071 | 110k | if (fn->isAsync()) { |
2072 | 4.02k | OpArgs.push_back('H'); |
2073 | 4.02k | } |
2074 | | |
2075 | 110k | GenericSignature sig = fn->getSubstGenericSignature(); |
2076 | | |
2077 | | // Mangle the parameters. |
2078 | 132k | for (auto param : fn->getParameters()) { |
2079 | 132k | OpArgs.push_back(getParamConvention(param.getConvention())); |
2080 | 132k | if (auto diffKind = getParamDifferentiability(param.getDifferentiability())) |
2081 | 112 | OpArgs.push_back(*diffKind); |
2082 | 132k | appendType(param.getInterfaceType(), sig, forDecl); |
2083 | 132k | } |
2084 | | |
2085 | | // Mangle the results. |
2086 | 117k | for (auto result : fn->getResults()) { |
2087 | 117k | OpArgs.push_back(getResultConvention(result.getConvention())); |
2088 | 117k | if (auto diffKind = |
2089 | 117k | getResultDifferentiability(result.getDifferentiability())) |
2090 | 0 | OpArgs.push_back(*diffKind); |
2091 | 117k | appendType(result.getInterfaceType(), sig, forDecl); |
2092 | 117k | } |
2093 | | |
2094 | | // Mangle the yields. |
2095 | 110k | for (auto yield : fn->getYields()) { |
2096 | 12.8k | OpArgs.push_back('Y'); |
2097 | 12.8k | OpArgs.push_back(getParamConvention(yield.getConvention())); |
2098 | 12.8k | appendType(yield.getInterfaceType(), sig, forDecl); |
2099 | 12.8k | } |
2100 | | |
2101 | | // Mangle the error result if present. |
2102 | 110k | if (fn->hasErrorResult()) { |
2103 | 2.23k | auto error = fn->getErrorResult(); |
2104 | 2.23k | OpArgs.push_back('z'); |
2105 | 2.23k | OpArgs.push_back(getResultConvention(error.getConvention())); |
2106 | 2.23k | appendType(error.getInterfaceType(), sig, forDecl); |
2107 | 2.23k | } |
2108 | | |
2109 | 110k | if (auto invocationSig = fn->getInvocationGenericSignature()) { |
2110 | 2.68k | appendGenericSignature(invocationSig); |
2111 | 2.68k | sig = outerGenericSig; |
2112 | 2.68k | } |
2113 | 110k | if (auto subs = fn->getInvocationSubstitutions()) { |
2114 | 0 | appendFlatGenericArgs(subs, sig, forDecl); |
2115 | 0 | appendRetroactiveConformances(subs, sig, Mod); |
2116 | 0 | } |
2117 | 110k | if (auto subs = fn->getPatternSubstitutions()) { |
2118 | 10.2k | appendGenericSignature(subs.getGenericSignature()); |
2119 | 10.2k | sig = |
2120 | 10.2k | fn->getInvocationGenericSignature() |
2121 | 10.2k | ? fn->getInvocationGenericSignature() |
2122 | 10.2k | : outerGenericSig; |
2123 | 10.2k | appendFlatGenericArgs(subs, sig, forDecl); |
2124 | 10.2k | appendRetroactiveConformances(subs, sig, Mod); |
2125 | 10.2k | } |
2126 | | |
2127 | 110k | OpArgs.push_back('_'); |
2128 | | |
2129 | 110k | appendOperator("I", StringRef(OpArgs.data(), OpArgs.size())); |
2130 | 110k | } |
2131 | | |
2132 | | void ASTMangler::appendOpaqueTypeArchetype(ArchetypeType *archetype, |
2133 | | OpaqueTypeDecl *opaqueDecl, |
2134 | | SubstitutionMap subs, |
2135 | | GenericSignature sig, |
2136 | 14.8k | const ValueDecl *forDecl) { |
2137 | 14.8k | Type interfaceType = archetype->getInterfaceType(); |
2138 | 14.8k | auto genericParam = interfaceType->getAs<GenericTypeParamType>(); |
2139 | | |
2140 | | // If this is the opaque return type of the declaration currently being |
2141 | | // mangled, use a short mangling to represent it. |
2142 | 14.8k | if (genericParam && opaqueDecl->getNamingDecl() == forDecl) { |
2143 | 12.8k | assert(subs.isIdentity()); |
2144 | 12.8k | if (genericParam->getIndex() == 0) |
2145 | 12.4k | return appendOperator("Qr"); |
2146 | | |
2147 | 432 | return appendOperator("QR", Index(genericParam->getIndex() - 1)); |
2148 | 12.8k | } |
2149 | | |
2150 | | // Otherwise, try to substitute it. |
2151 | 1.96k | if (tryMangleTypeSubstitution(Type(archetype), sig)) |
2152 | 105 | return; |
2153 | | |
2154 | | // Mangling at the root, described by a generic parameter. |
2155 | 1.86k | if (genericParam) { |
2156 | | // Use the fully elaborated explicit mangling. |
2157 | 1.66k | appendOpaqueDeclName(opaqueDecl); |
2158 | 1.66k | bool isFirstArgList = true; |
2159 | 1.66k | appendBoundGenericArgs(opaqueDecl, sig, subs, isFirstArgList, forDecl); |
2160 | 1.66k | appendRetroactiveConformances(subs, sig, opaqueDecl->getParentModule()); |
2161 | | |
2162 | 1.66k | appendOperator("Qo", Index(genericParam->getIndex())); |
2163 | 1.66k | } else { |
2164 | | // Mangle associated types of opaque archetypes like dependent member |
2165 | | // types, so that they can be accurately demangled at runtime. |
2166 | 195 | appendType(Type(archetype->getRoot()), sig, forDecl); |
2167 | 195 | bool isAssocTypeAtDepth = false; |
2168 | 195 | appendAssocType( |
2169 | 195 | archetype->getInterfaceType()->castTo<DependentMemberType>(), |
2170 | 195 | sig, isAssocTypeAtDepth); |
2171 | 195 | appendOperator(isAssocTypeAtDepth ? "QX" : "Qx"); |
2172 | 195 | } |
2173 | | |
2174 | 1.86k | addTypeSubstitution(Type(archetype), sig); |
2175 | 1.86k | } |
2176 | | |
2177 | | llvm::Optional<ASTMangler::SpecialContext> |
2178 | | ASTMangler::getSpecialManglingContext(const ValueDecl *decl, |
2179 | 14.5M | bool useObjCProtocolNames) { |
2180 | | // Declarations provided by a C module have a special context mangling. |
2181 | | // known-context ::= 'So' |
2182 | | // |
2183 | | // Also handle top-level imported declarations that don't have corresponding |
2184 | | // Clang decls. Check getKind() directly to avoid a layering dependency. |
2185 | | // known-context ::= 'SC' |
2186 | 14.5M | if (auto file = dyn_cast<FileUnit>(decl->getDeclContext())) { |
2187 | 9.61M | if (file->getKind() == FileUnitKind::ClangModule || |
2188 | 9.61M | file->getKind() == FileUnitKind::DWARFModule) { |
2189 | 364k | if (decl->getClangDecl()) |
2190 | 359k | return ASTMangler::ObjCContext; |
2191 | 4.77k | return ASTMangler::ClangImporterContext; |
2192 | 364k | } |
2193 | 9.61M | } |
2194 | | |
2195 | | // If @objc Swift protocols should be mangled as Objective-C protocols, |
2196 | | // they are defined in the Objective-C context. |
2197 | 14.2M | if (getOverriddenSwiftProtocolObjCName(decl, useObjCProtocolNames)) |
2198 | 12 | return ASTMangler::ObjCContext; |
2199 | | |
2200 | | // Nested types imported from C should also get use the special "So" context. |
2201 | 14.2M | if (isa<TypeDecl>(decl)) { |
2202 | 10.3M | if (auto *clangDecl = cast_or_null<clang::NamedDecl>(decl->getClangDecl())){ |
2203 | 85.2k | bool hasNameForLinkage; |
2204 | 85.2k | if (auto *tagDecl = dyn_cast<clang::TagDecl>(clangDecl)) |
2205 | | // Clang does not always populate the fields that determine if a tag |
2206 | | // decl has a linkage name. This is particularly the case for the |
2207 | | // C++ definition of CF_OPTIONS in the sdk. However, we use the |
2208 | | // name of the backing typedef as a linkage name, despite |
2209 | | // the enum itself not having one. |
2210 | 67.9k | hasNameForLinkage = |
2211 | 67.9k | tagDecl->hasNameForLinkage() || isCXXCFOptionsDefinition(decl); |
2212 | 17.3k | else |
2213 | 17.3k | hasNameForLinkage = !clangDecl->getDeclName().isEmpty(); |
2214 | 85.2k | if (hasNameForLinkage) { |
2215 | 83.7k | auto *clangDC = clangDecl->getDeclContext(); |
2216 | | // In C, "nested" structs, unions, enums, etc. will become siblings: |
2217 | | // struct Foo { struct Bar { }; }; -> struct Foo { }; struct Bar { }; |
2218 | | // Whereas in C++, nested records will actually be nested. So if this is |
2219 | | // a C++ record, simply treat it like a namespace and exit early. |
2220 | 83.7k | if (isa<clang::NamespaceDecl>(clangDC) || |
2221 | 83.7k | isa<clang::CXXRecordDecl>(clangDC)) |
2222 | 22.7k | return llvm::None; |
2223 | 60.9k | assert(clangDC->getRedeclContext()->isTranslationUnit() && |
2224 | 60.9k | "non-top-level Clang types not supported yet"); |
2225 | 0 | return ASTMangler::ObjCContext; |
2226 | 83.7k | } |
2227 | 85.2k | } |
2228 | | |
2229 | | // Types apparently defined in the Builtin module are actually |
2230 | | // synthetic declarations for types defined in the runtime, |
2231 | | // and they should be mangled as C-namespace entities; see e.g. |
2232 | | // IRGenModule::getObjCRuntimeBaseClass. |
2233 | 10.3M | if (decl->getModuleContext()->isBuiltinModule()) |
2234 | 51 | return ASTMangler::ObjCContext; |
2235 | 10.3M | } |
2236 | | |
2237 | | // Importer-synthesized types should always be mangled in the |
2238 | | // ClangImporterContext, even if an __attribute__((swift_name())) nests them |
2239 | | // inside a Swift type syntactically. |
2240 | 14.1M | if (decl->getAttrs().hasAttribute<ClangImporterSynthesizedTypeAttr>()) |
2241 | 156 | return ASTMangler::ClangImporterContext; |
2242 | | |
2243 | 14.1M | return llvm::None; |
2244 | 14.1M | } |
2245 | | |
2246 | | /// Mangle the context of the given declaration as a <context. |
2247 | | /// This is the top-level entrypoint for mangling <context>. |
2248 | 14.4M | void ASTMangler::appendContextOf(const ValueDecl *decl) { |
2249 | | // Check for a special mangling context. |
2250 | 14.4M | if (auto context = getSpecialManglingContext(decl, UseObjCRuntimeNames)) { |
2251 | 423k | switch (*context) { |
2252 | 4.84k | case ClangImporterContext: |
2253 | 4.84k | return appendOperator("SC"); |
2254 | 419k | case ObjCContext: |
2255 | 419k | return appendOperator("So"); |
2256 | 423k | } |
2257 | 423k | } |
2258 | | |
2259 | | // Just mangle the decl's DC. |
2260 | 14.0M | appendContext(decl->getDeclContext(), decl->getAlternateModuleName()); |
2261 | 14.0M | } |
2262 | | |
2263 | | namespace { |
2264 | | class FindFirstVariable : |
2265 | | public PatternVisitor<FindFirstVariable, VarDecl *> { |
2266 | | public: |
2267 | 1.01k | VarDecl *visitNamedPattern(NamedPattern *P) { |
2268 | 1.01k | return P->getDecl(); |
2269 | 1.01k | } |
2270 | | |
2271 | 0 | VarDecl *visitTuplePattern(TuplePattern *P) { |
2272 | 0 | for (auto &elt : P->getElements()) { |
2273 | 0 | VarDecl *var = visit(elt.getPattern()); |
2274 | 0 | if (var) return var; |
2275 | 0 | } |
2276 | 0 | return nullptr; |
2277 | 0 | } |
2278 | | |
2279 | 0 | VarDecl *visitParenPattern(ParenPattern *P) { |
2280 | 0 | return visit(P->getSubPattern()); |
2281 | 0 | } |
2282 | 0 | VarDecl *visitBindingPattern(BindingPattern *P) { |
2283 | 0 | return visit(P->getSubPattern()); |
2284 | 0 | } |
2285 | 568 | VarDecl *visitTypedPattern(TypedPattern *P) { |
2286 | 568 | return visit(P->getSubPattern()); |
2287 | 568 | } |
2288 | 0 | VarDecl *visitAnyPattern(AnyPattern *P) { |
2289 | 0 | return nullptr; |
2290 | 0 | } |
2291 | | |
2292 | | // Refutable patterns shouldn't ever come up. |
2293 | | #define REFUTABLE_PATTERN(ID, BASE) \ |
2294 | 0 | VarDecl *visit##ID##Pattern(ID##Pattern *P) { \ |
2295 | 0 | llvm_unreachable("shouldn't be visiting a refutable pattern here!"); \ |
2296 | 0 | } Unexecuted instantiation: ASTMangler.cpp:_ZN12_GLOBAL__N_117FindFirstVariable14visitIsPatternEPN5swift9IsPatternE Unexecuted instantiation: ASTMangler.cpp:_ZN12_GLOBAL__N_117FindFirstVariable23visitEnumElementPatternEPN5swift18EnumElementPatternE Unexecuted instantiation: ASTMangler.cpp:_ZN12_GLOBAL__N_117FindFirstVariable24visitOptionalSomePatternEPN5swift19OptionalSomePatternE Unexecuted instantiation: ASTMangler.cpp:_ZN12_GLOBAL__N_117FindFirstVariable16visitBoolPatternEPN5swift11BoolPatternE Unexecuted instantiation: ASTMangler.cpp:_ZN12_GLOBAL__N_117FindFirstVariable16visitExprPatternEPN5swift11ExprPatternE |
2297 | | #define PATTERN(ID, BASE) |
2298 | | #include "swift/AST/PatternNodes.def" |
2299 | | }; |
2300 | | } // end anonymous namespace |
2301 | | |
2302 | | /// Find the first identifier bound by the given binding. This |
2303 | | /// assumes that field and global-variable bindings always bind at |
2304 | | /// least one name, which is probably a reasonable assumption but may |
2305 | | /// not be adequately enforced. |
2306 | | static llvm::Optional<VarDecl *> |
2307 | 1.01k | findFirstVariable(PatternBindingDecl *binding) { |
2308 | 1.01k | for (auto idx : range(binding->getNumPatternEntries())) { |
2309 | 1.01k | auto var = FindFirstVariable().visit(binding->getPattern(idx)); |
2310 | 1.01k | if (var) return var; |
2311 | 1.01k | } |
2312 | | // Pattern-binding bound without variables exists in erroneous code, e.g. |
2313 | | // during code completion. |
2314 | 0 | return llvm::None; |
2315 | 1.01k | } |
2316 | | |
2317 | 24.0M | void ASTMangler::appendContext(const DeclContext *ctx, StringRef useModuleName) { |
2318 | 24.0M | switch (ctx->getContextKind()) { |
2319 | 0 | case DeclContextKind::Package: |
2320 | 0 | return; |
2321 | 9.32M | case DeclContextKind::Module: |
2322 | 9.32M | return appendModule(cast<ModuleDecl>(ctx), useModuleName); |
2323 | | |
2324 | 9.30M | case DeclContextKind::FileUnit: |
2325 | 9.30M | assert(!isa<BuiltinUnit>(ctx) && "mangling member of builtin module!"); |
2326 | 0 | appendContext(ctx->getParent(), useModuleName); |
2327 | 9.30M | return; |
2328 | | |
2329 | 1.49k | case DeclContextKind::SerializedLocal: { |
2330 | 1.49k | auto local = cast<SerializedLocalDeclContext>(ctx); |
2331 | 1.49k | switch (local->getLocalDeclContextKind()) { |
2332 | 801 | case LocalDeclContextKind::AbstractClosure: |
2333 | 801 | appendClosureEntity(cast<SerializedAbstractClosureExpr>(local)); |
2334 | 801 | return; |
2335 | 93 | case LocalDeclContextKind::DefaultArgumentInitializer: { |
2336 | 93 | auto argInit = cast<SerializedDefaultArgumentInitializer>(local); |
2337 | 93 | appendDefaultArgumentEntity(ctx->getParent(), argInit->getIndex()); |
2338 | 93 | return; |
2339 | 0 | } |
2340 | 93 | case LocalDeclContextKind::PatternBindingInitializer: { |
2341 | 93 | auto patternInit = cast<SerializedPatternBindingInitializer>(local); |
2342 | 93 | if (auto var = findFirstVariable(patternInit->getBinding())) { |
2343 | 93 | appendInitializerEntity(var.value()); |
2344 | 93 | } else { |
2345 | | // This is incorrect in that it does not produce a /unique/ mangling, |
2346 | | // but it will at least produce a /valid/ mangling. |
2347 | 0 | appendContext(ctx->getParent(), useModuleName); |
2348 | 0 | } |
2349 | 93 | return; |
2350 | 0 | } |
2351 | 504 | case LocalDeclContextKind::TopLevelCodeDecl: |
2352 | 504 | return appendContext(local->getParent(), useModuleName); |
2353 | 1.49k | } |
2354 | 1.49k | } |
2355 | | |
2356 | 3.20M | case DeclContextKind::GenericTypeDecl: |
2357 | 3.20M | appendAnyGenericType(cast<GenericTypeDecl>(ctx)); |
2358 | 3.20M | return; |
2359 | | |
2360 | 1.78M | case DeclContextKind::ExtensionDecl: { |
2361 | 1.78M | auto ExtD = cast<ExtensionDecl>(ctx); |
2362 | 1.78M | auto decl = ExtD->getExtendedNominal(); |
2363 | | // Recover from erroneous extension. |
2364 | 1.78M | if (!decl) |
2365 | 51 | return appendContext(ExtD->getDeclContext(), useModuleName); |
2366 | | |
2367 | 1.78M | if (!ExtD->isEquivalentToExtendedContext()) { |
2368 | | // Mangle the extension if: |
2369 | | // - the extension is defined in a different module from the original |
2370 | | // nominal type decl, |
2371 | | // - the extension is constrained, or |
2372 | | // - the extension is to a protocol. |
2373 | | // FIXME: In a world where protocol extensions are dynamically dispatched, |
2374 | | // "extension is to a protocol" would no longer be a reason to use the |
2375 | | // extension mangling, because an extension method implementation could be |
2376 | | // resiliently moved into the original protocol itself. |
2377 | 674k | auto sig = ExtD->getGenericSignature(); |
2378 | | // If the extension is constrained, mangle the generic signature that |
2379 | | // constrains it. |
2380 | 674k | appendAnyGenericType(decl); |
2381 | 674k | appendModule(ExtD->getParentModule(), useModuleName); |
2382 | 674k | if (sig && ExtD->isConstrainedExtension()) { |
2383 | 263k | Mod = ExtD->getModuleContext(); |
2384 | 263k | auto nominalSig = ExtD->getSelfNominalTypeDecl() |
2385 | 263k | ->getGenericSignatureOfContext(); |
2386 | 263k | appendGenericSignature(sig, nominalSig); |
2387 | 263k | } |
2388 | 674k | return appendOperator("E"); |
2389 | 674k | } |
2390 | 1.10M | return appendAnyGenericType(decl); |
2391 | 1.78M | } |
2392 | | |
2393 | 106k | case DeclContextKind::AbstractClosureExpr: |
2394 | 106k | return appendClosureEntity(cast<AbstractClosureExpr>(ctx)); |
2395 | | |
2396 | 168k | case DeclContextKind::AbstractFunctionDecl: { |
2397 | 168k | auto fn = cast<AbstractFunctionDecl>(ctx); |
2398 | | |
2399 | | // Constructors and destructors as contexts are always mangled |
2400 | | // using the non-(de)allocating variants. |
2401 | 168k | if (auto ctor = dyn_cast<ConstructorDecl>(fn)) { |
2402 | 21.8k | return appendConstructorEntity(ctor, /*allocating*/ false); |
2403 | 21.8k | } |
2404 | | |
2405 | 146k | if (auto dtor = dyn_cast<DestructorDecl>(fn)) |
2406 | 147 | return appendDestructorEntity(dtor, /*deallocating*/ false); |
2407 | | |
2408 | 146k | return appendEntity(fn); |
2409 | 146k | } |
2410 | | |
2411 | 258 | case DeclContextKind::EnumElementDecl: { |
2412 | 258 | auto eed = cast<EnumElementDecl>(ctx); |
2413 | 258 | return appendEntity(eed); |
2414 | 146k | } |
2415 | | |
2416 | 866 | case DeclContextKind::SubscriptDecl: { |
2417 | 866 | auto sd = cast<SubscriptDecl>(ctx); |
2418 | 866 | return appendEntity(sd); |
2419 | 146k | } |
2420 | | |
2421 | 1.59k | case DeclContextKind::Initializer: |
2422 | 1.59k | switch (cast<Initializer>(ctx)->getInitializerKind()) { |
2423 | 670 | case InitializerKind::DefaultArgument: { |
2424 | 670 | auto argInit = cast<DefaultArgumentInitializer>(ctx); |
2425 | 670 | return appendDefaultArgumentEntity(ctx->getParent(), argInit->getIndex()); |
2426 | 0 | } |
2427 | | |
2428 | 922 | case InitializerKind::PatternBinding: { |
2429 | 922 | auto patternInit = cast<PatternBindingInitializer>(ctx); |
2430 | 922 | if (auto var = findFirstVariable(patternInit->getBinding())) { |
2431 | 922 | appendInitializerEntity(var.value()); |
2432 | 922 | } else { |
2433 | | // This is incorrect in that it does not produce a /unique/ mangling, |
2434 | | // but it will at least produce a /valid/ mangling. |
2435 | 0 | appendContext(ctx->getParent(), useModuleName); |
2436 | 0 | } |
2437 | 922 | return; |
2438 | 0 | } |
2439 | | |
2440 | 6 | case InitializerKind::PropertyWrapper: { |
2441 | 6 | auto wrapperInit = cast<PropertyWrapperInitializer>(ctx); |
2442 | 6 | switch (wrapperInit->getKind()) { |
2443 | 6 | case PropertyWrapperInitializer::Kind::WrappedValue: |
2444 | 6 | appendBackingInitializerEntity(wrapperInit->getWrappedVar()); |
2445 | 6 | break; |
2446 | 0 | case PropertyWrapperInitializer::Kind::ProjectedValue: |
2447 | 0 | appendInitFromProjectedValueEntity(wrapperInit->getWrappedVar()); |
2448 | 0 | break; |
2449 | 6 | } |
2450 | 6 | return; |
2451 | 6 | } |
2452 | 1.59k | } |
2453 | 0 | llvm_unreachable("bad initializer kind"); |
2454 | |
|
2455 | 108k | case DeclContextKind::TopLevelCodeDecl: |
2456 | | // Mangle the containing module context. |
2457 | 108k | return appendContext(ctx->getParent(), useModuleName); |
2458 | | |
2459 | 12 | case DeclContextKind::MacroDecl: |
2460 | 12 | return appendContext(ctx->getParent(), useModuleName); |
2461 | 24.0M | } |
2462 | | |
2463 | 0 | llvm_unreachable("bad decl context"); |
2464 | 0 | } |
2465 | | |
2466 | | void ASTMangler::appendModule(const ModuleDecl *module, |
2467 | 11.1M | StringRef useModuleName) { |
2468 | 11.1M | assert(!module->getParent() && "cannot mangle nested modules!"); |
2469 | | |
2470 | | // Use the module real name in mangling; this is the physical name |
2471 | | // of the module on-disk, which can be different if -module-alias is |
2472 | | // used. |
2473 | | // |
2474 | | // For example, if a module Foo has 'import Bar', and '-module-alias Bar=Baz' |
2475 | | // was passed, the name 'Baz' will be used for mangling besides loading. |
2476 | 0 | StringRef ModName = module->getRealName().str(); |
2477 | 11.1M | if (RespectOriginallyDefinedIn && |
2478 | 11.1M | module->getABIName() != module->getName()) { // check if the ABI name is set |
2479 | 1.28M | ModName = module->getABIName().str(); |
2480 | 1.28M | } |
2481 | | |
2482 | | // Try the special 'swift' substitution. |
2483 | 11.1M | if (ModName == STDLIB_NAME) { |
2484 | 3.15M | if (useModuleName.empty()) { |
2485 | 3.15M | appendOperator("s"); |
2486 | 3.15M | } else if (!RespectOriginallyDefinedIn) { |
2487 | 0 | appendOperator("s"); |
2488 | 0 | } else { |
2489 | 0 | appendIdentifier(useModuleName); |
2490 | 0 | } |
2491 | 3.15M | return; |
2492 | 3.15M | } |
2493 | | |
2494 | 7.98M | if (ModName == MANGLING_MODULE_OBJC) { |
2495 | 858 | assert(useModuleName.empty()); |
2496 | 0 | return appendOperator("So"); |
2497 | 858 | } |
2498 | 7.97M | if (ModName == MANGLING_MODULE_CLANG_IMPORTER) { |
2499 | 48 | assert(useModuleName.empty()); |
2500 | 0 | return appendOperator("SC"); |
2501 | 48 | } |
2502 | | |
2503 | | // Disabling RespectOriginallyDefinedIn indicate the mangled names are not part |
2504 | | // of the ABI, probably used by the debugger or IDE (USR). These mangled names |
2505 | | // will not be demangled successfully if we use the original module name instead |
2506 | | // of the actual module name. |
2507 | 7.97M | if (!useModuleName.empty() && RespectOriginallyDefinedIn) |
2508 | 18.6k | appendIdentifier(useModuleName); |
2509 | 7.96M | else |
2510 | 7.96M | appendIdentifier(ModName); |
2511 | 7.97M | } |
2512 | | |
2513 | | /// Mangle the name of a protocol as a substitution candidate. |
2514 | | void ASTMangler::appendProtocolName(const ProtocolDecl *protocol, |
2515 | 2.29M | bool allowStandardSubstitution) { |
2516 | 2.29M | assert(AllowMarkerProtocols || !protocol->isMarkerProtocol()); |
2517 | | |
2518 | 2.29M | if (allowStandardSubstitution && tryAppendStandardSubstitution(protocol)) |
2519 | 779k | return; |
2520 | | |
2521 | | // We can use a symbolic reference if they're allowed in this context. |
2522 | 1.51M | if (canSymbolicReference(protocol)) { |
2523 | | // Try to use a symbolic reference substitution. |
2524 | 5.91k | if (tryMangleSubstitution(protocol)) |
2525 | 138 | return; |
2526 | | |
2527 | 5.77k | appendSymbolicReference(protocol); |
2528 | | // Substitutions can refer back to the symbolic reference. |
2529 | 5.77k | addSubstitution(protocol); |
2530 | 5.77k | return; |
2531 | 5.91k | } |
2532 | | |
2533 | 1.50M | appendContextOf(protocol); |
2534 | 1.50M | auto *clangDecl = protocol->getClangDecl(); |
2535 | 1.50M | auto clangProto = cast_or_null<clang::ObjCProtocolDecl>(clangDecl); |
2536 | 1.50M | if (clangProto && UseObjCRuntimeNames) |
2537 | 267 | appendIdentifier(clangProto->getObjCRuntimeNameAsString()); |
2538 | 1.50M | else if (clangProto) |
2539 | 8.75k | appendIdentifier(clangProto->getName()); |
2540 | 1.49M | else |
2541 | 1.49M | appendDeclName(protocol); |
2542 | 1.50M | } |
2543 | | |
2544 | 1.98k | bool ASTMangler::isCXXCFOptionsDefinition(const ValueDecl *decl) { |
2545 | 1.98k | return getTypeDefForCXXCFOptionsDefinition(decl); |
2546 | 1.98k | } |
2547 | | |
2548 | | const clang::TypedefType * |
2549 | 8.68M | ASTMangler::getTypeDefForCXXCFOptionsDefinition(const ValueDecl *decl) { |
2550 | 8.68M | const clang::Decl *clangDecl = decl->getClangDecl(); |
2551 | 8.68M | if (!clangDecl) |
2552 | 8.68M | return nullptr; |
2553 | | |
2554 | 4.81k | const auto &clangModuleLoader = decl->getASTContext().getClangModuleLoader(); |
2555 | 4.81k | return clangModuleLoader->getTypeDefForCXXCFOptionsDefinition(clangDecl); |
2556 | 8.68M | } |
2557 | | |
2558 | | const clang::NamedDecl * |
2559 | 9.16M | ASTMangler::getClangDeclForMangling(const ValueDecl *vd) { |
2560 | 9.16M | auto namedDecl = dyn_cast_or_null<clang::NamedDecl>(vd->getClangDecl()); |
2561 | 9.16M | if (!namedDecl) |
2562 | 8.72M | return nullptr; |
2563 | | |
2564 | | // Use an anonymous enum's enclosing typedef for the mangled name, if |
2565 | | // present. This matches C++'s rules for linkage names of tag declarations. |
2566 | 433k | if (namedDecl->getDeclName().isEmpty()) |
2567 | 38.5k | if (auto *tagDecl = dyn_cast<clang::TagDecl>(namedDecl)) |
2568 | 38.5k | if (auto *typedefDecl = tagDecl->getTypedefNameForAnonDecl()) |
2569 | 35.5k | namedDecl = typedefDecl; |
2570 | | |
2571 | 433k | if (namedDecl->getDeclName().isEmpty()) |
2572 | 2.94k | return nullptr; |
2573 | | |
2574 | 430k | return namedDecl; |
2575 | 433k | } |
2576 | | |
2577 | 170k | void ASTMangler::appendSymbolicReference(SymbolicReferent referent) { |
2578 | | // Drop in a placeholder. The real reference value has to be filled in during |
2579 | | // lowering to IR. |
2580 | 170k | auto offset = Buffer.str().size(); |
2581 | 170k | Buffer << StringRef("\0\0\0\0\0", 5); |
2582 | 170k | SymbolicReferences.emplace_back(referent, offset); |
2583 | 170k | } |
2584 | | |
2585 | 16.0M | void ASTMangler::appendAnyGenericType(const GenericTypeDecl *decl) { |
2586 | 16.0M | auto *nominal = dyn_cast<NominalTypeDecl>(decl); |
2587 | | |
2588 | 16.0M | if (nominal && isa<BuiltinTupleDecl>(nominal)) |
2589 | 21 | return appendOperator("BT"); |
2590 | | |
2591 | | // Check for certain standard types. |
2592 | 16.0M | if (tryAppendStandardSubstitution(decl)) |
2593 | 4.18M | return; |
2594 | | |
2595 | | // Mangle opaque type names. |
2596 | 11.9M | if (auto opaque = dyn_cast<OpaqueTypeDecl>(decl)) { |
2597 | 0 | appendOpaqueDeclName(opaque); |
2598 | 0 | return; |
2599 | 0 | } |
2600 | | |
2601 | | // For generic types, this uses the unbound type. |
2602 | 11.9M | if (nominal) { |
2603 | 11.8M | if (tryMangleTypeSubstitution(nominal->getDeclaredType(), nullptr)) |
2604 | 2.62M | return; |
2605 | 11.8M | } else { |
2606 | 47.4k | if (tryMangleSubstitution(cast<TypeAliasDecl>(decl))) |
2607 | 0 | return; |
2608 | 47.4k | } |
2609 | | |
2610 | | // Try to mangle a symbolic reference for a nominal type. |
2611 | 9.27M | if (nominal && canSymbolicReference(nominal)) { |
2612 | 164k | appendSymbolicReference(nominal); |
2613 | | // Substitutions can refer back to the symbolic reference. |
2614 | 164k | addTypeSubstitution(nominal->getDeclaredType(), nullptr); |
2615 | 164k | return; |
2616 | 164k | } |
2617 | | |
2618 | 9.10M | appendContextOf(decl); |
2619 | | |
2620 | | // Always use Clang names for imported Clang declarations, unless they don't |
2621 | | // have one. |
2622 | 9.10M | auto tryAppendClangName = [this, decl]() -> bool { |
2623 | 9.10M | auto *nominal = dyn_cast<NominalTypeDecl>(decl); |
2624 | 9.10M | auto namedDecl = getClangDeclForMangling(decl); |
2625 | 9.10M | if (!namedDecl) { |
2626 | 8.68M | if (auto typedefType = getTypeDefForCXXCFOptionsDefinition(decl)) { |
2627 | | // To make sure the C++ definition of CF_OPTIONS mangles the |
2628 | | // same way as the Objective-C definition, we mangle using the |
2629 | | // name of the backing typedef, but pretend as if it was an enum. |
2630 | | // See CFAvailability.h to understand how the definitions differ |
2631 | | // in C++ and Objective-C |
2632 | 1.20k | appendIdentifier(typedefType->getDecl()->getName()); |
2633 | 1.20k | appendOperator("V"); |
2634 | 1.20k | return true; |
2635 | 1.20k | } |
2636 | | |
2637 | 8.67M | return false; |
2638 | 8.68M | } |
2639 | | |
2640 | | // Mangle ObjC classes using their runtime names. |
2641 | 428k | auto interface = dyn_cast<clang::ObjCInterfaceDecl>(namedDecl); |
2642 | 428k | auto protocol = dyn_cast<clang::ObjCProtocolDecl>(namedDecl); |
2643 | | |
2644 | 428k | if (UseObjCRuntimeNames && interface) { |
2645 | 3.64k | appendIdentifier(interface->getObjCRuntimeNameAsString()); |
2646 | 424k | } else if (UseObjCRuntimeNames && protocol) { |
2647 | 0 | appendIdentifier(protocol->getObjCRuntimeNameAsString()); |
2648 | 424k | } else if (auto ctsd = dyn_cast<clang::ClassTemplateSpecializationDecl>(namedDecl)) { |
2649 | | // If this is a `ClassTemplateSpecializationDecl`, it was |
2650 | | // imported as a Swift decl with `__CxxTemplateInst...` name. |
2651 | | // `ClassTemplateSpecializationDecl`'s name does not include information about |
2652 | | // template arguments, and in order to prevent name clashes we use the |
2653 | | // name of the Swift decl which does include template arguments. |
2654 | 13.7k | appendIdentifier(nominal->getName().str()); |
2655 | 411k | } else { |
2656 | 411k | appendIdentifier(namedDecl->getName()); |
2657 | 411k | } |
2658 | | |
2659 | | // The important distinctions to maintain here are Objective-C's various |
2660 | | // namespaces: protocols, tags (struct/enum/union), and unqualified names. |
2661 | | // We continue to mangle "class" the standard Swift way because it feels |
2662 | | // weird to call that an alias, but they're really in the same namespace. |
2663 | 428k | if (interface) { |
2664 | 195k | appendOperator("C"); |
2665 | 232k | } else if (protocol) { |
2666 | 1.63k | appendOperator("P"); |
2667 | 230k | } else if (isa<clang::TagDecl>(namedDecl)) { |
2668 | | // Note: This includes enums, but that's okay. A Clang enum is not always |
2669 | | // imported as a Swift enum. |
2670 | 144k | appendOperator("V"); |
2671 | 144k | } else if (isa<clang::TypedefNameDecl>(namedDecl) || |
2672 | 86.1k | isa<clang::ObjCCompatibleAliasDecl>(namedDecl)) { |
2673 | 63.1k | appendOperator("a"); |
2674 | 63.1k | } else if (isa<clang::NamespaceDecl>(namedDecl)) { |
2675 | | // Note: Namespaces are not really enums, but since namespaces are |
2676 | | // imported as enums, be consistent. |
2677 | 22.9k | appendOperator("O"); |
2678 | 22.9k | } else if (isa<clang::ClassTemplateDecl>(namedDecl)) { |
2679 | 3 | appendIdentifier(nominal->getName().str()); |
2680 | 3 | } else { |
2681 | 0 | llvm_unreachable("unknown imported Clang type"); |
2682 | 0 | } |
2683 | | |
2684 | 428k | return true; |
2685 | 9.10M | }; |
2686 | | |
2687 | 9.10M | if (!tryAppendClangName()) { |
2688 | 8.67M | appendDeclName(decl); |
2689 | | |
2690 | 8.67M | switch (decl->getKind()) { |
2691 | 0 | default: |
2692 | 0 | llvm_unreachable("not a nominal type"); |
2693 | |
|
2694 | 47.3k | case DeclKind::TypeAlias: |
2695 | 47.3k | appendOperator("a"); |
2696 | 47.3k | break; |
2697 | 600k | case DeclKind::Protocol: |
2698 | 600k | assert(AllowMarkerProtocols || |
2699 | 600k | !cast<ProtocolDecl>(decl)->isMarkerProtocol()); |
2700 | 0 | appendOperator("P"); |
2701 | 600k | break; |
2702 | 1.76M | case DeclKind::Class: |
2703 | 1.76M | appendOperator("C"); |
2704 | 1.76M | break; |
2705 | 847k | case DeclKind::Enum: |
2706 | 847k | appendOperator("O"); |
2707 | 847k | break; |
2708 | 5.42M | case DeclKind::Struct: |
2709 | 5.42M | appendOperator("V"); |
2710 | 5.42M | break; |
2711 | 0 | case DeclKind::BuiltinTuple: |
2712 | 0 | llvm_unreachable("Not implemented"); |
2713 | 8.67M | } |
2714 | 8.67M | } |
2715 | | |
2716 | 9.10M | if (nominal) |
2717 | 9.06M | addTypeSubstitution(nominal->getDeclaredType(), nullptr); |
2718 | 47.4k | else |
2719 | 47.4k | addSubstitution(cast<TypeAliasDecl>(decl)); |
2720 | 9.10M | } |
2721 | | |
2722 | | void ASTMangler::appendFunction(AnyFunctionType *fn, GenericSignature sig, |
2723 | | FunctionManglingKind functionMangling, |
2724 | 2.16M | const ValueDecl *forDecl) { |
2725 | | // Append parameter labels right before the signature/type. |
2726 | 2.16M | auto parameters = fn->getParams(); |
2727 | 2.16M | auto firstLabel = std::find_if( |
2728 | 2.16M | parameters.begin(), parameters.end(), |
2729 | 2.35M | [&](AnyFunctionType::Param param) { return param.hasLabel(); }); |
2730 | | |
2731 | 2.16M | if (firstLabel != parameters.end()) { |
2732 | 1.69M | for (auto param : parameters) { |
2733 | 1.69M | auto label = param.getLabel(); |
2734 | 1.69M | if (!label.empty()) |
2735 | 1.45M | appendIdentifier(label.str()); |
2736 | 236k | else |
2737 | 236k | appendOperator("_"); |
2738 | 1.69M | } |
2739 | 1.28M | } else if (!parameters.empty()) { |
2740 | 880k | appendOperator("y"); |
2741 | 880k | } |
2742 | | |
2743 | 2.16M | if (functionMangling != NoFunctionMangling) { |
2744 | 1.69M | appendFunctionSignature(fn, sig, forDecl, functionMangling); |
2745 | 1.69M | } else { |
2746 | 464k | appendFunctionType(fn, sig, /*autoclosure*/ false, forDecl); |
2747 | 464k | } |
2748 | 2.16M | } |
2749 | | |
2750 | | void ASTMangler::appendFunctionType(AnyFunctionType *fn, GenericSignature sig, |
2751 | | bool isAutoClosure, |
2752 | 804k | const ValueDecl *forDecl) { |
2753 | 804k | assert((DWARFMangling || fn->isCanonical()) && |
2754 | 804k | "expecting canonical types when not mangling for the debugger"); |
2755 | | |
2756 | 0 | appendFunctionSignature(fn, sig, forDecl, NoFunctionMangling); |
2757 | | |
2758 | 804k | bool mangleClangType = fn->getASTContext().LangOpts.UseClangFunctionTypes && |
2759 | 804k | fn->hasNonDerivableClangType(); |
2760 | | |
2761 | | // Note that we do not currently use thin representations in the AST |
2762 | | // for the types of function decls. This may need to change at some |
2763 | | // point, in which case the uncurry logic can probably migrate to that |
2764 | | // case. |
2765 | | // |
2766 | | // It would have been cleverer if we'd used 'f' for thin functions |
2767 | | // and something else for uncurried functions, but oh well. |
2768 | | // |
2769 | | // Or maybe we can change the mangling at the same time we make |
2770 | | // changes to better support thin functions. |
2771 | 804k | switch (fn->getRepresentation()) { |
2772 | 1.86k | case AnyFunctionType::Representation::Block: |
2773 | 1.86k | if (mangleClangType) { |
2774 | 0 | appendOperator("XzB"); |
2775 | 0 | return appendClangType(fn); |
2776 | 0 | } |
2777 | | // We distinguish escaping and non-escaping blocks, but only in the DWARF |
2778 | | // mangling, because the ABI is already set. |
2779 | 1.86k | if (!fn->isNoEscape() && DWARFMangling) |
2780 | 117 | return appendOperator("XL"); |
2781 | 1.75k | return appendOperator("XB"); |
2782 | 417 | case AnyFunctionType::Representation::Thin: |
2783 | 417 | return appendOperator("Xf"); |
2784 | 800k | case AnyFunctionType::Representation::Swift: |
2785 | 800k | if (isAutoClosure) { |
2786 | 23.9k | if (fn->isNoEscape()) |
2787 | 22.7k | return appendOperator("XK"); |
2788 | 1.12k | else |
2789 | 1.12k | return appendOperator("XA"); |
2790 | 776k | } else if (fn->isNoEscape()) { |
2791 | 129k | return appendOperator("XE"); |
2792 | 129k | } |
2793 | 647k | return appendOperator("c"); |
2794 | | |
2795 | 1.68k | case AnyFunctionType::Representation::CFunctionPointer: |
2796 | 1.68k | if (mangleClangType) { |
2797 | 24 | appendOperator("XzC"); |
2798 | 24 | return appendClangType(fn); |
2799 | 24 | } |
2800 | 1.65k | return appendOperator("XC"); |
2801 | 804k | } |
2802 | 804k | } |
2803 | | |
2804 | | template <typename FnType> |
2805 | 24 | void ASTMangler::appendClangType(FnType *fn, llvm::raw_svector_ostream &out) { |
2806 | 24 | auto clangType = fn->getClangTypeInfo().getType(); |
2807 | 24 | SmallString<64> scratch; |
2808 | 24 | llvm::raw_svector_ostream scratchOS(scratch); |
2809 | 24 | clang::ASTContext &clangCtx = |
2810 | 24 | fn->getASTContext().getClangModuleLoader()->getClangASTContext(); |
2811 | 24 | std::unique_ptr<clang::ItaniumMangleContext> mangler{ |
2812 | 24 | clang::ItaniumMangleContext::create(clangCtx, clangCtx.getDiagnostics())}; |
2813 | 24 | mangler->mangleTypeName(clang::QualType(clangType, 0), scratchOS); |
2814 | 24 | out << scratchOS.str().size() << scratchOS.str(); |
2815 | 24 | } Unexecuted instantiation: _ZN5swift6Mangle10ASTMangler15appendClangTypeINS_15SILFunctionTypeEEEvPT_RN4llvm19raw_svector_ostreamE _ZN5swift6Mangle10ASTMangler15appendClangTypeINS_15AnyFunctionTypeEEEvPT_RN4llvm19raw_svector_ostreamE Line | Count | Source | 2805 | 24 | void ASTMangler::appendClangType(FnType *fn, llvm::raw_svector_ostream &out) { | 2806 | 24 | auto clangType = fn->getClangTypeInfo().getType(); | 2807 | 24 | SmallString<64> scratch; | 2808 | 24 | llvm::raw_svector_ostream scratchOS(scratch); | 2809 | 24 | clang::ASTContext &clangCtx = | 2810 | 24 | fn->getASTContext().getClangModuleLoader()->getClangASTContext(); | 2811 | 24 | std::unique_ptr<clang::ItaniumMangleContext> mangler{ | 2812 | 24 | clang::ItaniumMangleContext::create(clangCtx, clangCtx.getDiagnostics())}; | 2813 | 24 | mangler->mangleTypeName(clang::QualType(clangType, 0), scratchOS); | 2814 | 24 | out << scratchOS.str().size() << scratchOS.str(); | 2815 | 24 | } |
|
2816 | | |
2817 | 24 | void ASTMangler::appendClangType(AnyFunctionType *fn) { |
2818 | 24 | appendClangType(fn, Buffer); |
2819 | 24 | } |
2820 | | |
2821 | | void ASTMangler::appendFunctionSignature(AnyFunctionType *fn, |
2822 | | GenericSignature sig, |
2823 | | const ValueDecl *forDecl, |
2824 | 2.50M | FunctionManglingKind functionMangling) { |
2825 | 2.50M | appendFunctionResultType(fn->getResult(), sig, forDecl); |
2826 | 2.50M | appendFunctionInputType(fn->getParams(), sig, forDecl); |
2827 | 2.50M | if (fn->isAsync()) |
2828 | 70.8k | appendOperator("Ya"); |
2829 | 2.50M | if (fn->isSendable()) |
2830 | 15.2k | appendOperator("Yb"); |
2831 | 2.50M | if (auto thrownError = fn->getEffectiveThrownErrorType()) { |
2832 | 371k | if ((*thrownError)->isEqual(fn->getASTContext().getErrorExistentialType())){ |
2833 | 371k | appendOperator("K"); |
2834 | 371k | } else { |
2835 | 225 | appendType(*thrownError, sig); |
2836 | 225 | appendOperator("YK"); |
2837 | 225 | } |
2838 | 371k | } |
2839 | 2.50M | switch (auto diffKind = fn->getDifferentiabilityKind()) { |
2840 | 2.50M | case DifferentiabilityKind::NonDifferentiable: |
2841 | 2.50M | break; |
2842 | 0 | case DifferentiabilityKind::Forward: |
2843 | 0 | appendOperator("Yjf"); |
2844 | 0 | break; |
2845 | 1.61k | case DifferentiabilityKind::Reverse: |
2846 | 1.61k | appendOperator("Yjr"); |
2847 | 1.61k | break; |
2848 | 0 | case DifferentiabilityKind::Normal: |
2849 | 0 | appendOperator("Yjd"); |
2850 | 0 | break; |
2851 | 52 | case DifferentiabilityKind::Linear: |
2852 | 52 | appendOperator("Yjl"); |
2853 | 52 | break; |
2854 | 2.50M | } |
2855 | | |
2856 | 2.50M | if (Type globalActor = fn->getGlobalActor()) { |
2857 | 1.04k | appendType(globalActor, sig); |
2858 | 1.04k | appendOperator("Yc"); |
2859 | 1.04k | } |
2860 | 2.50M | } |
2861 | | |
2862 | | static ParamSpecifier |
2863 | 2.50M | getDefaultOwnership(const ValueDecl *forDecl) { |
2864 | | // `consuming` is the default ownership for initializers and setters. |
2865 | | // Everything else defaults to borrowing. |
2866 | 2.50M | if (!forDecl) { |
2867 | 319k | return ParamSpecifier::Borrowing; |
2868 | 319k | } |
2869 | 2.18M | auto forFuncDecl = dyn_cast<AbstractFunctionDecl>(forDecl); |
2870 | 2.18M | if (!forFuncDecl) { |
2871 | 141k | return ParamSpecifier::Borrowing; |
2872 | 141k | } |
2873 | | |
2874 | 2.04M | if (isa<ConstructorDecl>(forFuncDecl)) { |
2875 | 366k | return ParamSpecifier::Consuming; |
2876 | 1.67M | } else if (auto accessor = dyn_cast<AccessorDecl>(forFuncDecl)) { |
2877 | 0 | switch (accessor->getAccessorKind()) { |
2878 | 0 | case AccessorKind::Modify: |
2879 | 0 | case AccessorKind::Set: |
2880 | 0 | return ParamSpecifier::Consuming; |
2881 | 0 | default: |
2882 | 0 | return ParamSpecifier::Borrowing; |
2883 | 0 | } |
2884 | 0 | } |
2885 | | |
2886 | 1.67M | return ParamSpecifier::Borrowing; |
2887 | 2.04M | } |
2888 | | |
2889 | | static ParameterTypeFlags |
2890 | | getParameterFlagsForMangling(ParameterTypeFlags flags, |
2891 | 3.11M | ParamSpecifier defaultSpecifier) { |
2892 | 3.11M | switch (auto specifier = flags.getOwnershipSpecifier()) { |
2893 | | // If no parameter specifier was provided, mangle as-is, because we are by |
2894 | | // definition using the default convention. |
2895 | 2.79M | case ParamSpecifier::Default: |
2896 | | // If the legacy `__shared` or `__owned` modifier was provided, mangle as-is, |
2897 | | // because we need to maintain compatibility with their existing behavior. |
2898 | 2.79M | case ParamSpecifier::LegacyShared: |
2899 | 2.90M | case ParamSpecifier::LegacyOwned: |
2900 | | // `inout` should already be specified in the flags. |
2901 | 3.10M | case ParamSpecifier::InOut: |
2902 | 3.10M | return flags; |
2903 | | |
2904 | 4.88k | case ParamSpecifier::Consuming: |
2905 | 7.59k | case ParamSpecifier::Borrowing: |
2906 | | // Only mangle the ownership if it diverges from the default. |
2907 | 7.59k | if (specifier == defaultSpecifier) { |
2908 | 2.75k | flags = flags.withOwnershipSpecifier(ParamSpecifier::Default); |
2909 | 2.75k | } |
2910 | 7.59k | return flags; |
2911 | 3.11M | } |
2912 | 3.11M | } |
2913 | | |
2914 | | void ASTMangler::appendFunctionInputType( |
2915 | | ArrayRef<AnyFunctionType::Param> params, |
2916 | | GenericSignature sig, |
2917 | 2.50M | const ValueDecl *forDecl) { |
2918 | 2.50M | auto defaultSpecifier = getDefaultOwnership(forDecl); |
2919 | | |
2920 | 2.50M | switch (params.size()) { |
2921 | 613k | case 0: |
2922 | 613k | appendOperator("y"); |
2923 | 613k | break; |
2924 | | |
2925 | 1.08M | case 1: { |
2926 | 1.08M | const auto ¶m = params.front(); |
2927 | 1.08M | auto type = param.getPlainType(); |
2928 | | |
2929 | | // If the sole unlabeled parameter has a non-tuple type, encode |
2930 | | // the parameter list as a single type. |
2931 | 1.08M | if (!param.hasLabel() && !param.isVariadic() && |
2932 | 1.08M | !isa<TupleType>(type.getPointer())) { |
2933 | | // Note that we pass `nullptr` as the `forDecl` argument, since the type |
2934 | | // of the input is no longer directly the type of the declaration, so we |
2935 | | // don't want it to pick up contextual behavior, such as default ownership, |
2936 | | // from the top-level declaration type. |
2937 | 635k | appendTypeListElement(Identifier(), type, |
2938 | 635k | getParameterFlagsForMangling(param.getParameterFlags(), |
2939 | 635k | defaultSpecifier), |
2940 | 635k | sig, nullptr); |
2941 | 635k | break; |
2942 | 635k | } |
2943 | | |
2944 | | // If this is a tuple type with a single labeled element |
2945 | | // let's handle it as a general case. |
2946 | 1.08M | LLVM_FALLTHROUGH; |
2947 | 450k | } |
2948 | | |
2949 | 1.25M | default: |
2950 | 1.25M | bool isFirstParam = true; |
2951 | 2.47M | for (auto ¶m : params) { |
2952 | | // Note that we pass `nullptr` as the `forDecl` argument, since the type |
2953 | | // of the input is no longer directly the type of the declaration, so we |
2954 | | // don't want it to pick up contextual behavior, such as default ownership, |
2955 | | // from the top-level declaration type. |
2956 | 2.47M | appendTypeListElement(Identifier(), param.getPlainType(), |
2957 | 2.47M | getParameterFlagsForMangling(param.getParameterFlags(), |
2958 | 2.47M | defaultSpecifier), |
2959 | 2.47M | sig, nullptr); |
2960 | 2.47M | appendListSeparator(isFirstParam); |
2961 | 2.47M | } |
2962 | 1.25M | appendOperator("t"); |
2963 | 1.25M | break; |
2964 | 2.50M | } |
2965 | 2.50M | } |
2966 | | |
2967 | | void ASTMangler::appendFunctionResultType(Type resultType, GenericSignature sig, |
2968 | 2.50M | const ValueDecl *forDecl) { |
2969 | 2.50M | return resultType->isVoid() ? appendOperator("y") |
2970 | 2.50M | : appendType(resultType, sig, forDecl); |
2971 | 2.50M | } |
2972 | | |
2973 | | void ASTMangler::appendTypeList(Type listTy, GenericSignature sig, |
2974 | 138k | const ValueDecl *forDecl) { |
2975 | 138k | if (TupleType *tuple = listTy->getAs<TupleType>()) { |
2976 | 138k | if (tuple->getNumElements() == 0) |
2977 | 40.8k | return appendOperator("y"); |
2978 | 97.4k | bool firstField = true; |
2979 | 339k | for (auto &field : tuple->getElements()) { |
2980 | 339k | appendTypeListElement(field.getName(), field.getType(), |
2981 | 339k | ParameterTypeFlags(), |
2982 | 339k | sig, forDecl); |
2983 | 339k | appendListSeparator(firstField); |
2984 | 339k | } |
2985 | 97.4k | } else { |
2986 | 0 | appendType(listTy, sig, forDecl); |
2987 | 0 | appendListSeparator(); |
2988 | 0 | } |
2989 | 138k | } |
2990 | | |
2991 | | void ASTMangler::appendTypeListElement(Identifier name, Type elementType, |
2992 | | ParameterTypeFlags flags, |
2993 | | GenericSignature sig, |
2994 | 3.45M | const ValueDecl *forDecl) { |
2995 | 3.45M | if (auto *fnType = elementType->getAs<FunctionType>()) |
2996 | 116k | appendFunctionType(fnType, sig, flags.isAutoClosure(), forDecl); |
2997 | 3.33M | else |
2998 | 3.33M | appendType(elementType, sig, forDecl); |
2999 | | |
3000 | 3.45M | if (flags.isNoDerivative()) { |
3001 | 172 | appendOperator("Yk"); |
3002 | 172 | } |
3003 | 3.45M | switch (flags.getValueOwnership()) { |
3004 | 3.13M | case ValueOwnership::Default: |
3005 | | /* nothing */ |
3006 | 3.13M | break; |
3007 | 202k | case ValueOwnership::InOut: |
3008 | 202k | appendOperator("z"); |
3009 | 202k | break; |
3010 | 3.77k | case ValueOwnership::Shared: |
3011 | 3.77k | appendOperator("h"); |
3012 | 3.77k | break; |
3013 | 107k | case ValueOwnership::Owned: |
3014 | 107k | appendOperator("n"); |
3015 | 107k | break; |
3016 | 3.45M | } |
3017 | 3.45M | if (flags.isIsolated()) |
3018 | 378 | appendOperator("Yi"); |
3019 | | |
3020 | 3.45M | if (flags.isCompileTimeConst()) |
3021 | 36 | appendOperator("Yt"); |
3022 | | |
3023 | 3.45M | if (!name.empty()) |
3024 | 63.7k | appendIdentifier(name.str()); |
3025 | 3.45M | if (flags.isVariadic()) |
3026 | 21.8k | appendOperator("d"); |
3027 | 3.45M | } |
3028 | | |
3029 | | bool ASTMangler::appendGenericSignature(GenericSignature sig, |
3030 | 1.74M | GenericSignature contextSig) { |
3031 | 1.74M | auto canSig = sig.getCanonicalSignature(); |
3032 | | |
3033 | 1.74M | unsigned initialParamDepth; |
3034 | 1.74M | ArrayRef<CanTypeWrapper<GenericTypeParamType>> genericParams; |
3035 | 1.74M | ArrayRef<Requirement> requirements; |
3036 | 1.74M | SmallVector<Requirement, 4> requirementsBuffer; |
3037 | 1.74M | if (contextSig) { |
3038 | | // If the signature is the same as the context signature, there's nothing |
3039 | | // to do. |
3040 | 1.41M | if (contextSig.getCanonicalSignature() == canSig) { |
3041 | 969k | return false; |
3042 | 969k | } |
3043 | | |
3044 | | // The signature depth starts above the depth of the context signature. |
3045 | 448k | if (!contextSig.getGenericParams().empty()) { |
3046 | 448k | initialParamDepth = contextSig.getGenericParams().back()->getDepth() + 1; |
3047 | 448k | } |
3048 | | |
3049 | | // Find the parameters at this depth (or greater). |
3050 | 448k | genericParams = canSig.getGenericParams(); |
3051 | 448k | unsigned firstParam = genericParams.size(); |
3052 | 626k | while (firstParam > 1 && |
3053 | 626k | genericParams[firstParam-1]->getDepth() >= initialParamDepth) |
3054 | 177k | --firstParam; |
3055 | 448k | genericParams = genericParams.slice(firstParam); |
3056 | | |
3057 | | // Special case: if we would be mangling zero generic parameters, but |
3058 | | // the context signature is a single, unconstrained generic parameter, |
3059 | | // it's better to mangle the complete canonical signature because we |
3060 | | // have a special-case mangling for that. |
3061 | 448k | if (genericParams.empty() && |
3062 | 448k | contextSig.getGenericParams().size() == 1 && |
3063 | 448k | contextSig.getRequirements().empty()) { |
3064 | 45.7k | initialParamDepth = 0; |
3065 | 45.7k | genericParams = canSig.getGenericParams(); |
3066 | 45.7k | requirements = canSig.getRequirements(); |
3067 | 403k | } else { |
3068 | 403k | requirementsBuffer = canSig.requirementsNotSatisfiedBy(contextSig); |
3069 | 403k | requirements = requirementsBuffer; |
3070 | 403k | } |
3071 | 448k | } else { |
3072 | | // Use the complete canonical signature. |
3073 | 330k | initialParamDepth = 0; |
3074 | 330k | genericParams = canSig.getGenericParams(); |
3075 | 330k | requirements = canSig.getRequirements(); |
3076 | 330k | } |
3077 | | |
3078 | 779k | if (genericParams.empty() && requirements.empty()) |
3079 | 0 | return false; |
3080 | | |
3081 | 779k | appendGenericSignatureParts(sig, genericParams, |
3082 | 779k | initialParamDepth, requirements); |
3083 | 779k | return true; |
3084 | 779k | } |
3085 | | |
3086 | | void ASTMangler::appendRequirement(const Requirement &reqt, |
3087 | | GenericSignature sig, |
3088 | 941k | bool lhsBaseIsProtocolSelf) { |
3089 | | |
3090 | 941k | Type FirstTy = reqt.getFirstType()->getCanonicalType(); |
3091 | | |
3092 | 941k | switch (reqt.getKind()) { |
3093 | 2.06k | case RequirementKind::Layout: |
3094 | 2.06k | break; |
3095 | 630k | case RequirementKind::Conformance: { |
3096 | | // If we don't allow marker protocols but we have one here, skip it. |
3097 | 630k | if (!AllowMarkerProtocols && |
3098 | 630k | reqt.getProtocolDecl()->isMarkerProtocol()) |
3099 | 75 | return; |
3100 | | |
3101 | 630k | appendProtocolName(reqt.getProtocolDecl()); |
3102 | 630k | } break; |
3103 | 12.7k | case RequirementKind::Superclass: |
3104 | 308k | case RequirementKind::SameType: |
3105 | 308k | case RequirementKind::SameShape: { |
3106 | 308k | Type SecondTy = reqt.getSecondType(); |
3107 | 308k | appendType(SecondTy->getCanonicalType(), sig); |
3108 | 308k | break; |
3109 | 308k | } |
3110 | 941k | } |
3111 | | |
3112 | 940k | if (auto *DT = FirstTy->getAs<DependentMemberType>()) { |
3113 | 177k | if (tryMangleTypeSubstitution(DT, sig)) { |
3114 | 26.7k | switch (reqt.getKind()) { |
3115 | 0 | case RequirementKind::SameShape: |
3116 | 0 | llvm_unreachable("Same-shape requirement with dependent member type?"); |
3117 | 3.89k | case RequirementKind::Conformance: |
3118 | 3.89k | return appendOperator("RQ"); |
3119 | 0 | case RequirementKind::Layout: |
3120 | 0 | appendOperator("RL"); |
3121 | 0 | appendOpParamForLayoutConstraint(reqt.getLayoutConstraint()); |
3122 | 0 | return; |
3123 | 0 | case RequirementKind::Superclass: |
3124 | 0 | return appendOperator("RB"); |
3125 | 22.8k | case RequirementKind::SameType: |
3126 | 22.8k | return appendOperator("RS"); |
3127 | 26.7k | } |
3128 | 0 | llvm_unreachable("bad requirement type"); |
3129 | 0 | } |
3130 | 150k | bool isAssocTypeAtDepth = false; |
3131 | 150k | GenericTypeParamType *gpBase = appendAssocType(DT, sig, |
3132 | 150k | isAssocTypeAtDepth); |
3133 | 150k | addTypeSubstitution(DT, sig); |
3134 | 150k | assert(gpBase); |
3135 | 0 | switch (reqt.getKind()) { |
3136 | 0 | case RequirementKind::SameShape: |
3137 | 0 | llvm_unreachable("Same-shape requirement with a dependent member type?"); |
3138 | 50.8k | case RequirementKind::Conformance: |
3139 | 50.8k | return appendOpWithGenericParamIndex(isAssocTypeAtDepth ? "RP" : "Rp", |
3140 | 50.8k | gpBase, lhsBaseIsProtocolSelf); |
3141 | 114 | case RequirementKind::Layout: |
3142 | 114 | appendOpWithGenericParamIndex(isAssocTypeAtDepth ? "RM" : "Rm", gpBase, |
3143 | 114 | lhsBaseIsProtocolSelf); |
3144 | 114 | appendOpParamForLayoutConstraint(reqt.getLayoutConstraint()); |
3145 | 114 | return; |
3146 | 255 | case RequirementKind::Superclass: |
3147 | 255 | return appendOpWithGenericParamIndex(isAssocTypeAtDepth ? "RC" : "Rc", |
3148 | 255 | gpBase, lhsBaseIsProtocolSelf); |
3149 | 99.1k | case RequirementKind::SameType: |
3150 | 99.1k | return appendOpWithGenericParamIndex(isAssocTypeAtDepth ? "RT" : "Rt", |
3151 | 99.1k | gpBase, lhsBaseIsProtocolSelf); |
3152 | 150k | } |
3153 | 0 | llvm_unreachable("bad requirement type"); |
3154 | 0 | } |
3155 | 763k | GenericTypeParamType *gpBase = FirstTy->castTo<GenericTypeParamType>(); |
3156 | 763k | switch (reqt.getKind()) { |
3157 | 576k | case RequirementKind::Conformance: |
3158 | 576k | return appendOpWithGenericParamIndex("R", gpBase); |
3159 | 1.95k | case RequirementKind::Layout: |
3160 | 1.95k | appendOpWithGenericParamIndex("Rl", gpBase); |
3161 | 1.95k | appendOpParamForLayoutConstraint(reqt.getLayoutConstraint()); |
3162 | 1.95k | return; |
3163 | 12.4k | case RequirementKind::Superclass: |
3164 | 12.4k | return appendOpWithGenericParamIndex("Rb", gpBase); |
3165 | 173k | case RequirementKind::SameType: |
3166 | 173k | return appendOpWithGenericParamIndex("Rs", gpBase); |
3167 | 54 | case RequirementKind::SameShape: |
3168 | 54 | return appendOpWithGenericParamIndex("Rh", gpBase); |
3169 | 763k | } |
3170 | 0 | llvm_unreachable("bad requirement type"); |
3171 | 0 | } |
3172 | | |
3173 | | void ASTMangler::appendGenericSignatureParts( |
3174 | | GenericSignature sig, |
3175 | | ArrayRef<CanGenericTypeParamType> params, |
3176 | | unsigned initialParamDepth, |
3177 | 779k | ArrayRef<Requirement> requirements) { |
3178 | | // Mangle which generic parameters are pack parameters. |
3179 | 779k | for (auto param : params) { |
3180 | 687k | if (param->isParameterPack()) |
3181 | 1.08k | appendOpWithGenericParamIndex("Rv", param); |
3182 | 687k | } |
3183 | | |
3184 | | // Mangle the requirements. |
3185 | 939k | for (const Requirement &reqt : requirements) { |
3186 | 939k | appendRequirement(reqt, sig); |
3187 | 939k | } |
3188 | | |
3189 | 779k | if (params.size() == 1 && params[0]->getDepth() == initialParamDepth) |
3190 | 401k | return appendOperator("l"); |
3191 | | |
3192 | 377k | llvm::SmallVector<char, 16> OpStorage; |
3193 | 377k | llvm::raw_svector_ostream OpBuffer(OpStorage); |
3194 | | |
3195 | | // Mangle the number of parameters. |
3196 | 377k | unsigned depth = 0; |
3197 | 377k | unsigned count = 0; |
3198 | | |
3199 | | // Since it's unlikely (but not impossible) to have zero generic parameters |
3200 | | // at a depth, encode indexes starting from 1, and use a special mangling |
3201 | | // for zero. |
3202 | 407k | auto mangleGenericParamCount = [&](unsigned depth, unsigned count) { |
3203 | 407k | if (depth < initialParamDepth) |
3204 | 279k | return; |
3205 | 128k | if (count == 0) |
3206 | 0 | OpBuffer << 'z'; |
3207 | 128k | else |
3208 | 128k | OpBuffer << Index(count - 1); |
3209 | 128k | }; |
3210 | | |
3211 | | // As a special case, mangle nothing if there's a single generic parameter |
3212 | | // at the initial depth. |
3213 | 377k | for (auto param : params) { |
3214 | 286k | if (param->getDepth() != depth) { |
3215 | 29.3k | assert(param->getDepth() > depth && "generic params not ordered"); |
3216 | 58.7k | while (depth < param->getDepth()) { |
3217 | 29.4k | mangleGenericParamCount(depth, count); |
3218 | 29.4k | ++depth; |
3219 | 29.4k | count = 0; |
3220 | 29.4k | } |
3221 | 29.3k | } |
3222 | 0 | assert(param->getIndex() == count && "generic params not ordered"); |
3223 | 0 | ++count; |
3224 | 286k | } |
3225 | 377k | mangleGenericParamCount(depth, count); |
3226 | 377k | OpBuffer << 'l'; |
3227 | | |
3228 | 377k | appendOperator("r", StringRef(OpStorage.data(), OpStorage.size())); |
3229 | 377k | } |
3230 | | |
3231 | | /// Determine whether an associated type reference into the given set of |
3232 | | /// protocols is unambiguous. |
3233 | 1.45M | static bool associatedTypeRefIsUnambiguous(GenericSignature sig, Type t) { |
3234 | | // FIXME: This should be an assertion. |
3235 | 1.45M | if (!sig->isValidTypeParameter(t)) |
3236 | 288 | return false; |
3237 | | |
3238 | 1.45M | unsigned numProtocols = 0; |
3239 | 1.54M | for (auto proto : sig->getRequiredProtocols(t)) { |
3240 | | // Skip marker protocols, which cannot have associated types. |
3241 | 1.54M | if (proto->isMarkerProtocol()) |
3242 | 885 | continue; |
3243 | | |
3244 | 1.54M | ++numProtocols; |
3245 | 1.54M | } |
3246 | | |
3247 | 1.45M | return numProtocols <= 1; |
3248 | 1.45M | } |
3249 | | |
3250 | | // If the base type is known to have a single protocol conformance |
3251 | | // in the current generic context, then we don't need to disambiguate the |
3252 | | // associated type name by protocol. |
3253 | | DependentMemberType * |
3254 | | ASTMangler::dropProtocolFromAssociatedType(DependentMemberType *dmt, |
3255 | 1.04M | GenericSignature sig) { |
3256 | 1.04M | auto baseTy = dmt->getBase(); |
3257 | 1.04M | bool unambiguous = |
3258 | 1.04M | (!dmt->getAssocType() || |
3259 | 1.04M | associatedTypeRefIsUnambiguous(sig, baseTy)); |
3260 | | |
3261 | 1.04M | if (auto *baseDMT = baseTy->getAs<DependentMemberType>()) |
3262 | 20.2k | baseTy = dropProtocolFromAssociatedType(baseDMT, sig); |
3263 | | |
3264 | 1.04M | if (unambiguous) |
3265 | 1.00M | return DependentMemberType::get(baseTy, dmt->getName()); |
3266 | | |
3267 | 45.6k | return DependentMemberType::get(baseTy, dmt->getAssocType()); |
3268 | 1.04M | } |
3269 | | |
3270 | | Type |
3271 | | ASTMangler::dropProtocolsFromAssociatedTypes(Type type, |
3272 | 29.3M | GenericSignature sig) { |
3273 | 29.3M | if (!OptimizeProtocolNames || !sig) |
3274 | 26.9M | return type; |
3275 | | |
3276 | 2.44M | if (!type->hasDependentMember()) |
3277 | 1.42M | return type; |
3278 | | |
3279 | 1.25M | return type.transform([&](Type t) -> Type { |
3280 | 1.25M | if (auto *dmt = dyn_cast<DependentMemberType>(t.getPointer())) |
3281 | 1.02M | return dropProtocolFromAssociatedType(dmt, sig); |
3282 | 231k | return t; |
3283 | 1.25M | }); |
3284 | 2.44M | } |
3285 | | |
3286 | | void ASTMangler::appendAssociatedTypeName(DependentMemberType *dmt, |
3287 | 595k | GenericSignature sig) { |
3288 | 595k | if (auto assocTy = dmt->getAssocType()) { |
3289 | 595k | appendIdentifier(assocTy->getName().str()); |
3290 | | |
3291 | | // If the base type is known to have a single protocol conformance |
3292 | | // in the current generic context, then we don't need to disambiguate the |
3293 | | // associated type name by protocol. |
3294 | 595k | if (!OptimizeProtocolNames || !sig || |
3295 | 595k | !associatedTypeRefIsUnambiguous( |
3296 | 407k | sig, dmt->getBase())) { |
3297 | 208k | appendAnyGenericType(assocTy->getProtocol()); |
3298 | 208k | } |
3299 | 595k | return; |
3300 | 595k | } |
3301 | | |
3302 | 0 | appendIdentifier(dmt->getName().str()); |
3303 | 0 | } |
3304 | | |
3305 | | void ASTMangler::appendClosureEntity( |
3306 | 801 | const SerializedAbstractClosureExpr *closure) { |
3307 | 801 | appendClosureComponents(closure->getType(), closure->getDiscriminator(), |
3308 | 801 | closure->isImplicit(), closure->getParent()); |
3309 | 801 | } |
3310 | | |
3311 | 189k | void ASTMangler::appendClosureEntity(const AbstractClosureExpr *closure) { |
3312 | 189k | appendClosureComponents(closure->getType(), closure->getDiscriminator(), |
3313 | 189k | isa<AutoClosureExpr>(closure), closure->getParent()); |
3314 | 189k | } |
3315 | | |
3316 | | void ASTMangler::appendClosureComponents(Type Ty, unsigned discriminator, |
3317 | | bool isImplicit, |
3318 | 190k | const DeclContext *parentContext) { |
3319 | 190k | assert(discriminator != AbstractClosureExpr::InvalidDiscriminator |
3320 | 190k | && "closure must be marked correctly with discriminator"); |
3321 | | |
3322 | 0 | appendContext(parentContext, StringRef()); |
3323 | | |
3324 | 190k | if (!Ty) |
3325 | 171 | Ty = ErrorType::get(parentContext->getASTContext()); |
3326 | | |
3327 | 190k | auto Sig = parentContext->getGenericSignatureOfContext(); |
3328 | 190k | Ty = Ty->mapTypeOutOfContext(); |
3329 | 190k | appendType(Ty->getCanonicalType(), Sig); |
3330 | 190k | appendOperator(isImplicit ? "fu" : "fU", Index(discriminator)); |
3331 | 190k | } |
3332 | | |
3333 | | void ASTMangler::appendDefaultArgumentEntity(const DeclContext *func, |
3334 | 56.1k | unsigned index) { |
3335 | 56.1k | appendContext(func, StringRef()); |
3336 | 56.1k | appendOperator("fA", Index(index)); |
3337 | 56.1k | } |
3338 | | |
3339 | 33.4k | void ASTMangler::appendInitializerEntity(const VarDecl *var) { |
3340 | 33.4k | appendEntity(var, "vp", var->isStatic()); |
3341 | 33.4k | appendOperator("fi"); |
3342 | 33.4k | } |
3343 | | |
3344 | 605 | void ASTMangler::appendBackingInitializerEntity(const VarDecl *var) { |
3345 | 605 | appendEntity(var, "vp", var->isStatic()); |
3346 | 605 | appendOperator("fP"); |
3347 | 605 | } |
3348 | | |
3349 | 66 | void ASTMangler::appendInitFromProjectedValueEntity(const VarDecl *var) { |
3350 | 66 | appendEntity(var, "vp", var->isStatic()); |
3351 | 66 | appendOperator("fW"); |
3352 | 66 | } |
3353 | | |
3354 | | /// Is this declaration a method for mangling purposes? If so, we'll leave the |
3355 | | /// Self type out of its mangling. |
3356 | 6.15M | static bool isMethodDecl(const Decl *decl) { |
3357 | 6.15M | return isa<AbstractFunctionDecl>(decl) |
3358 | 6.15M | && decl->getDeclContext()->isTypeContext(); |
3359 | 6.15M | } |
3360 | | |
3361 | | CanType ASTMangler::getDeclTypeForMangling( |
3362 | | const ValueDecl *decl, |
3363 | | GenericSignature &genericSig, |
3364 | 3.07M | GenericSignature &parentGenericSig) { |
3365 | 3.07M | genericSig = GenericSignature(); |
3366 | 3.07M | parentGenericSig = GenericSignature(); |
3367 | | |
3368 | 3.07M | auto &C = decl->getASTContext(); |
3369 | 3.07M | if (decl->isInvalid()) { |
3370 | 1.71k | if (isa<AbstractFunctionDecl>(decl)) { |
3371 | | // FIXME: Verify ExtInfo state is correct, not working by accident. |
3372 | 540 | CanFunctionType::ExtInfo info; |
3373 | 540 | return CanFunctionType::get({AnyFunctionType::Param(C.TheErrorType)}, |
3374 | 540 | C.TheErrorType, info); |
3375 | 540 | } |
3376 | 1.17k | return C.TheErrorType; |
3377 | 1.71k | } |
3378 | | |
3379 | 3.07M | Type ty = decl->getInterfaceType()->getReferenceStorageReferent(); |
3380 | | |
3381 | | // If this declaration predates concurrency, adjust its type to not |
3382 | | // contain type features that were not available pre-concurrency. This |
3383 | | // cannot alter the ABI in any way. |
3384 | 3.07M | if (decl->preconcurrency()) { |
3385 | 20.7k | ty = ty->stripConcurrency(/*recurse=*/true, /*dropGlobalActor=*/true); |
3386 | 20.7k | } |
3387 | | |
3388 | 3.07M | auto canTy = ty->getCanonicalType(); |
3389 | | |
3390 | 3.07M | if (auto gft = dyn_cast<GenericFunctionType>(canTy)) { |
3391 | 1.28M | genericSig = gft.getGenericSignature(); |
3392 | | |
3393 | 1.28M | canTy = CanFunctionType::get(gft.getParams(), gft.getResult(), |
3394 | 1.28M | gft->getExtInfo()); |
3395 | 1.28M | } |
3396 | | |
3397 | 3.07M | if (!canTy->hasError()) { |
3398 | | // Shed the 'self' type and generic requirements from method manglings. |
3399 | 3.07M | if (isMethodDecl(decl)) { |
3400 | | // Drop the Self argument clause from the type. |
3401 | 1.68M | canTy = cast<AnyFunctionType>(canTy).getResult(); |
3402 | 1.68M | } |
3403 | | |
3404 | 3.07M | if (isMethodDecl(decl) || isa<SubscriptDecl>(decl)) |
3405 | 1.77M | parentGenericSig = decl->getDeclContext()->getGenericSignatureOfContext(); |
3406 | 3.07M | } |
3407 | | |
3408 | 3.07M | return canTy; |
3409 | 3.07M | } |
3410 | | |
3411 | | void ASTMangler::appendDeclType(const ValueDecl *decl, |
3412 | 3.07M | FunctionManglingKind functionMangling) { |
3413 | 3.07M | Mod = decl->getModuleContext(); |
3414 | 3.07M | GenericSignature genericSig; |
3415 | 3.07M | GenericSignature parentGenericSig; |
3416 | 3.07M | auto type = getDeclTypeForMangling(decl, genericSig, parentGenericSig); |
3417 | | |
3418 | 3.07M | auto sig = (genericSig |
3419 | 3.07M | ? genericSig |
3420 | 3.07M | : decl->getDeclContext()->getGenericSignatureOfContext()); |
3421 | | |
3422 | 3.07M | if (AnyFunctionType *FuncTy = type->getAs<AnyFunctionType>()) { |
3423 | 2.16M | appendFunction(FuncTy, sig, functionMangling, decl); |
3424 | 2.16M | } else { |
3425 | 914k | appendType(type, sig, decl); |
3426 | 914k | } |
3427 | | |
3428 | | // Mangle the generic signature, if any. |
3429 | 3.07M | if (genericSig && appendGenericSignature(genericSig, parentGenericSig)) { |
3430 | | // The 'F' function mangling doesn't need a 'u' for its generic signature. |
3431 | 420k | if (functionMangling == NoFunctionMangling) |
3432 | 40.0k | appendOperator("u"); |
3433 | 420k | } |
3434 | 3.07M | } |
3435 | | |
3436 | 18.3M | bool ASTMangler::tryAppendStandardSubstitution(const GenericTypeDecl *decl) { |
3437 | | // Bail out if our parent isn't the swift standard library. |
3438 | 18.3M | auto dc = decl->getDeclContext(); |
3439 | 18.3M | if (!dc->isModuleScopeContext() || |
3440 | 18.3M | !dc->getParentModule()->hasStandardSubstitutions()) |
3441 | 10.2M | return false; |
3442 | | |
3443 | 8.09M | if (!AllowStandardSubstitutions) |
3444 | 0 | return false; |
3445 | | |
3446 | 8.09M | if (isa<NominalTypeDecl>(decl)) { |
3447 | 8.08M | if (auto Subst = getStandardTypeSubst( |
3448 | 8.08M | decl->getName().str(), AllowConcurrencyStandardSubstitutions)) { |
3449 | 4.96M | if (!SubstMerging.tryMergeSubst(*this, *Subst, /*isStandardSubst*/ true)){ |
3450 | 4.72M | appendOperator("S", *Subst); |
3451 | 4.72M | } |
3452 | 4.96M | return true; |
3453 | 4.96M | } |
3454 | 8.08M | } |
3455 | 3.13M | return false; |
3456 | 8.09M | } |
3457 | | |
3458 | | void ASTMangler::appendConstructorEntity(const ConstructorDecl *ctor, |
3459 | 366k | bool isAllocating) { |
3460 | 366k | appendContextOf(ctor); |
3461 | 366k | appendDeclType(ctor); |
3462 | 366k | StringRef privateDiscriminator = getPrivateDiscriminatorIfNecessary(ctor); |
3463 | 366k | if (!privateDiscriminator.empty()) { |
3464 | 1.81k | appendIdentifier(privateDiscriminator); |
3465 | 1.81k | appendOperator("Ll"); |
3466 | 1.81k | } |
3467 | 366k | appendOperator(isAllocating ? "fC" : "fc"); |
3468 | 366k | } |
3469 | | |
3470 | | void ASTMangler::appendDestructorEntity(const DestructorDecl *dtor, |
3471 | 738k | bool isDeallocating) { |
3472 | 738k | appendContextOf(dtor); |
3473 | 738k | appendOperator(isDeallocating ? "fD" : "fd"); |
3474 | 738k | } |
3475 | | |
3476 | | void ASTMangler::appendAccessorEntity(StringRef accessorKindCode, |
3477 | | const AbstractStorageDecl *decl, |
3478 | 976k | bool isStatic) { |
3479 | 976k | appendContextOf(decl); |
3480 | 976k | if (auto *varDecl = dyn_cast<VarDecl>(decl)) { |
3481 | 889k | appendDeclName(decl); |
3482 | 889k | appendDeclType(decl); |
3483 | 889k | appendOperator("v", accessorKindCode); |
3484 | 889k | } else if (auto *subscriptDecl = dyn_cast<SubscriptDecl>(decl)) { |
3485 | 86.2k | appendDeclType(decl); |
3486 | | |
3487 | 86.2k | StringRef privateDiscriminator = getPrivateDiscriminatorIfNecessary(decl); |
3488 | 86.2k | if (!privateDiscriminator.empty()) { |
3489 | 453 | appendIdentifier(privateDiscriminator); |
3490 | 453 | appendOperator("Ll"); |
3491 | 453 | } |
3492 | | |
3493 | 86.2k | appendOperator("i", accessorKindCode); |
3494 | 86.2k | } else { |
3495 | 0 | llvm_unreachable("Unknown type of AbstractStorageDecl"); |
3496 | 0 | } |
3497 | 976k | if (isStatic) |
3498 | 134k | appendOperator("Z"); |
3499 | 976k | } |
3500 | | |
3501 | | void ASTMangler::appendEntity(const ValueDecl *decl, StringRef EntityOp, |
3502 | 35.9k | bool isStatic) { |
3503 | 35.9k | appendContextOf(decl); |
3504 | 35.9k | appendDeclName(decl); |
3505 | 35.9k | appendDeclType(decl); |
3506 | 35.9k | appendOperator(EntityOp); |
3507 | 35.9k | if (isStatic) |
3508 | 24 | appendOperator("Z"); |
3509 | 35.9k | } |
3510 | | |
3511 | 2.64M | void ASTMangler::appendEntity(const ValueDecl *decl) { |
3512 | 2.64M | assert(!isa<ConstructorDecl>(decl)); |
3513 | 0 | assert(!isa<DestructorDecl>(decl)); |
3514 | | |
3515 | | // Handle accessors specially, they are mangled as modifiers on the accessed |
3516 | | // declaration. |
3517 | 2.64M | if (auto accessor = dyn_cast<AccessorDecl>(decl)) { |
3518 | 645k | return appendAccessorEntity( |
3519 | 645k | getCodeForAccessorKind(accessor->getAccessorKind()), |
3520 | 645k | accessor->getStorage(), accessor->isStatic()); |
3521 | 645k | } |
3522 | | |
3523 | 2.00M | if (auto storageDecl = dyn_cast<AbstractStorageDecl>(decl)) |
3524 | 300k | return appendAccessorEntity("p", storageDecl, decl->isStatic()); |
3525 | 1.70M | if (isa<GenericTypeParamDecl>(decl)) |
3526 | 117 | return appendEntity(decl, "fp", decl->isStatic()); |
3527 | 1.70M | if (auto macro = dyn_cast<MacroDecl>(decl)) |
3528 | 1.68k | return appendEntity(decl, "fm", false); |
3529 | 1.69M | if (auto expansion = dyn_cast<MacroExpansionDecl>(decl)) { |
3530 | 0 | appendMacroExpansionContext( |
3531 | 0 | expansion->getLoc(), expansion->getDeclContext()); |
3532 | 0 | appendMacroExpansionOperator( |
3533 | 0 | expansion->getMacroName().getBaseName().userFacingName(), |
3534 | 0 | MacroRole::Declaration, |
3535 | 0 | expansion->getDiscriminator()); |
3536 | 0 | return; |
3537 | 0 | } |
3538 | | |
3539 | 1.69M | assert(isa<AbstractFunctionDecl>(decl) || isa<EnumElementDecl>(decl)); |
3540 | | |
3541 | 0 | appendContextOf(decl); |
3542 | 1.69M | appendDeclName(decl); |
3543 | 1.69M | appendDeclType(decl, FunctionMangling); |
3544 | 1.69M | appendOperator("F"); |
3545 | 1.69M | if (decl->isStatic()) |
3546 | 474k | appendOperator("Z"); |
3547 | 1.69M | } |
3548 | | |
3549 | | void |
3550 | 1.19M | ASTMangler::appendProtocolConformance(const ProtocolConformance *conformance) { |
3551 | 1.19M | auto topLevelSubcontext = |
3552 | 1.19M | conformance->getDeclContext()->getModuleScopeContext(); |
3553 | 1.19M | Mod = topLevelSubcontext->getParentModule(); |
3554 | | |
3555 | 1.19M | auto conformingType = conformance->getType(); |
3556 | 1.19M | appendType(conformingType->getCanonicalType(), nullptr); |
3557 | | |
3558 | 1.19M | appendProtocolName(conformance->getProtocol()); |
3559 | | |
3560 | 1.19M | bool needsModule = true; |
3561 | 1.19M | if (auto *file = dyn_cast<FileUnit>(topLevelSubcontext)) { |
3562 | 1.19M | if (file->getKind() == FileUnitKind::ClangModule || |
3563 | 1.19M | file->getKind() == FileUnitKind::DWARFModule) { |
3564 | 50.3k | if (conformance->getProtocol()->hasClangNode()) |
3565 | 6 | appendOperator("So"); |
3566 | 50.3k | else |
3567 | 50.3k | appendOperator("SC"); |
3568 | 50.3k | needsModule = false; |
3569 | 50.3k | } |
3570 | 1.19M | } |
3571 | 1.19M | if (needsModule) { |
3572 | 1.13M | auto *DC = conformance->getDeclContext(); |
3573 | 1.13M | assert(DC->getAsDecl()); |
3574 | 0 | appendModule(Mod, DC->getAsDecl()->getAlternateModuleName()); |
3575 | 1.13M | } |
3576 | | |
3577 | | // If this is a non-nominal type, we're done. |
3578 | 1.19M | if (!conformingType->getAnyNominal()) |
3579 | 48 | return; |
3580 | | |
3581 | 1.19M | auto contextSig = |
3582 | 1.19M | conformingType->getAnyNominal()->getGenericSignatureOfContext(); |
3583 | | |
3584 | 1.19M | if (GenericSignature Sig = conformance->getGenericSignature()) { |
3585 | 141k | appendGenericSignature(Sig, contextSig); |
3586 | 141k | } |
3587 | 1.19M | } |
3588 | | |
3589 | | void ASTMangler::appendProtocolConformanceRef( |
3590 | 1.09k | const RootProtocolConformance *conformance) { |
3591 | | // FIXME: Symbolic reference to the protocol conformance descriptor. |
3592 | 1.09k | appendProtocolName(conformance->getProtocol()); |
3593 | | |
3594 | | // For retroactive conformances, add a reference to the module in which the |
3595 | | // conformance resides. Otherwise, use an operator to indicate which known |
3596 | | // module it's associated with. |
3597 | 1.09k | if (!conformanceHasIdentity(conformance)) { |
3598 | | // Same as "conformance module matches type", below. |
3599 | 0 | appendOperator("HP"); |
3600 | 1.09k | } else if (isRetroactiveConformance(conformance)) { |
3601 | 306 | auto *DC = conformance->getDeclContext(); |
3602 | 306 | assert(DC->getAsDecl()); |
3603 | 0 | appendModule(conformance->getDeclContext()->getParentModule(), |
3604 | 306 | DC->getAsDecl()->getAlternateModuleName()); |
3605 | | // Builtin conformances are always from the Swift module. |
3606 | 792 | } else if (isa<BuiltinProtocolConformance>(conformance)) { |
3607 | 0 | appendOperator("HP"); |
3608 | 792 | } else if (conformance->getDeclContext()->getParentModule() == |
3609 | 792 | conformance->getType()->getAnyNominal()->getParentModule()) { |
3610 | 609 | appendOperator("HP"); |
3611 | 609 | } else { |
3612 | 183 | appendOperator("Hp"); |
3613 | 183 | } |
3614 | 1.09k | } |
3615 | | |
3616 | | /// Retrieve the index of the conformance requirement indicated by the |
3617 | | /// conformance path entry within the given set of requirements. |
3618 | | static unsigned conformanceRequirementIndex( |
3619 | | const ConformancePath::Entry &entry, |
3620 | 216 | ArrayRef<Requirement> requirements) { |
3621 | 216 | unsigned result = 0; |
3622 | 327 | for (const auto &req : requirements) { |
3623 | 327 | if (req.getKind() != RequirementKind::Conformance) |
3624 | 33 | continue; |
3625 | | |
3626 | 294 | if (req.getFirstType()->isEqual(entry.first) && |
3627 | 294 | req.getProtocolDecl() == entry.second) |
3628 | 216 | return result; |
3629 | | |
3630 | 78 | ++result; |
3631 | 78 | } |
3632 | | |
3633 | 0 | llvm_unreachable("Conformance access path step is missing from requirements"); |
3634 | 0 | } |
3635 | | |
3636 | | void ASTMangler::appendDependentProtocolConformance( |
3637 | | const ConformancePath &path, |
3638 | 189 | GenericSignature sig) { |
3639 | 189 | ProtocolDecl *currentProtocol = nullptr; |
3640 | 216 | for (const auto &entry : path) { |
3641 | | // After each step, update the current protocol to refer to where we |
3642 | | // are. |
3643 | 216 | SWIFT_DEFER { |
3644 | 216 | currentProtocol = entry.second; |
3645 | 216 | sig = currentProtocol->getGenericSignature(); |
3646 | 216 | }; |
3647 | | |
3648 | | // The first entry is the "root". Find this requirement in the generic |
3649 | | // signature. |
3650 | 216 | if (!currentProtocol) { |
3651 | 189 | appendType(entry.first, sig); |
3652 | 189 | appendProtocolName(entry.second); |
3653 | 189 | auto index = |
3654 | 189 | conformanceRequirementIndex(entry, |
3655 | 189 | sig.getRequirements()); |
3656 | | // This is never an unknown index and so must be adjusted by 2 per ABI. |
3657 | 189 | appendOperator("HD", Index(index + 2)); |
3658 | 189 | continue; |
3659 | 189 | } |
3660 | | |
3661 | | // Conformances are relative to the current protocol's requirement |
3662 | | // signature. |
3663 | 27 | auto reqs = currentProtocol->getRequirementSignature().getRequirements(); |
3664 | 27 | auto index = conformanceRequirementIndex(entry, reqs); |
3665 | | |
3666 | | // Inherited conformance. |
3667 | 27 | bool isInheritedConformance = |
3668 | 27 | entry.first->isEqual(currentProtocol->getSelfInterfaceType()); |
3669 | 27 | if (isInheritedConformance) { |
3670 | 3 | appendProtocolName(entry.second); |
3671 | | // For now, this is never an unknown index and so must be adjusted by 2. |
3672 | 3 | appendOperator("HI", Index(index + 2)); |
3673 | 3 | continue; |
3674 | 3 | } |
3675 | | |
3676 | | // Associated conformance. |
3677 | | // FIXME: Symbolic reference. |
3678 | 24 | appendType(entry.first, sig); |
3679 | 24 | appendProtocolName(entry.second); |
3680 | | |
3681 | | // For resilient protocols, the index is unknown, so we use the special |
3682 | | // value 1; otherwise we adjust by 2. |
3683 | 24 | bool isResilient = |
3684 | 24 | currentProtocol->isResilient(Mod, ResilienceExpansion::Maximal); |
3685 | 24 | appendOperator("HA", Index(isResilient ? 1 : index + 2)); |
3686 | 24 | } |
3687 | 189 | } |
3688 | | |
3689 | | void ASTMangler::appendAnyProtocolConformance( |
3690 | | GenericSignature genericSig, |
3691 | | CanType conformingType, |
3692 | 984 | ProtocolConformanceRef conformance) { |
3693 | | // If we have a conformance to a marker protocol but we aren't allowed to |
3694 | | // emit marker protocols, skip it. |
3695 | 984 | if (!AllowMarkerProtocols && |
3696 | 984 | conformance.getRequirement()->isMarkerProtocol()) |
3697 | 0 | return; |
3698 | | |
3699 | 984 | if (conformingType->isTypeParameter()) { |
3700 | 126 | assert(genericSig && "Need a generic signature to resolve conformance"); |
3701 | 0 | auto path = genericSig->getConformancePath(conformingType, |
3702 | 126 | conformance.getAbstract()); |
3703 | 126 | appendDependentProtocolConformance(path, genericSig); |
3704 | 858 | } else if (auto opaqueType = conformingType->getAs<OpaqueTypeArchetypeType>()) { |
3705 | 63 | GenericSignature opaqueSignature = |
3706 | 63 | opaqueType->getDecl()->getOpaqueInterfaceGenericSignature(); |
3707 | 63 | ConformancePath conformancePath = |
3708 | 63 | opaqueSignature->getConformancePath( |
3709 | 63 | opaqueType->getInterfaceType(), |
3710 | 63 | conformance.getAbstract()); |
3711 | | |
3712 | | // Append the conformance path with the signature of the opaque type. |
3713 | 63 | appendDependentProtocolConformance(conformancePath, opaqueSignature); |
3714 | 63 | appendType(conformingType, genericSig); |
3715 | 63 | appendOperator("HO"); |
3716 | 795 | } else { |
3717 | 795 | appendConcreteProtocolConformance(conformance.getConcrete(), genericSig); |
3718 | 795 | } |
3719 | 984 | } |
3720 | | |
3721 | | void ASTMangler::appendConcreteProtocolConformance( |
3722 | | const ProtocolConformance *conformance, |
3723 | 1.09k | GenericSignature sig) { |
3724 | 1.09k | auto module = conformance->getDeclContext()->getParentModule(); |
3725 | | |
3726 | | // Conforming type. |
3727 | 1.09k | Type conformingType = conformance->getType(); |
3728 | 1.09k | if (conformingType->hasArchetype()) |
3729 | 0 | conformingType = conformingType->mapTypeOutOfContext(); |
3730 | 1.09k | appendType(conformingType->getCanonicalType(), sig); |
3731 | | |
3732 | | // Protocol conformance reference. |
3733 | 1.09k | appendProtocolConformanceRef(conformance->getRootConformance()); |
3734 | | |
3735 | | // Conditional conformance requirements. |
3736 | 1.09k | bool firstRequirement = true; |
3737 | 1.09k | for (const auto &conditionalReq : conformance->getConditionalRequirements()) { |
3738 | 135 | switch (conditionalReq.getKind()) { |
3739 | 0 | case RequirementKind::SameShape: |
3740 | 0 | llvm_unreachable("Same-shape requirement not supported here"); |
3741 | 0 | case RequirementKind::Layout: |
3742 | 21 | case RequirementKind::SameType: |
3743 | 21 | case RequirementKind::Superclass: |
3744 | 21 | continue; |
3745 | | |
3746 | 114 | case RequirementKind::Conformance: { |
3747 | 114 | auto type = conditionalReq.getFirstType(); |
3748 | 114 | if (type->hasArchetype()) |
3749 | 0 | type = type->mapTypeOutOfContext(); |
3750 | 114 | CanType canType = type->getReducedType(sig); |
3751 | 114 | auto proto = conditionalReq.getProtocolDecl(); |
3752 | | |
3753 | 114 | ProtocolConformanceRef conformance; |
3754 | | |
3755 | 114 | if (canType->isTypeParameter() || canType->is<OpaqueTypeArchetypeType>()){ |
3756 | 84 | conformance = ProtocolConformanceRef(proto); |
3757 | 84 | } else { |
3758 | 30 | conformance = module->lookupConformance(canType, proto); |
3759 | 30 | } |
3760 | 114 | appendAnyProtocolConformance(sig, canType, conformance); |
3761 | 114 | appendListSeparator(firstRequirement); |
3762 | 114 | break; |
3763 | 21 | } |
3764 | 135 | } |
3765 | 135 | } |
3766 | 1.09k | if (firstRequirement) |
3767 | 993 | appendOperator("y"); |
3768 | | |
3769 | 1.09k | appendOperator("HC"); |
3770 | 1.09k | } |
3771 | | |
3772 | 2.06k | void ASTMangler::appendOpParamForLayoutConstraint(LayoutConstraint layout) { |
3773 | 2.06k | assert(layout); |
3774 | 0 | switch (layout->getKind()) { |
3775 | 0 | case LayoutConstraintKind::UnknownLayout: |
3776 | 0 | appendOperatorParam("U"); |
3777 | 0 | break; |
3778 | 18 | case LayoutConstraintKind::RefCountedObject: |
3779 | 18 | appendOperatorParam("R"); |
3780 | 18 | break; |
3781 | 0 | case LayoutConstraintKind::NativeRefCountedObject: |
3782 | 0 | appendOperatorParam("N"); |
3783 | 0 | break; |
3784 | 1.97k | case LayoutConstraintKind::Class: |
3785 | 1.97k | appendOperatorParam("C"); |
3786 | 1.97k | break; |
3787 | 0 | case LayoutConstraintKind::NativeClass: |
3788 | 0 | appendOperatorParam("D"); |
3789 | 0 | break; |
3790 | 18 | case LayoutConstraintKind::Trivial: |
3791 | 18 | appendOperatorParam("T"); |
3792 | 18 | break; |
3793 | 54 | case LayoutConstraintKind::TrivialOfExactSize: |
3794 | 54 | if (!layout->getAlignmentInBits()) |
3795 | 36 | appendOperatorParam("e", Index(layout->getTrivialSizeInBits())); |
3796 | 18 | else |
3797 | 18 | appendOperatorParam("E", Index(layout->getTrivialSizeInBits()), |
3798 | 18 | Index(layout->getAlignmentInBits())); |
3799 | 54 | break; |
3800 | 0 | case LayoutConstraintKind::TrivialOfAtMostSize: |
3801 | 0 | if (!layout->getAlignmentInBits()) |
3802 | 0 | appendOperatorParam("m", Index(layout->getTrivialSizeInBits())); |
3803 | 0 | else |
3804 | 0 | appendOperatorParam("M", Index(layout->getTrivialSizeInBits()), |
3805 | 0 | Index(layout->getAlignmentInBits())); |
3806 | 0 | break; |
3807 | 2.06k | } |
3808 | 2.06k | } |
3809 | | |
3810 | 1.82k | std::string ASTMangler::mangleOpaqueTypeDescriptor(const OpaqueTypeDecl *decl) { |
3811 | 1.82k | beginMangling(); |
3812 | 1.82k | appendOpaqueDeclName(decl); |
3813 | 1.82k | appendOperator("MQ"); |
3814 | 1.82k | return finalize(); |
3815 | 1.82k | } |
3816 | | |
3817 | | std::string |
3818 | 42 | ASTMangler::mangleOpaqueTypeDescriptorRecord(const OpaqueTypeDecl *decl) { |
3819 | 42 | beginMangling(); |
3820 | 42 | appendOpaqueDeclName(decl); |
3821 | 42 | appendOperator("Ho"); |
3822 | 42 | return finalize(); |
3823 | 42 | } |
3824 | | |
3825 | 984 | std::string ASTMangler::mangleDistributedThunk(const AbstractFunctionDecl *thunk) { |
3826 | | // Marker protocols cannot be checked at runtime, so there is no point |
3827 | | // in recording them for distributed thunks. |
3828 | 984 | llvm::SaveAndRestore<bool> savedAllowMarkerProtocols(AllowMarkerProtocols, |
3829 | 984 | false); |
3830 | | |
3831 | | // Since computed property SILDeclRef's refer to the "originator" |
3832 | | // of the thunk, we need to mangle distributed thunks of accessors |
3833 | | // specially. |
3834 | 984 | if (auto *accessor = dyn_cast<AccessorDecl>(thunk)) { |
3835 | | // TODO: This needs to use accessor type instead of |
3836 | | // distributed thunk after all SILDeclRefs are switched |
3837 | | // to use "originator" instead of the thunk itself. |
3838 | | // |
3839 | | // ``` |
3840 | | // beginMangling(); |
3841 | | // appendContextOf(thunk); |
3842 | | // appendDeclName(accessor->getStorage()); |
3843 | | // appendDeclType(accessor, FunctionMangling); |
3844 | | // appendOperator("F"); |
3845 | | // appendSymbolKind(SymbolKind::DistributedThunk); |
3846 | | // return finalize(); |
3847 | | // ``` |
3848 | 3 | auto *storage = accessor->getStorage(); |
3849 | 3 | thunk = storage->getDistributedThunk(); |
3850 | 3 | assert(thunk); |
3851 | 3 | } |
3852 | | |
3853 | 0 | return mangleEntity(thunk, SymbolKind::DistributedThunk); |
3854 | 984 | } |
3855 | | |
3856 | | void ASTMangler::appendMacroExpansionContext( |
3857 | | SourceLoc loc, DeclContext *origDC |
3858 | 9.84k | ) { |
3859 | 9.84k | origDC = MacroDiscriminatorContext::getInnermostMacroContext(origDC); |
3860 | | |
3861 | 9.84k | if (loc.isInvalid()) |
3862 | 0 | return appendContext(origDC, StringRef()); |
3863 | | |
3864 | 9.84k | ASTContext &ctx = origDC->getASTContext(); |
3865 | 9.84k | SourceManager &sourceMgr = ctx.SourceMgr; |
3866 | | |
3867 | 9.84k | auto bufferID = sourceMgr.findBufferContainingLoc(loc); |
3868 | 9.84k | auto generatedSourceInfo = sourceMgr.getGeneratedSourceInfo(bufferID); |
3869 | 9.84k | if (!generatedSourceInfo) |
3870 | 9.46k | return appendContext(origDC, StringRef()); |
3871 | | |
3872 | 381 | SourceLoc outerExpansionLoc; |
3873 | 381 | DeclContext *outerExpansionDC; |
3874 | 381 | DeclBaseName baseName; |
3875 | 381 | unsigned discriminator; |
3876 | | |
3877 | | // Determine the macro role. |
3878 | 381 | MacroRole role; |
3879 | 381 | switch (generatedSourceInfo->kind) { |
3880 | 0 | #define MACRO_ROLE(Name, Description) \ |
3881 | 381 | case GeneratedSourceInfo::Name##MacroExpansion: \ |
3882 | 381 | role = MacroRole::Name; \ |
3883 | 381 | break; |
3884 | 0 | #include "swift/Basic/MacroRoles.def" |
3885 | | |
3886 | 0 | case GeneratedSourceInfo::PrettyPrinted: |
3887 | 0 | case GeneratedSourceInfo::ReplacedFunctionBody: |
3888 | 0 | return appendContext(origDC, StringRef()); |
3889 | 381 | } |
3890 | | |
3891 | 381 | switch (generatedSourceInfo->kind) { |
3892 | | // Freestanding macros |
3893 | 0 | #define FREESTANDING_MACRO_ROLE(Name, Description) \ |
3894 | 1.13k | case GeneratedSourceInfo::Name##MacroExpansion: |
3895 | 0 | #define ATTACHED_MACRO_ROLE(Name, Description) |
3896 | 381 | #include "swift/Basic/MacroRoles.def" |
3897 | 381 | { |
3898 | 381 | auto parent = ASTNode::getFromOpaqueValue(generatedSourceInfo->astNode); |
3899 | 381 | if (auto expr = |
3900 | 381 | cast_or_null<MacroExpansionExpr>(parent.dyn_cast<Expr *>())) { |
3901 | 372 | outerExpansionLoc = expr->getLoc(); |
3902 | 372 | baseName = expr->getMacroName().getBaseName(); |
3903 | 372 | discriminator = expr->getDiscriminator(); |
3904 | 372 | outerExpansionDC = expr->getDeclContext(); |
3905 | 372 | } else { |
3906 | 9 | auto decl = cast<MacroExpansionDecl>(parent.get<Decl *>()); |
3907 | 9 | outerExpansionLoc = decl->getLoc(); |
3908 | 9 | baseName = decl->getMacroName().getBaseName(); |
3909 | 9 | discriminator = decl->getDiscriminator(); |
3910 | 9 | outerExpansionDC = decl->getDeclContext(); |
3911 | 9 | } |
3912 | 381 | break; |
3913 | 753 | } |
3914 | | |
3915 | | // Attached macros |
3916 | 0 | #define FREESTANDING_MACRO_ROLE(Name, Description) |
3917 | 0 | #define ATTACHED_MACRO_ROLE(Name, Description) \ |
3918 | 0 | case GeneratedSourceInfo::Name##MacroExpansion: |
3919 | 381 | #include "swift/Basic/MacroRoles.def" |
3920 | 0 | { |
3921 | 0 | auto decl = ASTNode::getFromOpaqueValue(generatedSourceInfo->astNode) |
3922 | 0 | .get<Decl *>(); |
3923 | 0 | auto attr = generatedSourceInfo->attachedMacroCustomAttr; |
3924 | 0 | outerExpansionLoc = decl->getLoc(); |
3925 | 0 | outerExpansionDC = decl->getDeclContext(); |
3926 | |
|
3927 | 0 | if (auto *macroDecl = decl->getResolvedMacro(attr)) |
3928 | 0 | baseName = macroDecl->getBaseName(); |
3929 | 0 | else |
3930 | 0 | baseName = ctx.getIdentifier("__unknown_macro__"); |
3931 | |
|
3932 | 0 | discriminator = decl->getAttachedMacroDiscriminator(baseName, role, attr); |
3933 | 0 | break; |
3934 | 0 | } |
3935 | | |
3936 | 0 | case GeneratedSourceInfo::PrettyPrinted: |
3937 | 0 | case GeneratedSourceInfo::ReplacedFunctionBody: |
3938 | 0 | llvm_unreachable("Exited above"); |
3939 | 381 | } |
3940 | | |
3941 | | // If we hit the point where the structure is represented as a DeclContext, |
3942 | | // we're done. |
3943 | 381 | if (origDC->isChildContextOf(outerExpansionDC)) |
3944 | 81 | return appendContext(origDC, StringRef()); |
3945 | | |
3946 | | // Append our own context and discriminator. |
3947 | 300 | appendMacroExpansionContext(outerExpansionLoc, origDC); |
3948 | 300 | appendMacroExpansionOperator( |
3949 | 300 | baseName.userFacingName(), role, discriminator); |
3950 | 300 | } |
3951 | | |
3952 | | void ASTMangler::appendMacroExpansionOperator( |
3953 | | StringRef macroName, MacroRole role, unsigned discriminator |
3954 | 12.0k | ) { |
3955 | 12.0k | appendIdentifier(macroName); |
3956 | | |
3957 | 12.0k | switch (role) { |
3958 | 19.9k | #define FREESTANDING_MACRO_ROLE(Name, Description) case MacroRole::Name: |
3959 | 0 | #define ATTACHED_MACRO_ROLE(Name, Description) |
3960 | 9.84k | #include "swift/Basic/MacroRoles.def" |
3961 | 9.84k | appendOperator("fMf", Index(discriminator)); |
3962 | 9.84k | break; |
3963 | | |
3964 | 582 | case MacroRole::Accessor: |
3965 | 582 | appendOperator("fMa", Index(discriminator)); |
3966 | 582 | break; |
3967 | | |
3968 | 342 | case MacroRole::MemberAttribute: |
3969 | 342 | appendOperator("fMr", Index(discriminator)); |
3970 | 342 | break; |
3971 | | |
3972 | 360 | case MacroRole::Member: |
3973 | 360 | appendOperator("fMm", Index(discriminator)); |
3974 | 360 | break; |
3975 | | |
3976 | 393 | case MacroRole::Peer: |
3977 | 393 | appendOperator("fMp", Index(discriminator)); |
3978 | 393 | break; |
3979 | | |
3980 | 6 | case MacroRole::Conformance: |
3981 | 6 | appendOperator("fMc", Index(discriminator)); |
3982 | 6 | break; |
3983 | | |
3984 | 522 | case MacroRole::Extension: |
3985 | 522 | appendOperator("fMe", Index(discriminator)); |
3986 | 522 | break; |
3987 | 12.0k | } |
3988 | 12.0k | } |
3989 | | |
3990 | | static StringRef getPrivateDiscriminatorIfNecessary( |
3991 | 4.54k | const MacroExpansionExpr *expansion) { |
3992 | 4.54k | auto dc = MacroDiscriminatorContext::getInnermostMacroContext( |
3993 | 4.54k | expansion->getDeclContext()); |
3994 | 4.54k | auto decl = dc->getAsDecl(); |
3995 | 4.54k | if (decl && !decl->isOutermostPrivateOrFilePrivateScope()) |
3996 | 3.88k | return StringRef(); |
3997 | | |
3998 | | // Mangle non-local private declarations with a textual discriminator |
3999 | | // based on their enclosing file. |
4000 | 660 | auto topLevelSubcontext = dc->getModuleScopeContext(); |
4001 | 660 | SourceFile *sf = dyn_cast<SourceFile>(topLevelSubcontext); |
4002 | 660 | if (!sf) |
4003 | 0 | return StringRef(); |
4004 | | |
4005 | 660 | Identifier discriminator = |
4006 | 660 | sf->getPrivateDiscriminator(/*createIfMissing=*/true); |
4007 | 660 | assert(!discriminator.empty()); |
4008 | 0 | assert(!isNonAscii(discriminator.str()) && |
4009 | 660 | "discriminator contains non-ASCII characters"); |
4010 | 0 | (void)&isNonAscii; |
4011 | 660 | assert(!clang::isDigit(discriminator.str().front()) && |
4012 | 660 | "not a valid identifier"); |
4013 | 0 | return discriminator.str(); |
4014 | 660 | } |
4015 | | |
4016 | | static StringRef getPrivateDiscriminatorIfNecessary( |
4017 | 9.54k | const FreestandingMacroExpansion *expansion) { |
4018 | 9.54k | switch (expansion->getFreestandingMacroKind()) { |
4019 | 4.54k | case FreestandingMacroKind::Expr: |
4020 | 4.54k | return getPrivateDiscriminatorIfNecessary( |
4021 | 4.54k | cast<MacroExpansionExpr>(expansion)); |
4022 | 5.00k | case FreestandingMacroKind::Decl: |
4023 | 5.00k | return getPrivateDiscriminatorIfNecessary( |
4024 | 5.00k | cast<Decl>(cast<MacroExpansionDecl>(expansion))); |
4025 | 9.54k | } |
4026 | 9.54k | } |
4027 | | |
4028 | | std::string |
4029 | 9.54k | ASTMangler::mangleMacroExpansion(const FreestandingMacroExpansion *expansion) { |
4030 | 9.54k | beginMangling(); |
4031 | 9.54k | appendMacroExpansionContext(expansion->getPoundLoc(), |
4032 | 9.54k | expansion->getDeclContext()); |
4033 | 9.54k | auto privateDiscriminator = getPrivateDiscriminatorIfNecessary(expansion); |
4034 | 9.54k | if (!privateDiscriminator.empty()) { |
4035 | 3.46k | appendIdentifier(privateDiscriminator); |
4036 | 3.46k | appendOperator("Ll"); |
4037 | 3.46k | } |
4038 | 9.54k | appendMacroExpansionOperator( |
4039 | 9.54k | expansion->getMacroName().getBaseName().userFacingName(), |
4040 | 9.54k | MacroRole::Declaration, |
4041 | 9.54k | expansion->getDiscriminator()); |
4042 | 9.54k | return finalize(); |
4043 | 9.54k | } |
4044 | | |
4045 | | std::string ASTMangler::mangleAttachedMacroExpansion( |
4046 | 2.20k | const Decl *decl, CustomAttr *attr, MacroRole role) { |
4047 | 2.20k | beginMangling(); |
4048 | | |
4049 | | // Append the context and name of the declaration. |
4050 | | // We don't mangle the declaration itself because doing so requires semantic |
4051 | | // information (e.g., its interface type), which introduces cyclic |
4052 | | // dependencies. |
4053 | 2.20k | const Decl *attachedTo = decl; |
4054 | 2.20k | DeclBaseName attachedToName; |
4055 | 2.20k | if (auto accessor = dyn_cast<AccessorDecl>(decl)) { |
4056 | 30 | auto storage = accessor->getStorage(); |
4057 | 30 | appendContextOf(storage); |
4058 | | |
4059 | | // Introduce an identifier mangling that includes var/subscript, accessor |
4060 | | // kind, and static. |
4061 | | // FIXME: THIS IS A HACK. We need something different. |
4062 | 30 | { |
4063 | 30 | llvm::SmallString<16> name; |
4064 | 30 | { |
4065 | 30 | llvm::raw_svector_ostream out(name); |
4066 | 30 | out << storage->getName().getBaseName().userFacingName() |
4067 | 30 | << "__"; |
4068 | 30 | if (isa<VarDecl>(storage)) { |
4069 | 30 | out << "v"; |
4070 | 30 | } else { |
4071 | 0 | assert(isa<SubscriptDecl>(storage)); |
4072 | 0 | out << "i"; |
4073 | 0 | } |
4074 | | |
4075 | 0 | out << getCodeForAccessorKind(accessor->getAccessorKind()); |
4076 | 30 | if (storage->isStatic()) |
4077 | 0 | out << "Z"; |
4078 | 30 | } |
4079 | | |
4080 | 0 | attachedToName = decl->getASTContext().getIdentifier(name); |
4081 | 30 | } |
4082 | | |
4083 | 0 | appendDeclName(storage, attachedToName); |
4084 | | |
4085 | | // For member attribute macros, the attribute is attached to the enclosing |
4086 | | // declaration. |
4087 | 30 | if (role == MacroRole::MemberAttribute) { |
4088 | 30 | attachedTo = storage->getDeclContext()->getAsDecl(); |
4089 | 30 | } |
4090 | 2.17k | } else if (auto valueDecl = dyn_cast<ValueDecl>(decl)) { |
4091 | 2.16k | appendContextOf(valueDecl); |
4092 | | |
4093 | | // Mangle the name, replacing special names with their user-facing names. |
4094 | 2.16k | attachedToName = valueDecl->getName().getBaseName(); |
4095 | 2.16k | if (attachedToName.isSpecial()) { |
4096 | 12 | attachedToName = |
4097 | 12 | decl->getASTContext().getIdentifier(attachedToName.userFacingName()); |
4098 | 12 | } |
4099 | 2.16k | appendDeclName(valueDecl, attachedToName); |
4100 | | |
4101 | | // For member attribute macros, the attribute is attached to the enclosing |
4102 | | // declaration. |
4103 | 2.16k | if (role == MacroRole::MemberAttribute) { |
4104 | 312 | attachedTo = decl->getDeclContext()->getAsDecl(); |
4105 | 312 | } |
4106 | 2.16k | } else { |
4107 | 6 | appendContext(decl->getDeclContext(), ""); |
4108 | 6 | appendIdentifier("_"); |
4109 | 6 | } |
4110 | | |
4111 | | // Determine the name of the macro. |
4112 | 0 | DeclBaseName macroName; |
4113 | 2.20k | if (auto *macroDecl = attachedTo->getResolvedMacro(attr)) { |
4114 | 2.20k | macroName = macroDecl->getName().getBaseName(); |
4115 | 2.20k | } else { |
4116 | 0 | macroName = decl->getASTContext().getIdentifier("__unknown_macro__"); |
4117 | 0 | } |
4118 | | |
4119 | | // FIXME: attached macro discriminators should take attachedToName into |
4120 | | // account. |
4121 | 2.20k | appendMacroExpansionOperator( |
4122 | 2.20k | macroName.userFacingName(), role, |
4123 | 2.20k | decl->getAttachedMacroDiscriminator(macroName, role, attr)); |
4124 | 2.20k | return finalize(); |
4125 | 2.20k | } |
4126 | | |
4127 | | static void gatherExistentialRequirements(SmallVectorImpl<Requirement> &reqs, |
4128 | 1.23k | ParameterizedProtocolType *PPT) { |
4129 | 1.23k | auto protoTy = PPT->getBaseType(); |
4130 | 1.23k | PPT->getRequirements(protoTy->getDecl()->getSelfInterfaceType(), reqs); |
4131 | 1.23k | } |
4132 | | |
4133 | | void ASTMangler::appendConstrainedExistential(Type base, GenericSignature sig, |
4134 | 1.23k | const ValueDecl *forDecl) { |
4135 | 1.23k | auto layout = base->getExistentialLayout(); |
4136 | 1.23k | appendExistentialLayout(layout, sig, forDecl); |
4137 | 1.23k | SmallVector<Requirement, 4> requirements; |
4138 | 1.23k | assert(!base->is<ProtocolType>() && |
4139 | 1.23k | "plain protocol type constraint has no generalization structure"); |
4140 | 1.23k | if (auto *PCT = base->getAs<ProtocolCompositionType>()) { |
4141 | 144 | for (auto memberTy : PCT->getMembers()) { |
4142 | 144 | if (auto *PPT = memberTy->getAs<ParameterizedProtocolType>()) |
4143 | 72 | gatherExistentialRequirements(requirements, PPT); |
4144 | 144 | } |
4145 | 1.15k | } else { |
4146 | 1.15k | auto *PPT = base->castTo<ParameterizedProtocolType>(); |
4147 | 1.15k | gatherExistentialRequirements(requirements, PPT); |
4148 | 1.15k | } |
4149 | | |
4150 | 1.23k | assert(!requirements.empty() && "Unconstrained existential?"); |
4151 | | // Sort the requirements to canonicalize their order. |
4152 | 0 | llvm::array_pod_sort( |
4153 | 1.23k | requirements.begin(), requirements.end(), |
4154 | 1.23k | [](const Requirement *lhs, const Requirement *rhs) -> int { |
4155 | 345 | return lhs->compare(*rhs); |
4156 | 345 | }); |
4157 | | |
4158 | 1.23k | bool firstRequirement = true; |
4159 | 1.57k | for (const auto &reqt : requirements) { |
4160 | 1.57k | switch (reqt.getKind()) { |
4161 | 0 | case RequirementKind::SameShape: |
4162 | 0 | llvm_unreachable("Same-shape requirement not supported here"); |
4163 | 0 | case RequirementKind::Layout: |
4164 | 0 | case RequirementKind::Conformance: |
4165 | 0 | case RequirementKind::Superclass: |
4166 | | // The surface language cannot express these requirements yet, so |
4167 | | // we have no mangling for them. |
4168 | 0 | assert(false && "Unexpected requirement in constrained existential!"); |
4169 | 0 | continue; |
4170 | | |
4171 | 1.57k | case RequirementKind::SameType: { |
4172 | 1.57k | break; |
4173 | 0 | } |
4174 | 1.57k | } |
4175 | | |
4176 | 1.57k | appendRequirement(reqt, sig, /*baseIsProtocolSelf*/ true); |
4177 | 1.57k | if (firstRequirement) { |
4178 | 1.23k | appendOperator("_"); |
4179 | 1.23k | firstRequirement = false; |
4180 | 1.23k | } |
4181 | 1.57k | } |
4182 | 1.23k | return appendOperator("XP"); |
4183 | 1.23k | } |