/Volumes/compiler/apple/swift/lib/AST/Attr.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- Attr.cpp - Swift Language Attr ASTs ------------------------------===// |
2 | | // |
3 | | // This source file is part of the Swift.org open source project |
4 | | // |
5 | | // Copyright (c) 2014 - 2017 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 routines relating to declaration attributes. |
14 | | // |
15 | | //===----------------------------------------------------------------------===// |
16 | | |
17 | | #include "swift/AST/Attr.h" |
18 | | #include "swift/AST/ASTContext.h" |
19 | | #include "swift/AST/ASTPrinter.h" |
20 | | #include "swift/AST/Decl.h" |
21 | | #include "swift/AST/Expr.h" |
22 | | #include "swift/AST/GenericEnvironment.h" |
23 | | #include "swift/AST/IndexSubset.h" |
24 | | #include "swift/AST/LazyResolver.h" |
25 | | #include "swift/AST/Module.h" |
26 | | #include "swift/AST/NameLookupRequests.h" |
27 | | #include "swift/AST/ParameterList.h" |
28 | | #include "swift/AST/TypeCheckRequests.h" |
29 | | #include "swift/AST/TypeRepr.h" |
30 | | #include "swift/AST/Types.h" |
31 | | #include "swift/Basic/Defer.h" |
32 | | #include "swift/Basic/QuotedString.h" |
33 | | #include "swift/Strings.h" |
34 | | #include "llvm/ADT/SmallString.h" |
35 | | #include "llvm/ADT/StringSwitch.h" |
36 | | #include "llvm/Support/ErrorHandling.h" |
37 | | #include "llvm/Support/raw_ostream.h" |
38 | | using namespace swift; |
39 | | |
40 | | #define DECL_ATTR(_, Id, ...) \ |
41 | | static_assert(IsTriviallyDestructible<Id##Attr>::value, \ |
42 | | "Attrs are BumpPtrAllocated; the destructor is never called"); |
43 | | #include "swift/AST/Attr.def" |
44 | | static_assert(IsTriviallyDestructible<DeclAttributes>::value, |
45 | | "DeclAttributes are BumpPtrAllocated; the d'tor is never called"); |
46 | | static_assert(IsTriviallyDestructible<TypeAttributes>::value, |
47 | | "TypeAttributes are BumpPtrAllocated; the d'tor is never called"); |
48 | | |
49 | | #define DECL_ATTR(Name, Id, ...) \ |
50 | | static_assert(DeclAttribute::isOptionSetFor##Id(DeclAttribute::DeclAttrOptions::ABIBreakingToAdd) != \ |
51 | | DeclAttribute::isOptionSetFor##Id(DeclAttribute::DeclAttrOptions::ABIStableToAdd), \ |
52 | | #Name " needs to specify either ABIBreakingToAdd or ABIStableToAdd"); |
53 | | #include "swift/AST/Attr.def" |
54 | | |
55 | | #define DECL_ATTR(Name, Id, ...) \ |
56 | | static_assert(DeclAttribute::isOptionSetFor##Id(DeclAttribute::DeclAttrOptions::ABIBreakingToRemove) != \ |
57 | | DeclAttribute::isOptionSetFor##Id(DeclAttribute::DeclAttrOptions::ABIStableToRemove), \ |
58 | | #Name " needs to specify either ABIBreakingToRemove or ABIStableToRemove"); |
59 | | #include "swift/AST/Attr.def" |
60 | | |
61 | | #define DECL_ATTR(Name, Id, ...) \ |
62 | | static_assert(DeclAttribute::isOptionSetFor##Id(DeclAttribute::DeclAttrOptions::APIBreakingToAdd) != \ |
63 | | DeclAttribute::isOptionSetFor##Id(DeclAttribute::DeclAttrOptions::APIStableToAdd), \ |
64 | | #Name " needs to specify either APIBreakingToAdd or APIStableToAdd"); |
65 | | #include "swift/AST/Attr.def" |
66 | | |
67 | | #define DECL_ATTR(Name, Id, ...) \ |
68 | | static_assert(DeclAttribute::isOptionSetFor##Id(DeclAttribute::DeclAttrOptions::APIBreakingToRemove) != \ |
69 | | DeclAttribute::isOptionSetFor##Id(DeclAttribute::DeclAttrOptions::APIStableToRemove), \ |
70 | | #Name " needs to specify either APIBreakingToRemove or APIStableToRemove"); |
71 | | #include "swift/AST/Attr.def" |
72 | | |
73 | 46.2k | StringRef swift::getAccessLevelSpelling(AccessLevel value) { |
74 | 46.2k | switch (value) { |
75 | 2.90k | case AccessLevel::Private: return "private"; |
76 | 515 | case AccessLevel::FilePrivate: return "fileprivate"; |
77 | 22.9k | case AccessLevel::Internal: return "internal"; |
78 | 105 | case AccessLevel::Package: return "package"; |
79 | 19.3k | case AccessLevel::Public: return "public"; |
80 | 438 | case AccessLevel::Open: return "open"; |
81 | 46.2k | } |
82 | | |
83 | 0 | llvm_unreachable("Unhandled AccessLevel in switch."); |
84 | 0 | } |
85 | | |
86 | 178 | void TypeAttributes::getConventionArguments(SmallVectorImpl<char> &buf) const { |
87 | 178 | llvm::raw_svector_ostream stream(buf); |
88 | 178 | auto &convention = ConventionArguments.value(); |
89 | 178 | stream << convention.Name; |
90 | 178 | if (convention.WitnessMethodProtocol) { |
91 | 0 | stream << ": " << convention.WitnessMethodProtocol; |
92 | 0 | return; |
93 | 0 | } |
94 | 178 | if (!convention.ClangType.Item.empty()) |
95 | 0 | stream << ", cType: " << QuotedString(convention.ClangType.Item); |
96 | 178 | } |
97 | | |
98 | | /// Given a name like "autoclosure", return the type attribute ID that |
99 | | /// corresponds to it. This returns TAK_Count on failure. |
100 | | /// |
101 | 585k | TypeAttrKind TypeAttributes::getAttrKindFromString(StringRef Str) { |
102 | 585k | return llvm::StringSwitch<TypeAttrKind>(Str) |
103 | 29.8M | #define TYPE_ATTR(X) .Case(#X, TAK_##X) |
104 | 585k | #include "swift/AST/Attr.def" |
105 | 585k | .Default(TAK_Count); |
106 | 585k | } |
107 | | |
108 | | /// Return the name (like "autoclosure") for an attribute ID. |
109 | 165 | const char *TypeAttributes::getAttrName(TypeAttrKind kind) { |
110 | 165 | switch (kind) { |
111 | 0 | default: llvm_unreachable("Invalid attribute ID"); |
112 | 165 | #define TYPE_ATTR(X) case TAK_##X: return #X; |
113 | 165 | #include "swift/AST/Attr.def" |
114 | 165 | } |
115 | 165 | } |
116 | | |
117 | | |
118 | | |
119 | | /// Given a name like "inline", return the decl attribute ID that corresponds |
120 | | /// to it. Note that this is a many-to-one mapping, and that the identifier |
121 | | /// passed in may only be the first portion of the attribute (e.g. in the case |
122 | | /// of the 'unowned(unsafe)' attribute, the string passed in is 'unowned'. |
123 | | /// |
124 | | /// Also note that this recognizes both attributes like '@inline' (with no @) |
125 | | /// and decl modifiers like 'final'. This returns DAK_Count on failure. |
126 | | /// |
127 | 4.07M | DeclAttrKind DeclAttribute::getAttrKindFromString(StringRef Str) { |
128 | 4.07M | return llvm::StringSwitch<DeclAttrKind>(Str) |
129 | 566M | #define DECL_ATTR(X, CLASS, ...) .Case(#X, DAK_##CLASS) |
130 | 36.6M | #define DECL_ATTR_ALIAS(X, CLASS) .Case(#X, DAK_##CLASS) |
131 | 4.07M | #include "swift/AST/Attr.def" |
132 | 4.07M | .Case(SPI_AVAILABLE_ATTRNAME, DAK_Available) |
133 | 4.07M | .Default(DAK_Count); |
134 | 4.07M | } |
135 | | |
136 | | /// Returns true if this attribute can appear on the specified decl. |
137 | 11.1M | bool DeclAttribute::canAttributeAppearOnDecl(DeclAttrKind DK, const Decl *D) { |
138 | 11.1M | if ((getOptions(DK) & OnAnyClangDecl) && D->hasClangNode()) |
139 | 0 | return true; |
140 | 11.1M | return canAttributeAppearOnDeclKind(DK, D->getKind()); |
141 | 11.1M | } |
142 | | |
143 | 11.4M | bool DeclAttribute::canAttributeAppearOnDeclKind(DeclAttrKind DAK, DeclKind DK) { |
144 | 11.4M | auto Options = getOptions(DAK); |
145 | 11.4M | switch (DK) { |
146 | 11.4M | #define DECL(Id, Parent) case DeclKind::Id: return (Options & On##Id) != 0; |
147 | 11.4M | #include "swift/AST/DeclNodes.def" |
148 | 11.4M | } |
149 | 0 | llvm_unreachable("bad DeclKind"); |
150 | 0 | } |
151 | | |
152 | | bool |
153 | | DeclAttributes::isUnavailableInSwiftVersion( |
154 | 207k | const version::Version &effectiveVersion) const { |
155 | 207k | llvm::VersionTuple vers = effectiveVersion; |
156 | 357k | for (auto attr : *this) { |
157 | 357k | if (auto available = dyn_cast<AvailableAttr>(attr)) { |
158 | 9.96k | if (available->isInvalid()) |
159 | 0 | continue; |
160 | | |
161 | 9.96k | if (available->getPlatformAgnosticAvailability() == |
162 | 9.96k | PlatformAgnosticAvailabilityKind::SwiftVersionSpecific) { |
163 | 2.65k | if (available->Introduced.has_value() && |
164 | 2.65k | available->Introduced.value() > vers) |
165 | 0 | return true; |
166 | 2.65k | if (available->Obsoleted.has_value() && |
167 | 2.65k | available->Obsoleted.value() <= vers) |
168 | 2.56k | return true; |
169 | 2.65k | } |
170 | 9.96k | } |
171 | 357k | } |
172 | | |
173 | 204k | return false; |
174 | 207k | } |
175 | | |
176 | | const AvailableAttr * |
177 | 121M | DeclAttributes::findMostSpecificActivePlatform(const ASTContext &ctx) const{ |
178 | 121M | const AvailableAttr *bestAttr = nullptr; |
179 | | |
180 | 128M | for (auto attr : *this) { |
181 | 128M | auto *avAttr = dyn_cast<AvailableAttr>(attr); |
182 | 128M | if (!avAttr) |
183 | 100M | continue; |
184 | | |
185 | 27.9M | if (avAttr->isInvalid()) |
186 | 42 | continue; |
187 | | |
188 | 27.9M | if (!avAttr->hasPlatform()) |
189 | 2.57M | continue; |
190 | | |
191 | 25.3M | if (!avAttr->isActivePlatform(ctx)) |
192 | 18.6M | continue; |
193 | | |
194 | | // We have an attribute that is active for the platform, but |
195 | | // is it more specific than our current best? |
196 | 6.66M | if (!bestAttr || inheritsAvailabilityFromPlatform(avAttr->Platform, |
197 | 6.66M | bestAttr->Platform)) { |
198 | 6.66M | bestAttr = avAttr; |
199 | 6.66M | } |
200 | 6.66M | } |
201 | | |
202 | 121M | return bestAttr; |
203 | 121M | } |
204 | | |
205 | | const AvailableAttr * |
206 | 1.47k | DeclAttributes::getPotentiallyUnavailable(const ASTContext &ctx) const { |
207 | 1.47k | const AvailableAttr *potential = nullptr; |
208 | 1.47k | const AvailableAttr *conditional = nullptr; |
209 | | |
210 | 1.47k | for (auto Attr : *this) |
211 | 291 | if (auto AvAttr = dyn_cast<AvailableAttr>(Attr)) { |
212 | 42 | if (AvAttr->isInvalid()) |
213 | 0 | continue; |
214 | | |
215 | 42 | if (!AvAttr->isActivePlatform(ctx) && |
216 | 42 | !AvAttr->isLanguageVersionSpecific() && |
217 | 42 | !AvAttr->isPackageDescriptionVersionSpecific()) |
218 | 0 | continue; |
219 | | |
220 | | // Definitely not available. |
221 | 42 | if (AvAttr->isUnconditionallyUnavailable()) |
222 | 18 | return AvAttr; |
223 | | |
224 | 24 | switch (AvAttr->getVersionAvailability(ctx)) { |
225 | 12 | case AvailableVersionComparison::Available: |
226 | | // Doesn't limit the introduced version. |
227 | 12 | break; |
228 | | |
229 | 6 | case AvailableVersionComparison::PotentiallyUnavailable: |
230 | | // We'll return this if we don't see something that proves it's |
231 | | // not available in this version. |
232 | 6 | potential = AvAttr; |
233 | 6 | break; |
234 | | |
235 | 0 | case AvailableVersionComparison::Unavailable: |
236 | 6 | case AvailableVersionComparison::Obsoleted: |
237 | 6 | conditional = AvAttr; |
238 | 6 | break; |
239 | 24 | } |
240 | 24 | } |
241 | | |
242 | 1.45k | if (conditional) |
243 | 6 | return conditional; |
244 | 1.45k | return potential; |
245 | 1.45k | } |
246 | | |
247 | | const AvailableAttr *DeclAttributes::getUnavailable( |
248 | 105M | const ASTContext &ctx) const { |
249 | 105M | const AvailableAttr *conditional = nullptr; |
250 | 105M | const AvailableAttr *bestActive = findMostSpecificActivePlatform(ctx); |
251 | | |
252 | 105M | for (auto Attr : *this) |
253 | 109M | if (auto AvAttr = dyn_cast<AvailableAttr>(Attr)) { |
254 | 21.7M | if (AvAttr->isInvalid()) |
255 | 27 | continue; |
256 | | |
257 | | // If this is a platform-specific attribute and it isn't the most |
258 | | // specific attribute for the current platform, we're done. |
259 | 21.7M | if (AvAttr->hasPlatform() && |
260 | 21.7M | (!bestActive || AvAttr != bestActive)) |
261 | 14.2M | continue; |
262 | | |
263 | | // If this attribute doesn't apply to the active platform, we're done. |
264 | 7.55M | if (!AvAttr->isActivePlatform(ctx) && |
265 | 7.55M | !AvAttr->isLanguageVersionSpecific() && |
266 | 7.55M | !AvAttr->isPackageDescriptionVersionSpecific()) |
267 | 0 | continue; |
268 | | |
269 | | // Unconditional unavailable. |
270 | 7.55M | if (AvAttr->isUnconditionallyUnavailable()) |
271 | 2.03M | return AvAttr; |
272 | | |
273 | 5.51M | switch (AvAttr->getVersionAvailability(ctx)) { |
274 | 3.68M | case AvailableVersionComparison::Available: |
275 | 5.26M | case AvailableVersionComparison::PotentiallyUnavailable: |
276 | 5.26M | break; |
277 | | |
278 | 244k | case AvailableVersionComparison::Obsoleted: |
279 | 247k | case AvailableVersionComparison::Unavailable: |
280 | 247k | conditional = AvAttr; |
281 | 247k | break; |
282 | 5.51M | } |
283 | 5.51M | } |
284 | 103M | return conditional; |
285 | 105M | } |
286 | | |
287 | | const AvailableAttr * |
288 | 15.5M | DeclAttributes::getDeprecated(const ASTContext &ctx) const { |
289 | 15.5M | const AvailableAttr *conditional = nullptr; |
290 | 15.5M | const AvailableAttr *bestActive = findMostSpecificActivePlatform(ctx); |
291 | 18.0M | for (auto Attr : *this) { |
292 | 18.0M | if (auto AvAttr = dyn_cast<AvailableAttr>(Attr)) { |
293 | 5.96M | if (AvAttr->isInvalid()) |
294 | 15 | continue; |
295 | | |
296 | 5.96M | if (AvAttr->hasPlatform() && |
297 | 5.96M | (!bestActive || AvAttr != bestActive)) |
298 | 4.36M | continue; |
299 | | |
300 | 1.59M | if (!AvAttr->isActivePlatform(ctx) && |
301 | 1.59M | !AvAttr->isLanguageVersionSpecific() && |
302 | 1.59M | !AvAttr->isPackageDescriptionVersionSpecific()) |
303 | 0 | continue; |
304 | | |
305 | | // Unconditional deprecated. |
306 | 1.59M | if (AvAttr->isUnconditionallyDeprecated()) |
307 | 25.2k | return AvAttr; |
308 | | |
309 | 1.57M | llvm::Optional<llvm::VersionTuple> DeprecatedVersion = AvAttr->Deprecated; |
310 | 1.57M | if (!DeprecatedVersion.has_value()) |
311 | 1.54M | continue; |
312 | | |
313 | 29.6k | llvm::VersionTuple MinVersion = AvAttr->getActiveVersion(ctx); |
314 | | |
315 | | // We treat the declaration as deprecated if it is deprecated on |
316 | | // all deployment targets. |
317 | | // Once availability checking is enabled by default, we should |
318 | | // query the type refinement context hierarchy to determine |
319 | | // whether a declaration is deprecated on all versions |
320 | | // allowed by the context containing the reference. |
321 | 29.6k | if (DeprecatedVersion.value() <= MinVersion) { |
322 | 19.0k | conditional = AvAttr; |
323 | 19.0k | } |
324 | 29.6k | } |
325 | 18.0M | } |
326 | 15.4M | return conditional; |
327 | 15.5M | } |
328 | | |
329 | | const AvailableAttr * |
330 | 321k | DeclAttributes::getSoftDeprecated(const ASTContext &ctx) const { |
331 | 321k | const AvailableAttr *conditional = nullptr; |
332 | 321k | const AvailableAttr *bestActive = findMostSpecificActivePlatform(ctx); |
333 | 321k | for (auto Attr : *this) { |
334 | 220k | if (auto AvAttr = dyn_cast<AvailableAttr>(Attr)) { |
335 | 51.1k | if (AvAttr->isInvalid()) |
336 | 0 | continue; |
337 | | |
338 | 51.1k | if (AvAttr->hasPlatform() && |
339 | 51.1k | (!bestActive || AvAttr != bestActive)) |
340 | 25.0k | continue; |
341 | | |
342 | 26.1k | if (!AvAttr->isActivePlatform(ctx) && |
343 | 26.1k | !AvAttr->isLanguageVersionSpecific() && |
344 | 26.1k | !AvAttr->isPackageDescriptionVersionSpecific()) |
345 | 0 | continue; |
346 | | |
347 | 26.1k | llvm::Optional<llvm::VersionTuple> DeprecatedVersion = AvAttr->Deprecated; |
348 | 26.1k | if (!DeprecatedVersion.has_value()) |
349 | 17.4k | continue; |
350 | | |
351 | 8.71k | llvm::VersionTuple ActiveVersion = AvAttr->getActiveVersion(ctx); |
352 | | |
353 | 8.71k | if (DeprecatedVersion.value() > ActiveVersion) { |
354 | 8.71k | conditional = AvAttr; |
355 | 8.71k | } |
356 | 8.71k | } |
357 | 220k | } |
358 | 321k | return conditional; |
359 | 321k | } |
360 | | |
361 | 88.3k | const AvailableAttr *DeclAttributes::getNoAsync(const ASTContext &ctx) const { |
362 | 88.3k | const AvailableAttr *bestAttr = nullptr; |
363 | 119k | for (const DeclAttribute *attr : *this) { |
364 | 119k | if (const AvailableAttr *avAttr = dyn_cast<AvailableAttr>(attr)) { |
365 | 39.8k | if (avAttr->isInvalid()) |
366 | 0 | continue; |
367 | | |
368 | 39.8k | if (avAttr->getPlatformAgnosticAvailability() == |
369 | 39.8k | PlatformAgnosticAvailabilityKind::NoAsync) { |
370 | | // An API may only be unavailable on specific platforms. |
371 | | // If it doesn't have a platform associated with it, then it's |
372 | | // unavailable for all platforms, so we should include it. If it does |
373 | | // have a platform and we are not that platform, then it doesn't apply |
374 | | // to us. |
375 | 63 | const bool isGoodForPlatform = |
376 | 63 | (avAttr->hasPlatform() && avAttr->isActivePlatform(ctx)) || |
377 | 63 | !avAttr->hasPlatform(); |
378 | | |
379 | 63 | if (!isGoodForPlatform) |
380 | 0 | continue; |
381 | | |
382 | 63 | if (!bestAttr) { |
383 | | // If there is no best attr selected |
384 | | // and the attr either has an active platform, or doesn't have one at |
385 | | // all, select it. |
386 | 63 | bestAttr = avAttr; |
387 | 63 | } else if (bestAttr && avAttr->hasPlatform() && |
388 | 0 | bestAttr->hasPlatform() && |
389 | 0 | inheritsAvailabilityFromPlatform(avAttr->Platform, |
390 | 0 | bestAttr->Platform)) { |
391 | | // if they both have a viable platform, use the better one |
392 | 0 | bestAttr = avAttr; |
393 | 0 | } else if (avAttr->hasPlatform() && !bestAttr->hasPlatform()) { |
394 | | // Use the one more specific |
395 | 0 | bestAttr = avAttr; |
396 | 0 | } |
397 | 63 | } |
398 | 39.8k | } |
399 | 119k | } |
400 | 88.3k | return bestAttr; |
401 | 88.3k | } |
402 | | |
403 | | const BackDeployedAttr * |
404 | 9.02M | DeclAttributes::getBackDeployed(const ASTContext &ctx) const { |
405 | 9.02M | const BackDeployedAttr *bestAttr = nullptr; |
406 | | |
407 | 10.6M | for (auto attr : *this) { |
408 | 10.6M | auto *backDeployedAttr = dyn_cast<BackDeployedAttr>(attr); |
409 | 10.6M | if (!backDeployedAttr) |
410 | 10.6M | continue; |
411 | | |
412 | 25.0k | if (backDeployedAttr->isInvalid() || |
413 | 25.0k | !backDeployedAttr->isActivePlatform(ctx)) |
414 | 15.3k | continue; |
415 | | |
416 | | // We have an attribute that is active for the platform, but |
417 | | // is it more specific than our current best? |
418 | 9.67k | if (!bestAttr || inheritsAvailabilityFromPlatform( |
419 | 9.66k | backDeployedAttr->Platform, bestAttr->Platform)) { |
420 | 9.66k | bestAttr = backDeployedAttr; |
421 | 9.66k | } |
422 | 9.67k | } |
423 | | |
424 | 9.02M | return bestAttr; |
425 | 9.02M | } |
426 | | |
427 | 0 | void DeclAttributes::dump(const Decl *D) const { |
428 | 0 | StreamPrinter P(llvm::errs()); |
429 | 0 | PrintOptions PO = PrintOptions::printDeclarations(); |
430 | 0 | print(P, PO, D); |
431 | 0 | } |
432 | | |
433 | | /// Returns true if the attribute can be presented as a short form available |
434 | | /// attribute (e.g., as @available(iOS 8.0, *). The presentation requires an |
435 | | /// introduction version and does not support deprecation, obsoletion, or |
436 | | /// messages. |
437 | | LLVM_READONLY |
438 | 366k | static bool isShortAvailable(const DeclAttribute *DA) { |
439 | 366k | auto *AvailAttr = dyn_cast<AvailableAttr>(DA); |
440 | 366k | if (!AvailAttr) |
441 | 111k | return false; |
442 | | |
443 | 255k | if (AvailAttr->IsSPI) |
444 | 96 | return false; |
445 | | |
446 | 254k | if (!AvailAttr->Introduced.has_value()) |
447 | 80.0k | return false; |
448 | | |
449 | 174k | if (AvailAttr->Deprecated.has_value()) |
450 | 3.75k | return false; |
451 | | |
452 | 171k | if (AvailAttr->Obsoleted.has_value()) |
453 | 42 | return false; |
454 | | |
455 | 171k | if (!AvailAttr->Message.empty()) |
456 | 45 | return false; |
457 | | |
458 | 171k | if (!AvailAttr->Rename.empty()) |
459 | 1.19k | return false; |
460 | | |
461 | 169k | switch (AvailAttr->PlatformAgnostic) { |
462 | 0 | case PlatformAgnosticAvailabilityKind::Deprecated: |
463 | 1.66k | case PlatformAgnosticAvailabilityKind::Unavailable: |
464 | 1.66k | case PlatformAgnosticAvailabilityKind::UnavailableInSwift: |
465 | 1.66k | case PlatformAgnosticAvailabilityKind::NoAsync: |
466 | 1.66k | return false; |
467 | 168k | case PlatformAgnosticAvailabilityKind::None: |
468 | 168k | case PlatformAgnosticAvailabilityKind::SwiftVersionSpecific: |
469 | 168k | case PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific: |
470 | 168k | return true; |
471 | 169k | } |
472 | | |
473 | 0 | return true; |
474 | 169k | } |
475 | | |
476 | | /// Return true when another availability attribute implies the same availability as this |
477 | | /// attribute and so printing the attribute can be skipped to de-clutter the declaration |
478 | | /// when printing the short form. |
479 | | /// For example, iOS availability implies macCatalyst availability so if attributes for |
480 | | /// both are present and they have the same 'introduced' version, we can skip printing an |
481 | | /// explicit availability for macCatalyst. |
482 | | static bool isShortFormAvailabilityImpliedByOther(const AvailableAttr *Attr, |
483 | 82.9k | ArrayRef<const DeclAttribute *> Others) { |
484 | 82.9k | assert(isShortAvailable(Attr)); |
485 | | |
486 | 272k | for (auto *DA : Others) { |
487 | 272k | auto *Other = cast<AvailableAttr>(DA); |
488 | 272k | if (Attr->Platform == Other->Platform) |
489 | 83.0k | continue; |
490 | | |
491 | 189k | if (!inheritsAvailabilityFromPlatform(Attr->Platform, Other->Platform)) |
492 | 189k | continue; |
493 | | |
494 | 0 | if (Attr->Introduced == Other->Introduced) |
495 | 0 | return true; |
496 | 0 | } |
497 | 82.9k | return false; |
498 | 82.9k | } |
499 | | |
500 | | /// Print the short-form @available() attribute for an array of long-form |
501 | | /// AvailableAttrs that can be represented in the short form. |
502 | | /// For example, for: |
503 | | /// @available(OSX, introduced: 10.10) |
504 | | /// @available(iOS, introduced: 8.0) |
505 | | /// this will print: |
506 | | /// @available(OSX 10.10, iOS 8.0, *) |
507 | | static void printShortFormAvailable(ArrayRef<const DeclAttribute *> Attrs, |
508 | | ASTPrinter &Printer, |
509 | | const PrintOptions &Options, |
510 | 35.9k | bool forAtSpecialize = false) { |
511 | 35.9k | assert(!Attrs.empty()); |
512 | 35.9k | if (!forAtSpecialize) |
513 | 35.9k | Printer << "@available("; |
514 | 35.9k | auto FirstAvail = cast<AvailableAttr>(Attrs.front()); |
515 | 35.9k | if (Attrs.size() == 1 && |
516 | 35.9k | FirstAvail->getPlatformAgnosticAvailability() != |
517 | 18.5k | PlatformAgnosticAvailabilityKind::None) { |
518 | 177 | assert(FirstAvail->Introduced.has_value()); |
519 | 177 | if (FirstAvail->isLanguageVersionSpecific()) { |
520 | 156 | Printer << "swift "; |
521 | 156 | } else { |
522 | 21 | assert(FirstAvail->isPackageDescriptionVersionSpecific()); |
523 | 0 | Printer << "_PackageDescription "; |
524 | 21 | } |
525 | 0 | Printer << FirstAvail->Introduced.value().getAsString(); |
526 | 177 | if (!forAtSpecialize) |
527 | 177 | Printer << ")"; |
528 | 35.7k | } else { |
529 | 85.3k | for (auto *DA : Attrs) { |
530 | 85.3k | auto *AvailAttr = cast<AvailableAttr>(DA); |
531 | 85.3k | assert(AvailAttr->Introduced.has_value()); |
532 | | // Avoid omitting available attribute when we are printing module interface. |
533 | 85.3k | if (!Options.IsForSwiftInterface && |
534 | 85.3k | isShortFormAvailabilityImpliedByOther(AvailAttr, Attrs)) |
535 | 0 | continue; |
536 | 85.3k | Printer << platformString(AvailAttr->Platform) << " " |
537 | 85.3k | << AvailAttr->Introduced.value().getAsString() << ", "; |
538 | 85.3k | } |
539 | 35.7k | Printer << "*"; |
540 | 35.7k | if (!forAtSpecialize) |
541 | 35.7k | Printer << ")"; |
542 | 35.7k | } |
543 | 35.9k | if (!forAtSpecialize) |
544 | 35.9k | Printer.printNewline(); |
545 | 35.9k | } |
546 | | |
547 | | static void printShortFormBackDeployed(ArrayRef<const DeclAttribute *> Attrs, |
548 | | ASTPrinter &Printer, |
549 | 219 | const PrintOptions &Options) { |
550 | 219 | assert(!Attrs.empty()); |
551 | 0 | Printer << "@backDeployed(before: "; |
552 | 219 | bool isFirst = true; |
553 | | |
554 | 324 | for (auto *DA : Attrs) { |
555 | 324 | if (!isFirst) |
556 | 105 | Printer << ", "; |
557 | 324 | auto *attr = cast<BackDeployedAttr>(DA); |
558 | 324 | Printer << platformString(attr->Platform) << " " |
559 | 324 | << attr->Version.getAsString(); |
560 | 324 | isFirst = false; |
561 | 324 | } |
562 | 219 | Printer << ")"; |
563 | 219 | Printer.printNewline(); |
564 | 219 | } |
565 | | |
566 | | /// The kind of a parameter in a `wrt:` differentiation parameters clause: |
567 | | /// either a differentiability parameter or a linearity parameter. Used for |
568 | | /// printing `@differentiable`, `@derivative`, and `@transpose` attributes. |
569 | | enum class DifferentiationParameterKind { |
570 | | /// A differentiability parameter, printed by name. |
571 | | /// Used for `@differentiable` and `@derivative` attribute. |
572 | | Differentiability, |
573 | | /// A linearity parameter, printed by index. |
574 | | /// Used for `@transpose` attribute. |
575 | | Linearity |
576 | | }; |
577 | | |
578 | | /// Returns the differentiation parameters clause string for the given function, |
579 | | /// parameter indices, parsed parameters, and differentiation parameter kind. |
580 | | /// Use the parameter indices if specified; otherwise, use the parsed |
581 | | /// parameters. |
582 | | static std::string getDifferentiationParametersClauseString( |
583 | | const AbstractFunctionDecl *function, IndexSubset *parameterIndices, |
584 | | ArrayRef<ParsedAutoDiffParameter> parsedParams, |
585 | 1.04k | DifferentiationParameterKind parameterKind) { |
586 | 1.04k | assert(function); |
587 | 0 | bool isInstanceMethod = function->isInstanceMember(); |
588 | 1.04k | bool isStaticMethod = function->isStatic(); |
589 | 1.04k | std::string result; |
590 | 1.04k | llvm::raw_string_ostream printer(result); |
591 | | |
592 | | // Use the parameter indices, if specified. |
593 | 1.04k | if (parameterIndices) { |
594 | 1.04k | auto parameters = parameterIndices->getBitVector(); |
595 | 1.04k | auto parameterCount = parameters.count(); |
596 | 1.04k | printer << "wrt: "; |
597 | 1.04k | if (parameterCount > 1) |
598 | 276 | printer << '('; |
599 | | // Check if differentiating wrt `self`. If so, manually print it first. |
600 | 1.04k | bool isWrtSelf = |
601 | 1.04k | (isInstanceMethod || |
602 | 1.04k | (isStaticMethod && |
603 | 528 | parameterKind == DifferentiationParameterKind::Linearity)) && |
604 | 1.04k | parameters.test(parameters.size() - 1); |
605 | 1.04k | if (isWrtSelf) { |
606 | 396 | parameters.reset(parameters.size() - 1); |
607 | 396 | printer << "self"; |
608 | 396 | if (parameters.any()) |
609 | 76 | printer << ", "; |
610 | 396 | } |
611 | | // Print remaining differentiation parameters. |
612 | 1.04k | interleave(parameters.set_bits(), [&](unsigned index) { |
613 | 948 | switch (parameterKind) { |
614 | | // Print differentiability parameters by name. |
615 | 928 | case DifferentiationParameterKind::Differentiability: |
616 | 928 | printer << function->getParameters()->get(index)->getName().str(); |
617 | 928 | break; |
618 | | // Print linearity parameters by index. |
619 | 20 | case DifferentiationParameterKind::Linearity: |
620 | 20 | printer << index; |
621 | 20 | break; |
622 | 948 | } |
623 | 948 | }, [&] { printer << ", "; }); |
624 | 1.04k | if (parameterCount > 1) |
625 | 276 | printer << ')'; |
626 | 1.04k | } |
627 | | // Otherwise, use the parsed parameters. |
628 | 0 | else if (!parsedParams.empty()) { |
629 | 0 | printer << "wrt: "; |
630 | 0 | if (parsedParams.size() > 1) |
631 | 0 | printer << '('; |
632 | 0 | interleave(parsedParams, [&](const ParsedAutoDiffParameter ¶m) { |
633 | 0 | switch (param.getKind()) { |
634 | 0 | case ParsedAutoDiffParameter::Kind::Named: |
635 | 0 | printer << param.getName(); |
636 | 0 | break; |
637 | 0 | case ParsedAutoDiffParameter::Kind::Self: |
638 | 0 | printer << "self"; |
639 | 0 | break; |
640 | 0 | case ParsedAutoDiffParameter::Kind::Ordered: |
641 | 0 | auto *paramList = function->getParameters(); |
642 | 0 | assert(param.getIndex() <= paramList->size() && |
643 | 0 | "wrt parameter is out of range"); |
644 | 0 | auto *funcParam = paramList->get(param.getIndex()); |
645 | 0 | printer << funcParam->getNameStr(); |
646 | 0 | break; |
647 | 0 | } |
648 | 0 | }, [&] { printer << ", "; }); |
649 | 0 | if (parsedParams.size() > 1) |
650 | 0 | printer << ')'; |
651 | 0 | } |
652 | 1.04k | return printer.str(); |
653 | 1.04k | } |
654 | | |
655 | | /// Print the arguments of the given `@differentiable` attribute. |
656 | | /// - If `omitWrtClause` is true, omit printing the `wrt:` differentiation |
657 | | /// parameters clause. |
658 | | static void printDifferentiableAttrArguments( |
659 | | const DifferentiableAttr *attr, ASTPrinter &printer, |
660 | 816 | const PrintOptions &Options, const Decl *D, bool omitWrtClause = false) { |
661 | | // Create a temporary string for the attribute argument text. |
662 | 816 | std::string attrArgText; |
663 | 816 | llvm::raw_string_ostream stream(attrArgText); |
664 | | |
665 | | // Print comma if not leading clause. |
666 | 816 | bool isLeadingClause = false; |
667 | 816 | auto printCommaIfNecessary = [&] { |
668 | 744 | if (isLeadingClause) { |
669 | 0 | isLeadingClause = false; |
670 | 0 | return; |
671 | 0 | } |
672 | 744 | stream << ", "; |
673 | 744 | }; |
674 | | |
675 | | // Print if the function is marked as linear. |
676 | 816 | switch (attr->getDifferentiabilityKind()) { |
677 | 0 | case DifferentiabilityKind::Normal: |
678 | 0 | isLeadingClause = true; |
679 | 0 | break; |
680 | 0 | case DifferentiabilityKind::Forward: |
681 | 0 | stream << "_forward"; |
682 | 0 | break; |
683 | 808 | case DifferentiabilityKind::Reverse: |
684 | 808 | stream << "reverse"; |
685 | 808 | break; |
686 | 8 | case DifferentiabilityKind::Linear: |
687 | 8 | stream << "_linear"; |
688 | 8 | break; |
689 | 0 | case DifferentiabilityKind::NonDifferentiable: |
690 | 0 | llvm_unreachable("Impossible case `NonDifferentiable`"); |
691 | 816 | } |
692 | | |
693 | | // If the declaration is not available, there is not enough context to print |
694 | | // the differentiability parameters or the 'where' clause, so just print the |
695 | | // differentiability kind if applicable (when not `Normal`). |
696 | 816 | if (!D) { |
697 | 0 | if (attr->getDifferentiabilityKind() != DifferentiabilityKind::Normal) { |
698 | 0 | printer << '(' << stream.str() << ')'; |
699 | 0 | } |
700 | 0 | return; |
701 | 0 | } |
702 | | |
703 | | // Get original function. |
704 | 816 | auto *original = dyn_cast<AbstractFunctionDecl>(D); |
705 | | // Handle stored/computed properties and subscript methods. |
706 | 816 | if (auto *asd = dyn_cast<AbstractStorageDecl>(D)) |
707 | 36 | original = asd->getAccessor(AccessorKind::Get); |
708 | 816 | assert(original && "Must resolve original declaration"); |
709 | | |
710 | | // Print differentiation parameters clause, unless it is to be omitted. |
711 | 816 | if (!omitWrtClause) { |
712 | 744 | auto diffParamsString = getDifferentiationParametersClauseString( |
713 | 744 | original, attr->getParameterIndices(), attr->getParsedParameters(), |
714 | 744 | DifferentiationParameterKind::Differentiability); |
715 | | // Check whether differentiation parameter clause is empty. |
716 | | // Handles edge case where resolved parameter indices are unset and |
717 | | // parsed parameters are empty. This case should never trigger for |
718 | | // user-visible printing. |
719 | 744 | if (!diffParamsString.empty()) { |
720 | 744 | printCommaIfNecessary(); |
721 | 744 | stream << diffParamsString; |
722 | 744 | } |
723 | 744 | } |
724 | | // Print 'where' clause, if any. |
725 | | // First, filter out requirements satisfied by the original function's |
726 | | // generic signature. They should not be printed. |
727 | 816 | ArrayRef<Requirement> derivativeRequirements; |
728 | 816 | if (auto derivativeGenSig = attr->getDerivativeGenericSignature()) |
729 | 404 | derivativeRequirements = derivativeGenSig.getRequirements(); |
730 | 816 | auto requirementsToPrint = |
731 | 816 | llvm::make_filter_range(derivativeRequirements, [&](Requirement req) { |
732 | 548 | if (const auto &originalGenSig = original->getGenericSignature()) |
733 | 548 | if (originalGenSig->isRequirementSatisfied(req)) |
734 | 408 | return false; |
735 | 140 | return true; |
736 | 548 | }); |
737 | 816 | if (!requirementsToPrint.empty()) { |
738 | 104 | if (!isLeadingClause) |
739 | 104 | stream << ' '; |
740 | 104 | stream << "where "; |
741 | 140 | interleave(requirementsToPrint, [&](Requirement req) { |
742 | 140 | if (const auto &originalGenSig = original->getGenericSignature()) |
743 | 140 | if (originalGenSig->isRequirementSatisfied(req)) |
744 | 0 | return; |
745 | 140 | req.print(stream, Options); |
746 | 140 | }, [&] { |
747 | 36 | stream << ", "; |
748 | 36 | }); |
749 | 104 | } |
750 | | |
751 | | // If the attribute argument text is empty, return. Do not print parentheses. |
752 | 816 | if (stream.str().empty()) |
753 | 0 | return; |
754 | | |
755 | | // Otherwise, print the attribute argument text enclosed in parentheses. |
756 | 816 | printer << '(' << stream.str() << ')'; |
757 | 816 | } |
758 | | |
759 | | void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options, |
760 | 1.08M | const Decl *D) const { |
761 | 1.08M | if (!DeclAttrs) |
762 | 737k | return; |
763 | | |
764 | 342k | SmallVector<const DeclAttribute *, 8> orderedAttributes(begin(), end()); |
765 | 342k | print(Printer, Options, orderedAttributes, D); |
766 | 342k | } |
767 | | |
768 | | void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options, |
769 | | ArrayRef<const DeclAttribute *> FlattenedAttrs, |
770 | 345k | const Decl *D) { |
771 | 345k | using AttributeVector = SmallVector<const DeclAttribute *, 8>; |
772 | | |
773 | | // Process attributes in passes. |
774 | 345k | AttributeVector shortAvailableAttributes; |
775 | 345k | const DeclAttribute *swiftVersionAvailableAttribute = nullptr; |
776 | 345k | const DeclAttribute *packageDescriptionVersionAvailableAttribute = nullptr; |
777 | 345k | AttributeVector backDeployedAttributes; |
778 | 345k | AttributeVector longAttributes; |
779 | 345k | AttributeVector attributes; |
780 | 345k | AttributeVector modifiers; |
781 | | |
782 | 532k | for (auto DA : llvm::reverse(FlattenedAttrs)) { |
783 | | // Always print result builder attribute. |
784 | 532k | if (!Options.PrintImplicitAttrs && DA->isImplicit()) |
785 | 191k | continue; |
786 | 341k | if (!Options.PrintUserInaccessibleAttrs && |
787 | 341k | DeclAttribute::isUserInaccessible(DA->getKind())) |
788 | 5.89k | continue; |
789 | 335k | if (Options.excludeAttrKind(DA->getKind())) |
790 | 27.6k | continue; |
791 | | |
792 | | // If we're supposed to suppress expanded macros, check whether this is |
793 | | // a macro. |
794 | 307k | if (Options.SuppressExpandedMacros) { |
795 | 307k | if (auto customAttr = dyn_cast<CustomAttr>(DA)) { |
796 | 1.94k | if (D->getResolvedMacro(const_cast<CustomAttr *>(customAttr))) |
797 | 54 | continue; |
798 | 1.94k | } |
799 | 307k | } |
800 | | |
801 | | // If this attribute is only allowed because this is a Clang decl, don't |
802 | | // print it. |
803 | 307k | if (D && D->hasClangNode() |
804 | 307k | && !DeclAttribute::canAttributeAppearOnDeclKind( |
805 | 75.2k | DA->getKind(), D->getKind())) |
806 | 1.26k | continue; |
807 | | |
808 | | // Be careful not to coalesce `@available(swift 5)` with other short |
809 | | // `available' attributes. |
810 | 306k | if (auto *availableAttr = dyn_cast<AvailableAttr>(DA)) { |
811 | 153k | if (availableAttr->isLanguageVersionSpecific() && |
812 | 153k | isShortAvailable(availableAttr)) { |
813 | 156 | swiftVersionAvailableAttribute = availableAttr; |
814 | 156 | continue; |
815 | 156 | } |
816 | 153k | if (availableAttr->isPackageDescriptionVersionSpecific() && |
817 | 153k | isShortAvailable(availableAttr)) { |
818 | 21 | packageDescriptionVersionAvailableAttribute = availableAttr; |
819 | 21 | continue; |
820 | 21 | } |
821 | 153k | } |
822 | | |
823 | 305k | AttributeVector &which = DA->isDeclModifier() ? modifiers : |
824 | 305k | isa<BackDeployedAttr>(DA) ? backDeployedAttributes : |
825 | 265k | isShortAvailable(DA) ? shortAvailableAttributes : |
826 | 264k | DA->isLongAttribute() ? longAttributes : |
827 | 179k | attributes; |
828 | 305k | which.push_back(DA); |
829 | 305k | } |
830 | | |
831 | 345k | if (swiftVersionAvailableAttribute) |
832 | 156 | printShortFormAvailable(swiftVersionAvailableAttribute, Printer, Options); |
833 | 345k | if (packageDescriptionVersionAvailableAttribute) |
834 | 21 | printShortFormAvailable(packageDescriptionVersionAvailableAttribute, Printer, Options); |
835 | 345k | if (!shortAvailableAttributes.empty()) |
836 | 35.7k | printShortFormAvailable(shortAvailableAttributes, Printer, Options); |
837 | 345k | if (!backDeployedAttributes.empty()) |
838 | 219 | printShortFormBackDeployed(backDeployedAttributes, Printer, Options); |
839 | | |
840 | 345k | for (auto DA : longAttributes) |
841 | 78.5k | DA->print(Printer, Options, D); |
842 | 345k | for (auto DA : attributes) |
843 | 101k | DA->print(Printer, Options, D); |
844 | 345k | for (auto DA : modifiers) |
845 | 40.8k | DA->print(Printer, Options, D); |
846 | 345k | } |
847 | | |
848 | 16.8k | SourceLoc DeclAttributes::getStartLoc(bool forModifiers) const { |
849 | 16.8k | if (isEmpty()) |
850 | 4.11k | return SourceLoc(); |
851 | | |
852 | 12.7k | const DeclAttribute *lastAttr = nullptr; |
853 | 23.4k | for (auto attr : *this) { |
854 | 23.4k | if (attr->getRangeWithAt().Start.isValid() && |
855 | 23.4k | (!forModifiers || attr->isDeclModifier())) |
856 | 5.10k | lastAttr = attr; |
857 | 23.4k | } |
858 | | |
859 | 12.7k | return lastAttr ? lastAttr->getRangeWithAt().Start : SourceLoc(); |
860 | 16.8k | } |
861 | | |
862 | | llvm::Optional<const DeclAttribute *> |
863 | 610M | ParsedDeclAttrFilter::operator()(const DeclAttribute *Attr) const { |
864 | 610M | if (Attr->isImplicit()) |
865 | 2.60M | return llvm::None; |
866 | | |
867 | 607M | auto declLoc = decl->getStartLoc(); |
868 | 607M | auto *mod = decl->getModuleContext(); |
869 | 607M | auto *declFile = mod->getSourceFileContainingLocation(declLoc); |
870 | 607M | auto *attrFile = mod->getSourceFileContainingLocation(Attr->getLocation()); |
871 | 607M | if (!declFile || !attrFile) |
872 | 7.26M | return llvm::None; |
873 | | |
874 | | // Only attributes in the same buffer as the declaration they're attached to |
875 | | // are part of the original attribute list. |
876 | 600M | if (declFile->getBufferID() != attrFile->getBufferID()) |
877 | 219 | return llvm::None; |
878 | | |
879 | 600M | return Attr; |
880 | 600M | } |
881 | | |
882 | | static void printAvailableAttr(const AvailableAttr *Attr, ASTPrinter &Printer, |
883 | 68.7k | const PrintOptions &Options) { |
884 | 68.7k | if (Attr->isLanguageVersionSpecific()) |
885 | 18.0k | Printer << "swift"; |
886 | 50.6k | else if (Attr->isPackageDescriptionVersionSpecific()) |
887 | 15 | Printer << "_PackageDescription"; |
888 | 50.6k | else |
889 | 50.6k | Printer << Attr->platformString(); |
890 | | |
891 | 68.7k | if (Attr->isUnconditionallyUnavailable()) |
892 | 31.7k | Printer << ", unavailable"; |
893 | 36.9k | else if (Attr->isUnconditionallyDeprecated()) |
894 | 15.2k | Printer << ", deprecated"; |
895 | 21.6k | else if (Attr->isNoAsync()) |
896 | 3 | Printer << ", noasync"; |
897 | | |
898 | 68.7k | if (Attr->Introduced) |
899 | 6.21k | Printer << ", introduced: " << Attr->Introduced.value().getAsString(); |
900 | 68.7k | if (Attr->Deprecated) |
901 | 5.15k | Printer << ", deprecated: " << Attr->Deprecated.value().getAsString(); |
902 | 68.7k | if (Attr->Obsoleted) |
903 | 17.2k | Printer << ", obsoleted: " << Attr->Obsoleted.value().getAsString(); |
904 | | |
905 | 68.7k | if (!Attr->Rename.empty()) { |
906 | 20.3k | Printer << ", renamed: \"" << Attr->Rename << "\""; |
907 | 48.3k | } else if (Attr->RenameDecl) { |
908 | 213 | Printer << ", renamed: \""; |
909 | 213 | if (auto *Accessor = dyn_cast<AccessorDecl>(Attr->RenameDecl)) { |
910 | 18 | SmallString<32> Name; |
911 | 18 | llvm::raw_svector_ostream OS(Name); |
912 | 18 | Accessor->printUserFacingName(OS); |
913 | 18 | Printer << Name.str(); |
914 | 195 | } else { |
915 | 195 | Printer << Attr->RenameDecl->getName(); |
916 | 195 | } |
917 | 213 | Printer << "\""; |
918 | 213 | } |
919 | | |
920 | | // If there's no message, but this is specifically an imported |
921 | | // "unavailable in Swift" attribute, synthesize a message to look good in |
922 | | // the generated interface. |
923 | 68.7k | if (!Attr->Message.empty()) { |
924 | 41.2k | Printer << ", message: "; |
925 | 41.2k | Printer.printEscapedStringLiteral(Attr->Message); |
926 | 41.2k | } else if (Attr->getPlatformAgnosticAvailability() == |
927 | 27.4k | PlatformAgnosticAvailabilityKind::UnavailableInSwift) |
928 | 1.58k | Printer << ", message: \"Not available in Swift\""; |
929 | 68.7k | } |
930 | | |
931 | | bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options, |
932 | 220k | const Decl *D) const { |
933 | | |
934 | | // Handle any attributes that are not printed at all before we make printer |
935 | | // callbacks. |
936 | 220k | switch (getKind()) { |
937 | 13.4k | case DAK_ObjC: |
938 | 13.4k | if (Options.PrintForSIL && isImplicit()) |
939 | 1.44k | return false; |
940 | 11.9k | break; |
941 | 11.9k | case DAK_RawDocComment: |
942 | 6.98k | case DAK_ObjCBridged: |
943 | 7.12k | case DAK_SynthesizedProtocol: |
944 | 8.34k | case DAK_Rethrows: |
945 | 8.36k | case DAK_Reasync: |
946 | 8.36k | case DAK_Infix: |
947 | 8.36k | return false; |
948 | 7.31k | case DAK_Override: { |
949 | 7.31k | if (!Options.IsForSwiftInterface) |
950 | 7.07k | break; |
951 | | // When we are printing Swift interface, we have to skip the override keyword |
952 | | // if the overridden decl is invisible from the interface. Otherwise, an error |
953 | | // will occur while building the Swift module because the overriding decl |
954 | | // doesn't override anything. |
955 | | // We couldn't skip every `override` keywords because they change the |
956 | | // ABI if the overridden decl is also publicly visible. |
957 | | // For public-override-internal case, having `override` doesn't have ABI |
958 | | // implication. Thus we can skip them. |
959 | 237 | if (auto *VD = dyn_cast<ValueDecl>(D)) { |
960 | 237 | if (auto *BD = VD->getOverriddenDecl()) { |
961 | | // If the overridden decl won't be printed, printing override will fail |
962 | | // the build of the interface file. |
963 | 237 | if (!Options.shouldPrint(BD)) |
964 | 42 | return false; |
965 | 195 | if (!BD->hasClangNode() && |
966 | 195 | !BD->getFormalAccessScope(VD->getDeclContext(), |
967 | 144 | /*treatUsableFromInlineAsPublic*/ true) |
968 | 144 | .isPublic()) { |
969 | 0 | return false; |
970 | 0 | } |
971 | 195 | } |
972 | 237 | } |
973 | 195 | break; |
974 | 237 | } |
975 | 1.89k | case DAK_Custom: { |
976 | 1.89k | auto attr = cast<CustomAttr>(this); |
977 | 1.89k | if (auto type = |
978 | 1.89k | D->getResolvedCustomAttrType(const_cast<CustomAttr *>(attr))) { |
979 | | // Print custom attributes only if the attribute decl is accessible. |
980 | | // FIXME: rdar://85477478 They should be rejected. |
981 | 1.87k | if (auto attrDecl = type->getNominalOrBoundGenericNominal()) { |
982 | 1.13k | if (attrDecl->getFormalAccess() < Options.AccessFilter) { |
983 | 0 | return false; |
984 | 0 | } |
985 | 1.13k | } |
986 | 1.87k | } |
987 | | |
988 | 1.89k | if (!Options.IsForSwiftInterface) |
989 | 1.68k | break; |
990 | | // For Swift interface, we should print result builder attributes |
991 | | // on parameter decls and on protocol requirements. |
992 | | // Printing the attribute elsewhere isn't ABI relevant. |
993 | 213 | if (auto *VD = dyn_cast<ValueDecl>(D)) { |
994 | 213 | if (VD->getAttachedResultBuilder() == this) { |
995 | 18 | if (!isa<ParamDecl>(D) && |
996 | 18 | !((isa<VarDecl>(D) || isa<FuncDecl>(D)) && |
997 | 12 | isa<ProtocolDecl>(D->getDeclContext()))) |
998 | 6 | return false; |
999 | 18 | } |
1000 | 213 | } |
1001 | 207 | break; |
1002 | 213 | } |
1003 | 189k | default: |
1004 | 189k | break; |
1005 | 220k | } |
1006 | | |
1007 | | // Handle any decl-modifiers. |
1008 | | // FIXME: Ideally we would handle decl modifiers as a special kind of |
1009 | | // attribute, but for now it's simpler to treat them as a keyword in the |
1010 | | // printer. |
1011 | 210k | switch (getKind()) { |
1012 | | // Handle all of the SIMPLE_DECL_ATTRs. |
1013 | 5.03M | #define SIMPLE_DECL_ATTR(X, CLASS, ...) case DAK_##CLASS: |
1014 | 5.03M | #include "swift/AST/Attr.def" |
1015 | 5.03M | case DAK_Inline: |
1016 | 112k | case DAK_AccessControl: |
1017 | 113k | case DAK_ReferenceOwnership: |
1018 | 113k | case DAK_Effects: |
1019 | 113k | case DAK_Optimize: |
1020 | 113k | case DAK_Exclusivity: |
1021 | 115k | case DAK_NonSendable: |
1022 | 115k | case DAK_ObjCImplementation: |
1023 | 115k | if (getKind() == DAK_Effects && |
1024 | 115k | cast<EffectsAttr>(this)->getKind() == EffectsKind::Custom) { |
1025 | 3 | Printer.printAttrName("@_effects"); |
1026 | 3 | Printer << "(" << cast<EffectsAttr>(this)->getCustomString() << ")"; |
1027 | 115k | } else if (DeclAttribute::isDeclModifier(getKind())) { |
1028 | 39.7k | Printer.printKeyword(getAttrName(), Options); |
1029 | 75.5k | } else if (Options.IsForSwiftInterface && getKind() == DAK_ResultBuilder) { |
1030 | | // Use @_functionBuilder in Swift interfaces to maintain backward |
1031 | | // compatibility. |
1032 | 6 | Printer.printSimpleAttr("_functionBuilder", /*needAt=*/true); |
1033 | 75.5k | } else { |
1034 | 75.5k | Printer.printSimpleAttr(getAttrName(), /*needAt=*/true); |
1035 | 75.5k | } |
1036 | 115k | return true; |
1037 | | |
1038 | 45 | case DAK_MainType: { |
1039 | | // Don't print into SIL. Necessary bits have already been generated. |
1040 | 45 | if (Options.PrintForSIL) |
1041 | 42 | return false; |
1042 | 3 | Printer.printSimpleAttr(getAttrName(), /*needAt=*/true); |
1043 | 3 | return true; |
1044 | 45 | } |
1045 | | |
1046 | 105 | case DAK_SetterAccess: |
1047 | 105 | Printer.printKeyword(getAttrName(), Options, "(set)"); |
1048 | 105 | return true; |
1049 | | |
1050 | 18 | case DAK_SPIAccessControl: { |
1051 | 18 | if (Options.printPublicInterface()) return false; |
1052 | | |
1053 | 0 | auto spiAttr = static_cast<const SPIAccessControlAttr*>(this); |
1054 | 0 | interleave(spiAttr->getSPIGroups(), |
1055 | 0 | [&](Identifier spiName) { |
1056 | 0 | Printer.printAttrName(getAttrName(), true); |
1057 | 0 | Printer << "(" << spiName << ")"; |
1058 | 0 | }, |
1059 | 0 | [&] { Printer << " "; }); |
1060 | 0 | return true; |
1061 | 18 | } |
1062 | | |
1063 | 95.2k | default: |
1064 | 95.2k | break; |
1065 | 210k | } |
1066 | | |
1067 | 95.2k | Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute); |
1068 | 95.2k | SWIFT_DEFER { |
1069 | 95.2k | Printer.printStructurePost(PrintStructureKind::BuiltinAttribute); |
1070 | 95.2k | }; |
1071 | | |
1072 | 95.2k | switch (getKind()) { |
1073 | 4.47k | case DAK_Semantics: |
1074 | 4.47k | Printer.printAttrName("@_semantics"); |
1075 | 4.47k | Printer << "(\"" << cast<SemanticsAttr>(this)->Value << "\")"; |
1076 | 4.47k | break; |
1077 | | |
1078 | 237 | case DAK_Alignment: |
1079 | 237 | Printer.printAttrName("@_alignment"); |
1080 | 237 | Printer << "(" << cast<AlignmentAttr>(this)->getValue() << ")"; |
1081 | 237 | break; |
1082 | | |
1083 | 1.18k | case DAK_SILGenName: |
1084 | 1.18k | Printer.printAttrName("@_silgen_name"); |
1085 | 1.18k | Printer << "(\"" << cast<SILGenNameAttr>(this)->Name << "\")"; |
1086 | 1.18k | break; |
1087 | | |
1088 | 102 | case DAK_OriginallyDefinedIn: { |
1089 | 102 | Printer.printAttrName("@_originallyDefinedIn"); |
1090 | 102 | Printer << "(module: "; |
1091 | 102 | auto Attr = cast<OriginallyDefinedInAttr>(this); |
1092 | 102 | Printer << "\"" << Attr->OriginalModuleName << "\", "; |
1093 | 102 | Printer << platformString(Attr->Platform) << " " << |
1094 | 102 | Attr->MovedVersion.getAsString(); |
1095 | 102 | Printer << ")"; |
1096 | 102 | break; |
1097 | 0 | } |
1098 | | |
1099 | 68.7k | case DAK_Available: { |
1100 | 68.7k | auto Attr = cast<AvailableAttr>(this); |
1101 | 68.7k | if (Options.SuppressNoAsyncAvailabilityAttr && Attr->isNoAsync()) |
1102 | 3 | return false; |
1103 | 68.6k | if (Options.printPublicInterface() && Attr->IsSPI) { |
1104 | 42 | assert(Attr->hasPlatform()); |
1105 | 0 | assert(Attr->Introduced.has_value()); |
1106 | 0 | Printer.printAttrName("@available"); |
1107 | 42 | Printer << "("; |
1108 | 42 | Printer << Attr->platformString(); |
1109 | 42 | Printer << ", unavailable)"; |
1110 | 42 | break; |
1111 | 42 | } |
1112 | 68.6k | if (Attr->IsSPI) { |
1113 | 54 | std::string atSPI = (llvm::Twine("@") + SPI_AVAILABLE_ATTRNAME).str(); |
1114 | 54 | Printer.printAttrName(atSPI); |
1115 | 68.6k | } else { |
1116 | 68.6k | Printer.printAttrName("@available"); |
1117 | 68.6k | } |
1118 | 68.6k | Printer << "("; |
1119 | 68.6k | printAvailableAttr(Attr, Printer, Options); |
1120 | 68.6k | Printer << ")"; |
1121 | 68.6k | break; |
1122 | 68.6k | } |
1123 | | |
1124 | 45 | case DAK_CDecl: |
1125 | 45 | Printer << "@_cdecl(\"" << cast<CDeclAttr>(this)->Name << "\")"; |
1126 | 45 | break; |
1127 | | |
1128 | 66 | case DAK_Expose: { |
1129 | 66 | Printer.printAttrName("@_expose"); |
1130 | 66 | auto Attr = cast<ExposeAttr>(this); |
1131 | 66 | switch (Attr->getExposureKind()) { |
1132 | 0 | case ExposureKind::Wasm: |
1133 | 0 | Printer << "(wasm"; |
1134 | 0 | break; |
1135 | 66 | case ExposureKind::Cxx: |
1136 | 66 | Printer << "(Cxx"; |
1137 | 66 | break; |
1138 | 66 | } |
1139 | 66 | if (!cast<ExposeAttr>(this)->Name.empty()) |
1140 | 36 | Printer << ", \"" << cast<ExposeAttr>(this)->Name << "\""; |
1141 | 66 | Printer << ")"; |
1142 | 66 | break; |
1143 | 66 | } |
1144 | | |
1145 | 39 | case DAK_Extern: { |
1146 | 39 | auto *Attr = cast<ExternAttr>(this); |
1147 | 39 | Printer.printAttrName("@_extern"); |
1148 | 39 | Printer << "("; |
1149 | 39 | switch (Attr->getExternKind()) { |
1150 | 33 | case ExternKind::C: |
1151 | 33 | Printer << "c"; |
1152 | | // Symbol name can be omitted for C. |
1153 | 33 | if (auto cName = Attr->Name) |
1154 | 27 | Printer << ", \"" << *cName << "\""; |
1155 | 33 | break; |
1156 | 6 | case ExternKind::Wasm: |
1157 | 6 | Printer << "wasm"; |
1158 | | // @_extern(wasm) always has names. |
1159 | 6 | Printer << ", module: \"" << *Attr->ModuleName << "\""; |
1160 | 6 | Printer << ", name: \"" << *Attr->Name << "\""; |
1161 | 6 | break; |
1162 | 39 | } |
1163 | 39 | Printer << ")"; |
1164 | 39 | break; |
1165 | 39 | } |
1166 | | |
1167 | 30 | case DAK_Section: |
1168 | 30 | Printer.printAttrName("@_section"); |
1169 | 30 | Printer << "(\"" << cast<SectionAttr>(this)->Name << "\")"; |
1170 | 30 | break; |
1171 | | |
1172 | 11.9k | case DAK_ObjC: { |
1173 | 11.9k | Printer.printAttrName("@objc"); |
1174 | 11.9k | llvm::SmallString<32> scratch; |
1175 | 11.9k | if (auto Name = cast<ObjCAttr>(this)->getName()) { |
1176 | 3.27k | if (!cast<ObjCAttr>(this)->isNameImplicit()) |
1177 | 1.21k | Printer << "(" << Name->getString(scratch) << ")"; |
1178 | 3.27k | } |
1179 | 11.9k | break; |
1180 | 39 | } |
1181 | | |
1182 | 39 | case DAK_PrivateImport: { |
1183 | 39 | Printer.printAttrName("@_private(sourceFile: \""); |
1184 | 39 | Printer << cast<PrivateImportAttr>(this)->getSourceFile() << "\")"; |
1185 | 39 | break; |
1186 | 39 | } |
1187 | | |
1188 | 18 | case DAK_SwiftNativeObjCRuntimeBase: { |
1189 | 18 | auto *attr = cast<SwiftNativeObjCRuntimeBaseAttr>(this); |
1190 | 18 | Printer.printAttrName("@_swift_native_objc_runtime_base"); |
1191 | 18 | Printer << "(" << attr->BaseClassName.str() << ")"; |
1192 | 18 | break; |
1193 | 39 | } |
1194 | | |
1195 | 2.37k | case DAK_Specialize: { |
1196 | 2.37k | auto *attr = cast<SpecializeAttr>(this); |
1197 | | // Don't print the _specialize attribute if it is marked spi and we are |
1198 | | // asked to skip SPI. |
1199 | 2.37k | if (Options.printPublicInterface() && !attr->getSPIGroups().empty()) |
1200 | 84 | return false; |
1201 | | |
1202 | | // Don't print the _specialize attribute if we are asked to skip the ones |
1203 | | // with availability parameters. |
1204 | 2.29k | if (!Options.PrintSpecializeAttributeWithAvailability && |
1205 | 2.29k | !attr->getAvailableAttrs().empty()) |
1206 | 30 | return false; |
1207 | | |
1208 | 2.26k | Printer << "@" << getAttrName() << "("; |
1209 | 2.26k | auto exported = attr->isExported() ? "true" : "false"; |
1210 | 2.26k | auto kind = attr->isPartialSpecialization() ? "partial" : "full"; |
1211 | 2.26k | auto target = attr->getTargetFunctionName(); |
1212 | 2.26k | Printer << "exported: "<< exported << ", "; |
1213 | 2.26k | for (auto id : attr->getSPIGroups()) { |
1214 | 90 | Printer << "spi: " << id << ", "; |
1215 | 90 | } |
1216 | 2.26k | Printer << "kind: " << kind << ", "; |
1217 | 2.26k | if (target) |
1218 | 561 | Printer << "target: " << target << ", "; |
1219 | 2.26k | auto availAttrs = attr->getAvailableAttrs(); |
1220 | 2.26k | if (!availAttrs.empty()) { |
1221 | 162 | Printer << "availability: "; |
1222 | 162 | auto numAttrs = availAttrs.size(); |
1223 | 162 | if (numAttrs == 1) { |
1224 | 90 | printAvailableAttr(availAttrs[0], Printer, Options); |
1225 | 90 | Printer << "; "; |
1226 | 90 | } else { |
1227 | 72 | SmallVector<const DeclAttribute *, 8> tmp(availAttrs.begin(), |
1228 | 72 | availAttrs.end()); |
1229 | 72 | printShortFormAvailable(tmp, Printer, Options, |
1230 | 72 | true /*forAtSpecialize*/); |
1231 | 72 | Printer << "; "; |
1232 | 72 | } |
1233 | 162 | } |
1234 | 2.26k | SmallVector<Requirement, 4> requirementsScratch; |
1235 | 2.26k | auto *FnDecl = dyn_cast_or_null<AbstractFunctionDecl>(D); |
1236 | 2.26k | auto specializedSig = attr->getSpecializedSignature(FnDecl); |
1237 | 2.26k | auto requirements = specializedSig.getRequirements(); |
1238 | 2.26k | if (FnDecl && FnDecl->getGenericSignature()) { |
1239 | 2.25k | auto genericSig = FnDecl->getGenericSignature(); |
1240 | | |
1241 | 2.25k | if (auto sig = specializedSig) { |
1242 | 2.25k | requirementsScratch = sig.requirementsNotSatisfiedBy(genericSig); |
1243 | 2.25k | requirements = requirementsScratch; |
1244 | 2.25k | } |
1245 | 2.25k | } |
1246 | | |
1247 | 2.26k | if (!requirements.empty()) { |
1248 | 2.22k | Printer << "where "; |
1249 | 2.22k | } |
1250 | | |
1251 | 2.26k | interleave(requirements, |
1252 | 2.55k | [&](Requirement req) { |
1253 | 2.55k | bool typeErased = false; |
1254 | 2.55k | if (req.getKind() == RequirementKind::Layout && |
1255 | 2.55k | !attr->getTypeErasedParams().empty()) { |
1256 | 132 | const auto &erasedParams = attr->getTypeErasedParams(); |
1257 | 132 | typeErased = std::any_of(erasedParams.begin(), |
1258 | 132 | erasedParams.end(), |
1259 | 135 | [&](Type t) { return t->isEqual(req.getFirstType()); }); |
1260 | 132 | if (typeErased) |
1261 | 132 | Printer << "@_noMetadata "; |
1262 | 132 | } |
1263 | 2.55k | auto OptionsCopy = Options; |
1264 | 2.55k | OptionsCopy.PrintClassLayoutName = typeErased; |
1265 | 2.55k | req.print(Printer, OptionsCopy); |
1266 | 2.55k | }, |
1267 | 2.26k | [&] { Printer << ", "; }); |
1268 | | |
1269 | 2.26k | Printer << ")"; |
1270 | 2.26k | break; |
1271 | 2.29k | } |
1272 | | |
1273 | 921 | case DAK_Implements: { |
1274 | 921 | Printer.printAttrName("@_implements"); |
1275 | 921 | Printer << "("; |
1276 | 921 | auto *attr = cast<ImplementsAttr>(this); |
1277 | 921 | if (auto *proto = attr->getProtocol(D->getDeclContext())) |
1278 | 921 | proto->getDeclaredInterfaceType()->print(Printer, Options); |
1279 | 0 | else |
1280 | 0 | attr->getProtocolTypeRepr()->print(Printer, Options); |
1281 | 921 | Printer << ", " << attr->getMemberName() << ")"; |
1282 | 921 | break; |
1283 | 2.29k | } |
1284 | | |
1285 | 9 | case DAK_ObjCRuntimeName: { |
1286 | 9 | Printer.printAttrName("@_objcRuntimeName"); |
1287 | 9 | Printer << "("; |
1288 | 9 | auto *attr = cast<ObjCRuntimeNameAttr>(this); |
1289 | 9 | Printer << attr->Name; |
1290 | 9 | Printer << ")"; |
1291 | 9 | break; |
1292 | 2.29k | } |
1293 | | |
1294 | 12 | case DAK_ClangImporterSynthesizedType: { |
1295 | 12 | Printer.printAttrName("@_clangImporterSynthesizedType"); |
1296 | 12 | auto *attr = cast<ClangImporterSynthesizedTypeAttr>(this); |
1297 | 12 | Printer << "(originalTypeName: \"" << attr->originalTypeName |
1298 | 12 | << "\", manglingForKind: \"" << attr->getManglingName() << "\")"; |
1299 | 12 | break; |
1300 | 2.29k | } |
1301 | | |
1302 | 177 | case DAK_DynamicReplacement: { |
1303 | 177 | Printer.printAttrName("@_dynamicReplacement"); |
1304 | 177 | Printer << "(for: \""; |
1305 | 177 | auto *attr = cast<DynamicReplacementAttr>(this); |
1306 | 177 | Printer << attr->getReplacedFunctionName() << "\")"; |
1307 | 177 | break; |
1308 | 2.29k | } |
1309 | | |
1310 | 0 | case DAK_TypeEraser: { |
1311 | 0 | Printer.printAttrName("@_typeEraser"); |
1312 | 0 | Printer << "("; |
1313 | 0 | Printer.callPrintNamePre(PrintNameContext::Attribute); |
1314 | 0 | auto *attr = cast<TypeEraserAttr>(this); |
1315 | 0 | if (auto *repr = attr->getParsedTypeEraserTypeRepr()) |
1316 | 0 | repr->print(Printer, Options); |
1317 | 0 | else if (auto proto = dyn_cast<ProtocolDecl>(D)) |
1318 | 0 | attr->getResolvedType(proto)->print(Printer, Options); |
1319 | 0 | Printer.printNamePost(PrintNameContext::Attribute); |
1320 | 0 | Printer << ")"; |
1321 | 0 | break; |
1322 | 2.29k | } |
1323 | | |
1324 | 1.88k | case DAK_Custom: { |
1325 | 1.88k | Printer.callPrintNamePre(PrintNameContext::Attribute); |
1326 | 1.88k | Printer << "@"; |
1327 | 1.88k | auto *attr = cast<CustomAttr>(this); |
1328 | 1.88k | if (auto type = attr->getType()) |
1329 | 1.87k | type.print(Printer, Options); |
1330 | 18 | else |
1331 | 18 | attr->getTypeRepr()->print(Printer, Options); |
1332 | 1.88k | if (attr->isArgUnsafe() && Options.IsForSwiftInterface) |
1333 | 0 | Printer << "(unsafe)"; |
1334 | 1.88k | Printer.printNamePost(PrintNameContext::Attribute); |
1335 | 1.88k | break; |
1336 | 2.29k | } |
1337 | | |
1338 | 141 | case DAK_ProjectedValueProperty: |
1339 | 141 | Printer.printAttrName("@_projectedValueProperty"); |
1340 | 141 | Printer << "("; |
1341 | 141 | Printer << cast<ProjectedValuePropertyAttr>(this)->ProjectionPropertyName; |
1342 | 141 | Printer << ")"; |
1343 | 141 | break; |
1344 | | |
1345 | 700 | case DAK_Differentiable: { |
1346 | 700 | Printer.printAttrName("@differentiable"); |
1347 | 700 | auto *attr = cast<DifferentiableAttr>(this); |
1348 | 700 | printDifferentiableAttrArguments(attr, Printer, Options, D); |
1349 | 700 | break; |
1350 | 2.29k | } |
1351 | | |
1352 | 276 | case DAK_Derivative: { |
1353 | 276 | Printer.printAttrName("@derivative"); |
1354 | 276 | Printer << "(of: "; |
1355 | 276 | auto *attr = cast<DerivativeAttr>(this); |
1356 | 276 | if (auto *baseType = attr->getBaseTypeRepr()) |
1357 | 0 | baseType->print(Printer, Options); |
1358 | 276 | attr->getOriginalFunctionName().print(Printer); |
1359 | 276 | auto *derivative = cast<AbstractFunctionDecl>(D); |
1360 | 276 | auto diffParamsString = getDifferentiationParametersClauseString( |
1361 | 276 | derivative, attr->getParameterIndices(), attr->getParsedParameters(), |
1362 | 276 | DifferentiationParameterKind::Differentiability); |
1363 | 276 | if (!diffParamsString.empty()) |
1364 | 276 | Printer << ", " << diffParamsString; |
1365 | 276 | Printer << ')'; |
1366 | 276 | break; |
1367 | 2.29k | } |
1368 | | |
1369 | 28 | case DAK_Transpose: { |
1370 | 28 | Printer.printAttrName("@transpose"); |
1371 | 28 | Printer << "(of: "; |
1372 | 28 | auto *attr = cast<TransposeAttr>(this); |
1373 | 28 | if (auto *baseType = attr->getBaseTypeRepr()) |
1374 | 0 | baseType->print(Printer, Options); |
1375 | 28 | attr->getOriginalFunctionName().print(Printer); |
1376 | 28 | auto *transpose = cast<AbstractFunctionDecl>(D); |
1377 | 28 | auto transParamsString = getDifferentiationParametersClauseString( |
1378 | 28 | transpose, attr->getParameterIndices(), attr->getParsedParameters(), |
1379 | 28 | DifferentiationParameterKind::Linearity); |
1380 | 28 | if (!transParamsString.empty()) |
1381 | 28 | Printer << ", " << transParamsString; |
1382 | 28 | Printer << ')'; |
1383 | 28 | break; |
1384 | 2.29k | } |
1385 | | |
1386 | 369 | case DAK_UnavailableFromAsync: { |
1387 | 369 | Printer.printAttrName("@_unavailableFromAsync"); |
1388 | 369 | const UnavailableFromAsyncAttr *attr = cast<UnavailableFromAsyncAttr>(this); |
1389 | 369 | if (attr->hasMessage()) { |
1390 | 366 | Printer << "(message: \""; |
1391 | 366 | Printer << attr->Message; |
1392 | 366 | Printer << "\")"; |
1393 | 366 | } |
1394 | 369 | break; |
1395 | 2.29k | } |
1396 | | |
1397 | 0 | case DAK_BackDeployed: { |
1398 | 0 | Printer.printAttrName("@backDeployed"); |
1399 | 0 | Printer << "(before: "; |
1400 | 0 | auto Attr = cast<BackDeployedAttr>(this); |
1401 | 0 | Printer << platformString(Attr->Platform) << " " << |
1402 | 0 | Attr->Version.getAsString(); |
1403 | 0 | Printer << ")"; |
1404 | 0 | break; |
1405 | 2.29k | } |
1406 | | |
1407 | 933 | case DAK_Nonisolated: { |
1408 | 933 | Printer.printAttrName("nonisolated"); |
1409 | 933 | if (cast<NonisolatedAttr>(this)->isUnsafe()) { |
1410 | 18 | Printer << "(unsafe)"; |
1411 | 18 | } |
1412 | 933 | break; |
1413 | 2.29k | } |
1414 | | |
1415 | 369 | case DAK_MacroRole: { |
1416 | 369 | auto Attr = cast<MacroRoleAttr>(this); |
1417 | | |
1418 | | // Suppress @attached(extension) if needed. |
1419 | 369 | if (!Options.PrintExtensionMacroAttributes && |
1420 | 369 | Attr->getMacroRole() == MacroRole::Extension) { |
1421 | 3 | break; |
1422 | 3 | } |
1423 | | |
1424 | 366 | switch (Attr->getMacroSyntax()) { |
1425 | 300 | case MacroSyntax::Freestanding: |
1426 | 300 | Printer.printAttrName("@freestanding"); |
1427 | 300 | break; |
1428 | | |
1429 | 66 | case MacroSyntax::Attached: |
1430 | 66 | Printer.printAttrName("@attached"); |
1431 | 66 | break; |
1432 | 366 | } |
1433 | 366 | Printer << "("; |
1434 | 366 | Printer << getMacroRoleString(Attr->getMacroRole()); |
1435 | | |
1436 | | // Print conformances, if present. |
1437 | 366 | auto conformances = evaluateOrDefault( |
1438 | 366 | D->getASTContext().evaluator, |
1439 | 366 | ResolveMacroConformances{Attr, D}, |
1440 | 366 | {}); |
1441 | 366 | if (!conformances.empty()) { |
1442 | 9 | Printer << ", conformances: "; |
1443 | 9 | interleave(conformances, |
1444 | 9 | [&](Type type) { |
1445 | 9 | type.print(Printer, Options); |
1446 | 9 | }, |
1447 | 9 | [&] { |
1448 | 0 | Printer << ", "; |
1449 | 0 | }); |
1450 | 9 | } |
1451 | | |
1452 | 366 | if (!Attr->getNames().empty()) { |
1453 | 105 | Printer << ", names: "; |
1454 | 105 | interleave( |
1455 | 105 | Attr->getNames(), |
1456 | 141 | [&](MacroIntroducedDeclName name) { |
1457 | 141 | Printer << getMacroIntroducedDeclNameString(name.getKind()); |
1458 | 141 | if (macroIntroducedNameRequiresArgument(name.getKind())) { |
1459 | 102 | SmallString<32> buffer; |
1460 | 102 | StringRef nameText = name.getName().getString(buffer); |
1461 | 102 | bool shouldEscape = |
1462 | 102 | !name.getName().isSpecial() && |
1463 | 102 | (escapeKeywordInContext(nameText, PrintNameContext::Normal) || |
1464 | 87 | nameText == "$"); |
1465 | 102 | Printer << "("; |
1466 | 102 | if (shouldEscape) |
1467 | 9 | Printer << "`"; |
1468 | 102 | Printer << nameText; |
1469 | 102 | if (shouldEscape) |
1470 | 9 | Printer << "`"; |
1471 | 102 | Printer << ")"; |
1472 | 102 | } |
1473 | 141 | }, |
1474 | 105 | [&] { |
1475 | 36 | Printer << ", "; |
1476 | 36 | } |
1477 | 105 | ); |
1478 | 105 | } |
1479 | 366 | Printer << ")"; |
1480 | 366 | break; |
1481 | 366 | } |
1482 | | |
1483 | 0 | case DAK_Documentation: { |
1484 | 0 | auto *attr = cast<DocumentationAttr>(this); |
1485 | |
|
1486 | 0 | Printer.printAttrName("@_documentation"); |
1487 | 0 | Printer << "("; |
1488 | |
|
1489 | 0 | bool needs_comma = !attr->Metadata.empty() && attr->Visibility; |
1490 | |
|
1491 | 0 | if (attr->Visibility) { |
1492 | 0 | Printer << "visibility: "; |
1493 | 0 | Printer << getAccessLevelSpelling(*attr->Visibility); |
1494 | 0 | } |
1495 | |
|
1496 | 0 | if (needs_comma) { |
1497 | 0 | Printer << ", "; |
1498 | 0 | } |
1499 | |
|
1500 | 0 | if (!attr->Metadata.empty()) { |
1501 | 0 | Printer << "metadata: "; |
1502 | 0 | Printer << attr->Metadata; |
1503 | 0 | } |
1504 | |
|
1505 | 0 | Printer << ")"; |
1506 | 0 | break; |
1507 | 366 | } |
1508 | | |
1509 | 21 | case DAK_RawLayout: { |
1510 | 21 | auto *attr = cast<RawLayoutAttr>(this); |
1511 | 21 | Printer.printAttrName("@_rawLayout"); |
1512 | 21 | Printer << "("; |
1513 | | |
1514 | 21 | if (auto sizeAndAlign = attr->getSizeAndAlignment()) { |
1515 | 9 | Printer << "size: " << sizeAndAlign->first |
1516 | 9 | << ", alignment: " << sizeAndAlign->second; |
1517 | 12 | } else if (auto type = attr->getScalarLikeType()) { |
1518 | 6 | Printer << "like: "; |
1519 | 6 | type->print(Printer, Options); |
1520 | 6 | } else if (auto array = attr->getArrayLikeTypeAndCount()) { |
1521 | 6 | Printer << "likeArrayOf: "; |
1522 | 6 | array->first->print(Printer, Options); |
1523 | 6 | Printer << ", count: " << array->second; |
1524 | 6 | } else { |
1525 | 0 | llvm_unreachable("unhandled @_rawLayout form"); |
1526 | 0 | } |
1527 | 21 | Printer << ")"; |
1528 | 21 | break; |
1529 | 366 | } |
1530 | | |
1531 | 63 | case DAK_StorageRestrictions: { |
1532 | 63 | auto *attr = cast<StorageRestrictionsAttr>(this); |
1533 | 63 | Printer.printAttrName("@storageRestrictions"); |
1534 | 63 | Printer << "("; |
1535 | | |
1536 | 63 | auto initializes = attr->getInitializesNames(); |
1537 | 63 | auto accesses = attr->getAccessesNames(); |
1538 | | |
1539 | 63 | bool needsComma = !initializes.empty() && !accesses.empty(); |
1540 | | |
1541 | 63 | if (!initializes.empty()) { |
1542 | 45 | Printer << "initializes: "; |
1543 | 45 | interleave(initializes, Printer, ", "); |
1544 | 45 | } |
1545 | | |
1546 | 63 | if (needsComma) |
1547 | 6 | Printer << ", "; |
1548 | | |
1549 | 63 | if (!accesses.empty()) { |
1550 | 24 | Printer << "accesses: "; |
1551 | 24 | interleave(accesses, Printer, ", "); |
1552 | 24 | } |
1553 | 63 | Printer << ")"; |
1554 | 63 | break; |
1555 | 366 | } |
1556 | | |
1557 | 0 | case DAK_Count: |
1558 | 0 | llvm_unreachable("exceed declaration attribute kinds"); |
1559 | |
|
1560 | 0 | #define SIMPLE_DECL_ATTR(X, CLASS, ...) case DAK_##CLASS: |
1561 | 0 | #include "swift/AST/Attr.def" |
1562 | 0 | llvm_unreachable("handled above"); |
1563 | |
|
1564 | 0 | default: |
1565 | 0 | assert(DeclAttribute::isDeclModifier(getKind()) && |
1566 | 95.2k | "handled above"); |
1567 | 95.2k | } |
1568 | | |
1569 | 95.0k | return true; |
1570 | 95.2k | } |
1571 | | |
1572 | | void DeclAttribute::print(ASTPrinter &Printer, const PrintOptions &Options, |
1573 | 220k | const Decl *D) const { |
1574 | | |
1575 | 220k | if (!printImpl(Printer, Options, D)) |
1576 | 10.0k | return; // Nothing printed. |
1577 | | |
1578 | 210k | if (isLongAttribute() && Options.PrintLongAttrsOnSeparateLines) |
1579 | 78.4k | Printer.printNewline(); |
1580 | 132k | else |
1581 | 132k | Printer << " "; |
1582 | 210k | } |
1583 | | |
1584 | 0 | void DeclAttribute::print(llvm::raw_ostream &OS, const Decl *D) const { |
1585 | 0 | StreamPrinter P(OS); |
1586 | 0 | print(P, PrintOptions(), D); |
1587 | 0 | } |
1588 | | |
1589 | 29.6M | uint64_t DeclAttribute::getOptions(DeclAttrKind DK) { |
1590 | 29.6M | switch (DK) { |
1591 | 0 | case DAK_Count: |
1592 | 0 | llvm_unreachable("getOptions needs a valid attribute"); |
1593 | 0 | #define DECL_ATTR(_, CLASS, OPTIONS, ...)\ |
1594 | 29.6M | case DAK_##CLASS: return OPTIONS; |
1595 | 29.6M | #include "swift/AST/Attr.def" |
1596 | 29.6M | } |
1597 | 0 | llvm_unreachable("bad DeclAttrKind"); |
1598 | 0 | } |
1599 | | |
1600 | 124k | StringRef DeclAttribute::getAttrName() const { |
1601 | 124k | switch (getKind()) { |
1602 | 0 | case DAK_Count: |
1603 | 0 | llvm_unreachable("getAttrName needs a valid attribute"); |
1604 | 0 | #define SIMPLE_DECL_ATTR(NAME, CLASS, ...) \ |
1605 | 86.4k | case DAK_##CLASS: \ |
1606 | 86.4k | return #NAME; |
1607 | 0 | #include "swift/AST/Attr.def" |
1608 | 9 | case DAK_SILGenName: |
1609 | 9 | return "_silgen_name"; |
1610 | 12 | case DAK_Alignment: |
1611 | 12 | return "_alignment"; |
1612 | 21 | case DAK_CDecl: |
1613 | 21 | return "_cdecl"; |
1614 | 0 | case DAK_SwiftNativeObjCRuntimeBase: |
1615 | 0 | return "_swift_native_objc_runtime_base"; |
1616 | 0 | case DAK_Semantics: |
1617 | 0 | return "_semantics"; |
1618 | 12 | case DAK_Available: |
1619 | 12 | return "available"; |
1620 | 117 | case DAK_ObjC: |
1621 | 117 | case DAK_ObjCRuntimeName: |
1622 | 117 | return "objc"; |
1623 | 3 | case DAK_ObjCImplementation: |
1624 | 3 | return "_objcImplementation"; |
1625 | 6 | case DAK_MainType: |
1626 | 6 | return "main"; |
1627 | 0 | case DAK_DynamicReplacement: |
1628 | 0 | return "_dynamicReplacement"; |
1629 | 3 | case DAK_TypeEraser: |
1630 | 3 | return "_typeEraser"; |
1631 | 3 | case DAK_PrivateImport: |
1632 | 3 | return "_private"; |
1633 | 0 | case DAK_RestatedObjCConformance: |
1634 | 0 | return "_restatedObjCConformance"; |
1635 | 6.34k | case DAK_Inline: { |
1636 | 6.34k | switch (cast<InlineAttr>(this)->getKind()) { |
1637 | 3.29k | case InlineKind::Never: |
1638 | 3.29k | return "inline(never)"; |
1639 | 3.04k | case InlineKind::Always: |
1640 | 3.04k | return "inline(__always)"; |
1641 | 6.34k | } |
1642 | 0 | llvm_unreachable("Invalid inline kind"); |
1643 | 0 | } |
1644 | 1.43k | case DAK_NonSendable: { |
1645 | 1.43k | switch (cast<NonSendableAttr>(this)->Specificity) { |
1646 | 60 | case NonSendableKind::Specific: |
1647 | 60 | return "_nonSendable"; |
1648 | 1.37k | case NonSendableKind::Assumed: |
1649 | 1.37k | return "_nonSendable(_assumed)"; |
1650 | 1.43k | } |
1651 | 0 | llvm_unreachable("Invalid nonSendable kind"); |
1652 | 0 | } |
1653 | 306 | case DAK_Optimize: { |
1654 | 306 | switch (cast<OptimizeAttr>(this)->getMode()) { |
1655 | 273 | case OptimizationMode::NoOptimization: |
1656 | 273 | return "_optimize(none)"; |
1657 | 24 | case OptimizationMode::ForSpeed: |
1658 | 24 | return "_optimize(speed)"; |
1659 | 9 | case OptimizationMode::ForSize: |
1660 | 9 | return "_optimize(size)"; |
1661 | 0 | default: |
1662 | 0 | llvm_unreachable("Invalid optimization kind"); |
1663 | 306 | } |
1664 | 306 | } |
1665 | 60 | case DAK_Exclusivity: { |
1666 | 60 | switch (cast<ExclusivityAttr>(this)->getMode()) { |
1667 | 21 | case ExclusivityAttr::Checked: |
1668 | 21 | return "exclusivity(checked)"; |
1669 | 39 | case ExclusivityAttr::Unchecked: |
1670 | 39 | return "exclusivity(unchecked)"; |
1671 | 60 | } |
1672 | 0 | llvm_unreachable("Invalid optimization kind"); |
1673 | 0 | } |
1674 | 534 | case DAK_Effects: |
1675 | 534 | switch (cast<EffectsAttr>(this)->getKind()) { |
1676 | 81 | case EffectsKind::ReadNone: |
1677 | 81 | return "_effects(readnone)"; |
1678 | 453 | case EffectsKind::ReadOnly: |
1679 | 453 | return "_effects(readonly)"; |
1680 | 0 | case EffectsKind::ReleaseNone: |
1681 | 0 | return "_effects(releasenone)"; |
1682 | 0 | case EffectsKind::ReadWrite: |
1683 | 0 | return "_effects(readwrite)"; |
1684 | 0 | case EffectsKind::Unspecified: |
1685 | 0 | return "_effects(unspecified)"; |
1686 | 0 | case EffectsKind::Custom: |
1687 | 0 | return "_effects"; |
1688 | 534 | } |
1689 | 20.5k | case DAK_AccessControl: |
1690 | 20.6k | case DAK_SetterAccess: { |
1691 | 20.6k | AccessLevel access = cast<AbstractAccessControlAttr>(this)->getAccess(); |
1692 | 20.6k | return getAccessLevelSpelling(access); |
1693 | 20.5k | } |
1694 | | |
1695 | 3 | case DAK_SPIAccessControl: |
1696 | 3 | return "_spi"; |
1697 | 588 | case DAK_ReferenceOwnership: |
1698 | 588 | return keywordOf(cast<ReferenceOwnershipAttr>(this)->get()); |
1699 | 0 | case DAK_RawDocComment: |
1700 | 0 | return "<<raw doc comment>>"; |
1701 | 0 | case DAK_ObjCBridged: |
1702 | 0 | return "<<ObjC bridged>>"; |
1703 | 0 | case DAK_SynthesizedProtocol: |
1704 | 0 | return "<<synthesized protocol>>"; |
1705 | 2.26k | case DAK_Specialize: |
1706 | 2.26k | return "_specialize"; |
1707 | 0 | case DAK_StorageRestrictions: |
1708 | 0 | return "storageRestrictions"; |
1709 | 0 | case DAK_Implements: |
1710 | 0 | return "_implements"; |
1711 | 0 | case DAK_ClangImporterSynthesizedType: |
1712 | 0 | return "_clangImporterSynthesizedType"; |
1713 | 0 | case DAK_Custom: |
1714 | 0 | return "<<custom>>"; |
1715 | 0 | case DAK_ProjectedValueProperty: |
1716 | 0 | return "_projectedValueProperty"; |
1717 | 39 | case DAK_OriginallyDefinedIn: |
1718 | 39 | return "_originallyDefinedIn"; |
1719 | 3.58k | case DAK_Differentiable: |
1720 | 3.58k | return "differentiable"; |
1721 | 1.42k | case DAK_Derivative: |
1722 | 1.42k | return "derivative"; |
1723 | 0 | case DAK_Transpose: |
1724 | 0 | return "transpose"; |
1725 | 60 | case DAK_UnavailableFromAsync: |
1726 | 60 | return "_unavailableFromAsync"; |
1727 | 153 | case DAK_BackDeployed: |
1728 | 153 | return "backDeployed"; |
1729 | 0 | case DAK_Expose: |
1730 | 0 | return "_expose"; |
1731 | 21 | case DAK_Section: |
1732 | 21 | return "_section"; |
1733 | 0 | case DAK_Documentation: |
1734 | 0 | return "_documentation"; |
1735 | 9 | case DAK_Nonisolated: |
1736 | 9 | if (cast<NonisolatedAttr>(this)->isUnsafe()) { |
1737 | 0 | return "nonisolated(unsafe)"; |
1738 | 9 | } else { |
1739 | 9 | return "nonisolated"; |
1740 | 9 | } |
1741 | 0 | case DAK_MacroRole: |
1742 | 0 | switch (cast<MacroRoleAttr>(this)->getMacroSyntax()) { |
1743 | 0 | case MacroSyntax::Freestanding: |
1744 | 0 | return "freestanding"; |
1745 | | |
1746 | 0 | case MacroSyntax::Attached: |
1747 | 0 | return "attached"; |
1748 | 0 | } |
1749 | 12 | case DAK_RawLayout: |
1750 | 12 | return "_rawLayout"; |
1751 | 3 | case DAK_Extern: |
1752 | 3 | return "_extern"; |
1753 | 124k | } |
1754 | 0 | llvm_unreachable("bad DeclAttrKind"); |
1755 | 0 | } |
1756 | | |
1757 | | ObjCAttr::ObjCAttr(SourceLoc atLoc, SourceRange baseRange, |
1758 | | llvm::Optional<ObjCSelector> name, SourceRange parenRange, |
1759 | | ArrayRef<SourceLoc> nameLocs) |
1760 | | : DeclAttribute(DAK_ObjC, atLoc, baseRange, /*Implicit=*/false), |
1761 | 35.6k | NameData(nullptr) { |
1762 | 35.6k | if (name) { |
1763 | | // Store the name. |
1764 | 3.45k | assert(name->getNumSelectorPieces() == nameLocs.size()); |
1765 | 0 | NameData = name->getOpaqueValue(); |
1766 | | |
1767 | | // Store location information. |
1768 | 3.45k | Bits.ObjCAttr.HasTrailingLocationInfo = true; |
1769 | 3.45k | getTrailingLocations()[0] = parenRange.Start; |
1770 | 3.45k | getTrailingLocations()[1] = parenRange.End; |
1771 | 3.45k | std::memcpy(getTrailingLocations().slice(2).data(), nameLocs.data(), |
1772 | 3.45k | nameLocs.size() * sizeof(SourceLoc)); |
1773 | 32.2k | } else { |
1774 | 32.2k | Bits.ObjCAttr.HasTrailingLocationInfo = false; |
1775 | 32.2k | } |
1776 | | |
1777 | 0 | Bits.ObjCAttr.ImplicitName = false; |
1778 | 35.6k | Bits.ObjCAttr.Swift3Inferred = false; |
1779 | 35.6k | } |
1780 | | |
1781 | | ObjCAttr *ObjCAttr::create(ASTContext &Ctx, llvm::Optional<ObjCSelector> name, |
1782 | 440k | bool isNameImplicit) { |
1783 | 440k | return new (Ctx) ObjCAttr(name, isNameImplicit); |
1784 | 440k | } |
1785 | | |
1786 | | ObjCAttr *ObjCAttr::createUnnamed(ASTContext &Ctx, SourceLoc AtLoc, |
1787 | 32.2k | SourceLoc ObjCLoc) { |
1788 | 32.2k | return new (Ctx) |
1789 | 32.2k | ObjCAttr(AtLoc, SourceRange(ObjCLoc), llvm::None, SourceRange(), {}); |
1790 | 32.2k | } |
1791 | | |
1792 | 4.92k | ObjCAttr *ObjCAttr::createUnnamedImplicit(ASTContext &Ctx) { |
1793 | 4.92k | return new (Ctx) ObjCAttr(llvm::None, false); |
1794 | 4.92k | } |
1795 | | |
1796 | | ObjCAttr *ObjCAttr::createNullary(ASTContext &Ctx, SourceLoc AtLoc, |
1797 | | SourceLoc ObjCLoc, SourceLoc LParenLoc, |
1798 | | SourceLoc NameLoc, Identifier Name, |
1799 | 1.64k | SourceLoc RParenLoc) { |
1800 | 1.64k | void *mem = Ctx.Allocate(totalSizeToAlloc<SourceLoc>(3), alignof(ObjCAttr)); |
1801 | 1.64k | return new (mem) ObjCAttr(AtLoc, SourceRange(ObjCLoc, RParenLoc), |
1802 | 1.64k | ObjCSelector(Ctx, 0, Name), |
1803 | 1.64k | SourceRange(LParenLoc, RParenLoc), |
1804 | 1.64k | NameLoc); |
1805 | 1.64k | } |
1806 | | |
1807 | | ObjCAttr *ObjCAttr::createNullary(ASTContext &Ctx, Identifier Name, |
1808 | 3.82k | bool isNameImplicit) { |
1809 | 3.82k | return new (Ctx) ObjCAttr(ObjCSelector(Ctx, 0, Name), isNameImplicit); |
1810 | 3.82k | } |
1811 | | |
1812 | | ObjCAttr *ObjCAttr::createSelector(ASTContext &Ctx, SourceLoc AtLoc, |
1813 | | SourceLoc ObjCLoc, SourceLoc LParenLoc, |
1814 | | ArrayRef<SourceLoc> NameLocs, |
1815 | | ArrayRef<Identifier> Names, |
1816 | 1.80k | SourceLoc RParenLoc) { |
1817 | 1.80k | assert(NameLocs.size() == Names.size()); |
1818 | 0 | void *mem = Ctx.Allocate(totalSizeToAlloc<SourceLoc>(NameLocs.size() + 2), |
1819 | 1.80k | alignof(ObjCAttr)); |
1820 | 1.80k | return new (mem) ObjCAttr(AtLoc, SourceRange(ObjCLoc, RParenLoc), |
1821 | 1.80k | ObjCSelector(Ctx, Names.size(), Names), |
1822 | 1.80k | SourceRange(LParenLoc, RParenLoc), |
1823 | 1.80k | NameLocs); |
1824 | 1.80k | } |
1825 | | |
1826 | | ObjCAttr *ObjCAttr::createSelector(ASTContext &Ctx, |
1827 | | ArrayRef<Identifier> Names, |
1828 | 0 | bool isNameImplicit) { |
1829 | 0 | return new (Ctx) ObjCAttr(ObjCSelector(Ctx, Names.size(), Names), |
1830 | 0 | isNameImplicit); |
1831 | 0 | } |
1832 | | |
1833 | 753 | ArrayRef<SourceLoc> ObjCAttr::getNameLocs() const { |
1834 | 753 | if (!hasTrailingLocationInfo()) |
1835 | 135 | return { }; |
1836 | | |
1837 | 618 | return getTrailingLocations().slice(2); |
1838 | 753 | } |
1839 | | |
1840 | 189 | SourceLoc ObjCAttr::getLParenLoc() const { |
1841 | 189 | if (!hasTrailingLocationInfo()) |
1842 | 54 | return SourceLoc(); |
1843 | | |
1844 | 135 | return getTrailingLocations()[0]; |
1845 | 189 | } |
1846 | | |
1847 | 360 | SourceLoc ObjCAttr::getRParenLoc() const { |
1848 | 360 | if (!hasTrailingLocationInfo()) |
1849 | 108 | return SourceLoc(); |
1850 | | |
1851 | 252 | return getTrailingLocations()[1]; |
1852 | 360 | } |
1853 | | |
1854 | 1.71k | ObjCAttr *ObjCAttr::clone(ASTContext &context) const { |
1855 | 1.71k | auto attr = new (context) ObjCAttr(getName(), isNameImplicit()); |
1856 | 1.71k | attr->setSwift3Inferred(isSwift3Inferred()); |
1857 | 1.71k | attr->setAddedByAccessNote(getAddedByAccessNote()); |
1858 | 1.71k | return attr; |
1859 | 1.71k | } |
1860 | | |
1861 | | PrivateImportAttr::PrivateImportAttr(SourceLoc atLoc, SourceRange baseRange, |
1862 | | StringRef sourceFile, |
1863 | | SourceRange parenRange) |
1864 | | : DeclAttribute(DAK_PrivateImport, atLoc, baseRange, /*Implicit=*/false), |
1865 | 216 | SourceFile(sourceFile) {} |
1866 | | |
1867 | | PrivateImportAttr *PrivateImportAttr::create(ASTContext &Ctxt, SourceLoc AtLoc, |
1868 | | SourceLoc PrivateLoc, |
1869 | | SourceLoc LParenLoc, |
1870 | | StringRef sourceFile, |
1871 | 216 | SourceLoc RParenLoc) { |
1872 | 216 | return new (Ctxt) |
1873 | 216 | PrivateImportAttr(AtLoc, SourceRange(PrivateLoc, RParenLoc), sourceFile, |
1874 | 216 | SourceRange(LParenLoc, RParenLoc)); |
1875 | 216 | } |
1876 | | |
1877 | | DynamicReplacementAttr::DynamicReplacementAttr(SourceLoc atLoc, |
1878 | | SourceRange baseRange, |
1879 | | DeclNameRef name, |
1880 | | SourceRange parenRange) |
1881 | | : DeclAttribute(DAK_DynamicReplacement, atLoc, baseRange, |
1882 | | /*Implicit=*/false), |
1883 | 1.88k | ReplacedFunctionName(name) { |
1884 | 1.88k | Bits.DynamicReplacementAttr.HasTrailingLocationInfo = true; |
1885 | 1.88k | getTrailingLocations()[0] = parenRange.Start; |
1886 | 1.88k | getTrailingLocations()[1] = parenRange.End; |
1887 | 1.88k | } |
1888 | | |
1889 | | DynamicReplacementAttr * |
1890 | | DynamicReplacementAttr::create(ASTContext &Ctx, SourceLoc AtLoc, |
1891 | | SourceLoc DynReplLoc, SourceLoc LParenLoc, |
1892 | 1.88k | DeclNameRef ReplacedFunction, SourceLoc RParenLoc) { |
1893 | 1.88k | void *mem = Ctx.Allocate(totalSizeToAlloc<SourceLoc>(2), |
1894 | 1.88k | alignof(DynamicReplacementAttr)); |
1895 | 1.88k | return new (mem) DynamicReplacementAttr( |
1896 | 1.88k | AtLoc, SourceRange(DynReplLoc, RParenLoc), ReplacedFunction, |
1897 | 1.88k | SourceRange(LParenLoc, RParenLoc)); |
1898 | 1.88k | } |
1899 | | |
1900 | | DynamicReplacementAttr * |
1901 | | DynamicReplacementAttr::create(ASTContext &Ctx, DeclNameRef name, |
1902 | 0 | AbstractFunctionDecl *f) { |
1903 | 0 | return new (Ctx) DynamicReplacementAttr(name, f); |
1904 | 0 | } |
1905 | | |
1906 | | DynamicReplacementAttr * |
1907 | | DynamicReplacementAttr::create(ASTContext &Ctx, DeclNameRef name, |
1908 | 420 | LazyMemberLoader *Resolver, uint64_t Data) { |
1909 | 420 | return new (Ctx) DynamicReplacementAttr(name, Resolver, Data); |
1910 | 420 | } |
1911 | | |
1912 | 0 | SourceLoc DynamicReplacementAttr::getLParenLoc() const { |
1913 | 0 | return getTrailingLocations()[0]; |
1914 | 0 | } |
1915 | | |
1916 | 0 | SourceLoc DynamicReplacementAttr::getRParenLoc() const { |
1917 | 0 | return getTrailingLocations()[1]; |
1918 | 0 | } |
1919 | | |
1920 | | TypeEraserAttr *TypeEraserAttr::create(ASTContext &ctx, |
1921 | | SourceLoc atLoc, SourceRange range, |
1922 | 102 | TypeExpr *typeEraserExpr) { |
1923 | 102 | return new (ctx) TypeEraserAttr(atLoc, range, typeEraserExpr, nullptr, 0); |
1924 | 102 | } |
1925 | | |
1926 | | TypeEraserAttr *TypeEraserAttr::create(ASTContext &ctx, |
1927 | | LazyMemberLoader *Resolver, |
1928 | 6 | uint64_t Data) { |
1929 | 6 | return new (ctx) TypeEraserAttr(SourceLoc(), SourceRange(), |
1930 | 6 | nullptr, Resolver, Data); |
1931 | 6 | } |
1932 | | |
1933 | 96 | bool TypeEraserAttr::hasViableTypeEraserInit(ProtocolDecl *protocol) const { |
1934 | 96 | return evaluateOrDefault(protocol->getASTContext().evaluator, |
1935 | 96 | TypeEraserHasViableInitRequest{ |
1936 | 96 | const_cast<TypeEraserAttr *>(this), protocol}, |
1937 | 96 | false); |
1938 | 96 | } |
1939 | | |
1940 | 102 | TypeRepr *TypeEraserAttr::getParsedTypeEraserTypeRepr() const { |
1941 | 102 | return TypeEraserExpr ? TypeEraserExpr->getTypeRepr() : nullptr; |
1942 | 102 | } |
1943 | | |
1944 | 21 | SourceLoc TypeEraserAttr::getLoc() const { |
1945 | 21 | return TypeEraserExpr ? TypeEraserExpr->getLoc() : SourceLoc(); |
1946 | 21 | } |
1947 | | |
1948 | 0 | Type TypeEraserAttr::getTypeWithoutResolving() const { |
1949 | 0 | return TypeEraserExpr ? TypeEraserExpr->getInstanceType() : Type(); |
1950 | 0 | } |
1951 | | |
1952 | 135 | Type TypeEraserAttr::getResolvedType(const ProtocolDecl *PD) const { |
1953 | 135 | auto &ctx = PD->getASTContext(); |
1954 | 135 | return evaluateOrDefault(ctx.evaluator, |
1955 | 135 | ResolveTypeEraserTypeRequest{ |
1956 | 135 | const_cast<ProtocolDecl *>(PD), |
1957 | 135 | const_cast<TypeEraserAttr *>(this)}, |
1958 | 135 | ErrorType::get(ctx)); |
1959 | 135 | } |
1960 | | |
1961 | 270 | Type RawLayoutAttr::getResolvedLikeType(StructDecl *sd) const { |
1962 | 270 | auto &ctx = sd->getASTContext(); |
1963 | 270 | return evaluateOrDefault(ctx.evaluator, |
1964 | 270 | ResolveRawLayoutLikeTypeRequest{sd, |
1965 | 270 | const_cast<RawLayoutAttr *>(this)}, |
1966 | 270 | ErrorType::get(ctx)); |
1967 | 270 | } |
1968 | | |
1969 | | AvailableAttr * |
1970 | | AvailableAttr::createPlatformAgnostic(ASTContext &C, |
1971 | | StringRef Message, |
1972 | | StringRef Rename, |
1973 | | PlatformAgnosticAvailabilityKind Kind, |
1974 | 329k | llvm::VersionTuple Obsoleted) { |
1975 | 329k | assert(Kind != PlatformAgnosticAvailabilityKind::None); |
1976 | 0 | llvm::VersionTuple NoVersion; |
1977 | 329k | if (Kind == PlatformAgnosticAvailabilityKind::SwiftVersionSpecific) { |
1978 | 205k | assert(!Obsoleted.empty()); |
1979 | 205k | } |
1980 | 0 | return new (C) AvailableAttr( |
1981 | 329k | SourceLoc(), SourceRange(), PlatformKind::none, Message, Rename, nullptr, |
1982 | 329k | NoVersion, SourceRange(), |
1983 | 329k | NoVersion, SourceRange(), |
1984 | 329k | Obsoleted, SourceRange(), |
1985 | 329k | Kind, /* isImplicit */ false, /*SPI*/false); |
1986 | 329k | } |
1987 | | |
1988 | | AvailableAttr *AvailableAttr::createForAlternative( |
1989 | 1.48k | ASTContext &C, AbstractFunctionDecl *AsyncFunc) { |
1990 | 1.48k | llvm::VersionTuple NoVersion; |
1991 | 1.48k | return new (C) AvailableAttr( |
1992 | 1.48k | SourceLoc(), SourceRange(), PlatformKind::none, "", "", AsyncFunc, |
1993 | 1.48k | NoVersion, SourceRange(), |
1994 | 1.48k | NoVersion, SourceRange(), |
1995 | 1.48k | NoVersion, SourceRange(), |
1996 | 1.48k | PlatformAgnosticAvailabilityKind::None, /*Implicit=*/true, /*SPI*/false); |
1997 | 1.48k | } |
1998 | | |
1999 | 70.3M | bool AvailableAttr::isActivePlatform(const ASTContext &ctx) const { |
2000 | 70.3M | return isPlatformActive(Platform, ctx.LangOpts); |
2001 | 70.3M | } |
2002 | | |
2003 | 24.9k | bool BackDeployedAttr::isActivePlatform(const ASTContext &ctx) const { |
2004 | 24.9k | return isPlatformActive(Platform, ctx.LangOpts); |
2005 | 24.9k | } |
2006 | | |
2007 | 672 | AvailableAttr *AvailableAttr::clone(ASTContext &C, bool implicit) const { |
2008 | 672 | return new (C) AvailableAttr(implicit ? SourceLoc() : AtLoc, |
2009 | 672 | implicit ? SourceRange() : getRange(), |
2010 | 672 | Platform, Message, Rename, RenameDecl, |
2011 | 672 | Introduced ? *Introduced : llvm::VersionTuple(), |
2012 | 672 | implicit ? SourceRange() : IntroducedRange, |
2013 | 672 | Deprecated ? *Deprecated : llvm::VersionTuple(), |
2014 | 672 | implicit ? SourceRange() : DeprecatedRange, |
2015 | 672 | Obsoleted ? *Obsoleted : llvm::VersionTuple(), |
2016 | 672 | implicit ? SourceRange() : ObsoletedRange, |
2017 | 672 | PlatformAgnostic, |
2018 | 672 | implicit, |
2019 | 672 | IsSPI); |
2020 | 672 | } |
2021 | | |
2022 | | llvm::Optional<OriginallyDefinedInAttr::ActiveVersion> |
2023 | 150k | OriginallyDefinedInAttr::isActivePlatform(const ASTContext &ctx) const { |
2024 | 150k | OriginallyDefinedInAttr::ActiveVersion Result; |
2025 | 150k | Result.Platform = Platform; |
2026 | 150k | Result.Version = MovedVersion; |
2027 | 150k | Result.ModuleName = OriginalModuleName; |
2028 | 150k | if (isPlatformActive(Platform, ctx.LangOpts, /*TargetVariant*/false)) { |
2029 | 34.0k | Result.IsSimulator = ctx.LangOpts.Target.isSimulatorEnvironment(); |
2030 | 34.0k | return Result; |
2031 | 34.0k | } |
2032 | | |
2033 | | // Also check if the platform is active by using target variant. This ensures |
2034 | | // we emit linker directives for multiple platforms when building zippered |
2035 | | // libraries. |
2036 | 116k | if (ctx.LangOpts.TargetVariant.has_value() && |
2037 | 116k | isPlatformActive(Platform, ctx.LangOpts, /*TargetVariant*/true)) { |
2038 | 57 | Result.IsSimulator = ctx.LangOpts.TargetVariant->isSimulatorEnvironment(); |
2039 | 57 | return Result; |
2040 | 57 | } |
2041 | 116k | return llvm::None; |
2042 | 116k | } |
2043 | | |
2044 | | OriginallyDefinedInAttr *OriginallyDefinedInAttr::clone(ASTContext &C, |
2045 | 18 | bool implicit) const { |
2046 | 18 | return new (C) OriginallyDefinedInAttr( |
2047 | 18 | implicit ? SourceLoc() : AtLoc, implicit ? SourceRange() : getRange(), |
2048 | 18 | OriginalModuleName, Platform, MovedVersion, implicit); |
2049 | 18 | } |
2050 | | |
2051 | 14.5M | bool AvailableAttr::isLanguageVersionSpecific() const { |
2052 | 14.5M | if (PlatformAgnostic == |
2053 | 14.5M | PlatformAgnosticAvailabilityKind::SwiftVersionSpecific) |
2054 | 423k | { |
2055 | 423k | assert(Platform == PlatformKind::none && |
2056 | 423k | (Introduced.has_value() || |
2057 | 423k | Deprecated.has_value() || |
2058 | 423k | Obsoleted.has_value())); |
2059 | 0 | return true; |
2060 | 423k | } |
2061 | 14.1M | return false; |
2062 | 14.5M | } |
2063 | | |
2064 | 14.6M | bool AvailableAttr::isPackageDescriptionVersionSpecific() const { |
2065 | 14.6M | if (PlatformAgnostic == |
2066 | 14.6M | PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific) |
2067 | 1.04k | { |
2068 | 1.04k | assert(Platform == PlatformKind::none && |
2069 | 1.04k | (Introduced.has_value() || |
2070 | 1.04k | Deprecated.has_value() || |
2071 | 1.04k | Obsoleted.has_value())); |
2072 | 0 | return true; |
2073 | 1.04k | } |
2074 | 14.6M | return false; |
2075 | 14.6M | } |
2076 | | |
2077 | 13.6M | bool AvailableAttr::isUnconditionallyUnavailable() const { |
2078 | 13.6M | switch (PlatformAgnostic) { |
2079 | 10.4M | case PlatformAgnosticAvailabilityKind::None: |
2080 | 10.8M | case PlatformAgnosticAvailabilityKind::Deprecated: |
2081 | 11.5M | case PlatformAgnosticAvailabilityKind::SwiftVersionSpecific: |
2082 | 11.5M | case PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific: |
2083 | 11.5M | case PlatformAgnosticAvailabilityKind::NoAsync: |
2084 | 11.5M | return false; |
2085 | | |
2086 | 1.88M | case PlatformAgnosticAvailabilityKind::Unavailable: |
2087 | 2.09M | case PlatformAgnosticAvailabilityKind::UnavailableInSwift: |
2088 | 2.09M | return true; |
2089 | 13.6M | } |
2090 | | |
2091 | 0 | llvm_unreachable("Unhandled PlatformAgnosticAvailabilityKind in switch."); |
2092 | 0 | } |
2093 | | |
2094 | 2.13M | bool AvailableAttr::isUnconditionallyDeprecated() const { |
2095 | 2.13M | switch (PlatformAgnostic) { |
2096 | 1.99M | case PlatformAgnosticAvailabilityKind::None: |
2097 | 2.03M | case PlatformAgnosticAvailabilityKind::Unavailable: |
2098 | 2.03M | case PlatformAgnosticAvailabilityKind::UnavailableInSwift: |
2099 | 2.08M | case PlatformAgnosticAvailabilityKind::SwiftVersionSpecific: |
2100 | 2.08M | case PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific: |
2101 | 2.08M | case PlatformAgnosticAvailabilityKind::NoAsync: |
2102 | 2.08M | return false; |
2103 | | |
2104 | 52.9k | case PlatformAgnosticAvailabilityKind::Deprecated: |
2105 | 52.9k | return true; |
2106 | 2.13M | } |
2107 | | |
2108 | 0 | llvm_unreachable("Unhandled PlatformAgnosticAvailabilityKind in switch."); |
2109 | 0 | } |
2110 | | |
2111 | 978k | bool AvailableAttr::isNoAsync() const { |
2112 | 978k | return PlatformAgnostic == PlatformAgnosticAvailabilityKind::NoAsync; |
2113 | 978k | } |
2114 | | |
2115 | 5.56M | llvm::VersionTuple AvailableAttr::getActiveVersion(const ASTContext &ctx) const { |
2116 | 5.56M | if (isLanguageVersionSpecific()) { |
2117 | 355k | return ctx.LangOpts.EffectiveLanguageVersion; |
2118 | 5.21M | } else if (isPackageDescriptionVersionSpecific()) { |
2119 | 513 | return ctx.LangOpts.PackageDescriptionVersion; |
2120 | 5.21M | } else { |
2121 | 5.21M | return ctx.LangOpts.getMinPlatformVersion(); |
2122 | 5.21M | } |
2123 | 5.56M | } |
2124 | | |
2125 | | AvailableVersionComparison AvailableAttr::getVersionAvailability( |
2126 | 5.53M | const ASTContext &ctx) const { |
2127 | | |
2128 | | // Unconditional unavailability. |
2129 | 5.53M | if (isUnconditionallyUnavailable()) |
2130 | 6.18k | return AvailableVersionComparison::Unavailable; |
2131 | | |
2132 | 5.53M | llvm::VersionTuple queryVersion = getActiveVersion(ctx); |
2133 | | |
2134 | | // If this entity was obsoleted before or at the query platform version, |
2135 | | // consider it obsolete. |
2136 | 5.53M | if (Obsoleted && *Obsoleted <= queryVersion) |
2137 | 245k | return AvailableVersionComparison::Obsoleted; |
2138 | | |
2139 | | // If this entity was introduced after the query version and we're doing a |
2140 | | // platform comparison, true availability can only be determined dynamically; |
2141 | | // if we're doing a _language_ version check, the query version is a |
2142 | | // static requirement, so we treat "introduced later" as just plain |
2143 | | // unavailable. |
2144 | 5.28M | if (Introduced && *Introduced > queryVersion) { |
2145 | 1.59M | if (isLanguageVersionSpecific() || isPackageDescriptionVersionSpecific()) |
2146 | 3.93k | return AvailableVersionComparison::Unavailable; |
2147 | 1.58M | else |
2148 | 1.58M | return AvailableVersionComparison::PotentiallyUnavailable; |
2149 | 1.59M | } |
2150 | | |
2151 | | // The entity is available. |
2152 | 3.69M | return AvailableVersionComparison::Available; |
2153 | 5.28M | } |
2154 | | |
2155 | 34.0M | const AvailableAttr *AvailableAttr::isUnavailable(const Decl *D) { |
2156 | 34.0M | ASTContext &ctx = D->getASTContext(); |
2157 | 34.0M | if (auto attr = D->getAttrs().getUnavailable(ctx)) |
2158 | 73.2k | return attr; |
2159 | | |
2160 | | // If D is an extension member, check if the extension is unavailable. |
2161 | | // |
2162 | | // Skip decls imported from Clang, they could be associated to the wrong |
2163 | | // extension and inherit undesired unavailability. The ClangImporter |
2164 | | // associates Objective-C protocol members to the first category where the |
2165 | | // protocol is directly or indirectly adopted, no matter its availability |
2166 | | // and the availability of other categories. rdar://problem/53956555 |
2167 | 33.9M | if (!D->getClangNode()) |
2168 | 33.4M | if (auto ext = dyn_cast<ExtensionDecl>(D->getDeclContext())) |
2169 | 3.36M | return AvailableAttr::isUnavailable(ext); |
2170 | | |
2171 | 30.6M | return nullptr; |
2172 | 33.9M | } |
2173 | | |
2174 | | SpecializeAttr::SpecializeAttr(SourceLoc atLoc, SourceRange range, |
2175 | | TrailingWhereClause *clause, bool exported, |
2176 | | SpecializationKind kind, |
2177 | | GenericSignature specializedSignature, |
2178 | | DeclNameRef targetFunctionName, |
2179 | | ArrayRef<Identifier> spiGroups, |
2180 | | ArrayRef<AvailableAttr *> availableAttrs, |
2181 | | size_t typeErasedParamsCount) |
2182 | | : DeclAttribute(DAK_Specialize, atLoc, range, |
2183 | | /*Implicit=*/clause == nullptr), |
2184 | | trailingWhereClause(clause), specializedSignature(specializedSignature), |
2185 | | targetFunctionName(targetFunctionName), numSPIGroups(spiGroups.size()), |
2186 | | numAvailableAttrs(availableAttrs.size()), |
2187 | | numTypeErasedParams(typeErasedParamsCount), |
2188 | 161k | typeErasedParamsInitialized(false) { |
2189 | 161k | std::uninitialized_copy(spiGroups.begin(), spiGroups.end(), |
2190 | 161k | getTrailingObjects<Identifier>()); |
2191 | 161k | std::uninitialized_copy(availableAttrs.begin(), availableAttrs.end(), |
2192 | 161k | getTrailingObjects<AvailableAttr *>()); |
2193 | | |
2194 | 161k | Bits.SpecializeAttr.exported = exported; |
2195 | 161k | Bits.SpecializeAttr.kind = unsigned(kind); |
2196 | 161k | } |
2197 | | |
2198 | 27.1k | TrailingWhereClause *SpecializeAttr::getTrailingWhereClause() const { |
2199 | 27.1k | return trailingWhereClause; |
2200 | 27.1k | } |
2201 | | |
2202 | | SpecializeAttr *SpecializeAttr::create(ASTContext &Ctx, SourceLoc atLoc, |
2203 | | SourceRange range, |
2204 | | TrailingWhereClause *clause, |
2205 | | bool exported, SpecializationKind kind, |
2206 | | DeclNameRef targetFunctionName, |
2207 | | ArrayRef<Identifier> spiGroups, |
2208 | | ArrayRef<AvailableAttr *> availableAttrs, |
2209 | | size_t typeErasedParamsCount, |
2210 | 11.1k | GenericSignature specializedSignature) { |
2211 | 11.1k | unsigned size = totalSizeToAlloc<Identifier, AvailableAttr *, Type>( |
2212 | 11.1k | spiGroups.size(), availableAttrs.size(), typeErasedParamsCount); |
2213 | 11.1k | void *mem = Ctx.Allocate(size, alignof(SpecializeAttr)); |
2214 | 11.1k | return new (mem) |
2215 | 11.1k | SpecializeAttr(atLoc, range, clause, exported, kind, specializedSignature, |
2216 | 11.1k | targetFunctionName, spiGroups, availableAttrs, typeErasedParamsCount); |
2217 | 11.1k | } |
2218 | | |
2219 | | SpecializeAttr *SpecializeAttr::create(ASTContext &ctx, bool exported, |
2220 | | SpecializationKind kind, |
2221 | | ArrayRef<Identifier> spiGroups, |
2222 | | ArrayRef<AvailableAttr *> availableAttrs, |
2223 | | GenericSignature specializedSignature, |
2224 | 0 | DeclNameRef targetFunctionName) { |
2225 | 0 | unsigned size = totalSizeToAlloc<Identifier, AvailableAttr *, Type>( |
2226 | 0 | spiGroups.size(), availableAttrs.size(), 0); |
2227 | 0 | void *mem = ctx.Allocate(size, alignof(SpecializeAttr)); |
2228 | 0 | return new (mem) SpecializeAttr( |
2229 | 0 | SourceLoc(), SourceRange(), nullptr, exported, kind, specializedSignature, |
2230 | 0 | targetFunctionName, spiGroups, availableAttrs, 0); |
2231 | 0 | } |
2232 | | |
2233 | | SpecializeAttr *SpecializeAttr::create( |
2234 | | ASTContext &ctx, bool exported, SpecializationKind kind, |
2235 | | ArrayRef<Identifier> spiGroups, ArrayRef<AvailableAttr *> availableAttrs, |
2236 | | ArrayRef<Type> typeErasedParams, GenericSignature specializedSignature, |
2237 | | DeclNameRef targetFunctionName, LazyMemberLoader *resolver, |
2238 | 150k | uint64_t data) { |
2239 | 150k | unsigned size = totalSizeToAlloc<Identifier, AvailableAttr *, Type>( |
2240 | 150k | spiGroups.size(), availableAttrs.size(), typeErasedParams.size()); |
2241 | 150k | void *mem = ctx.Allocate(size, alignof(SpecializeAttr)); |
2242 | 150k | auto *attr = new (mem) SpecializeAttr( |
2243 | 150k | SourceLoc(), SourceRange(), nullptr, exported, kind, specializedSignature, |
2244 | 150k | targetFunctionName, spiGroups, availableAttrs, typeErasedParams.size()); |
2245 | 150k | attr->setTypeErasedParams(typeErasedParams); |
2246 | 150k | attr->resolver = resolver; |
2247 | 150k | attr->resolverContextData = data; |
2248 | 150k | return attr; |
2249 | 150k | } |
2250 | | |
2251 | 59.6k | ValueDecl * SpecializeAttr::getTargetFunctionDecl(const ValueDecl *onDecl) const { |
2252 | 59.6k | return evaluateOrDefault(onDecl->getASTContext().evaluator, |
2253 | 59.6k | SpecializeAttrTargetDeclRequest{ |
2254 | 59.6k | onDecl, const_cast<SpecializeAttr *>(this)}, |
2255 | 59.6k | nullptr); |
2256 | 59.6k | } |
2257 | | |
2258 | | GenericSignature SpecializeAttr::getSpecializedSignature( |
2259 | 58.8k | const AbstractFunctionDecl *onDecl) const { |
2260 | 58.8k | return evaluateOrDefault(onDecl->getASTContext().evaluator, |
2261 | 58.8k | SerializeAttrGenericSignatureRequest{ |
2262 | 58.8k | onDecl, const_cast<SpecializeAttr *>(this)}, |
2263 | 58.8k | nullptr); |
2264 | 58.8k | } |
2265 | | |
2266 | | SPIAccessControlAttr::SPIAccessControlAttr(SourceLoc atLoc, SourceRange range, |
2267 | | ArrayRef<Identifier> spiGroups) |
2268 | | : DeclAttribute(DAK_SPIAccessControl, atLoc, range, |
2269 | | /*Implicit=*/false), |
2270 | 135k | numSPIGroups(spiGroups.size()) { |
2271 | 135k | std::uninitialized_copy(spiGroups.begin(), spiGroups.end(), |
2272 | 135k | getTrailingObjects<Identifier>()); |
2273 | 135k | } |
2274 | | |
2275 | | SPIAccessControlAttr * |
2276 | | SPIAccessControlAttr::create(ASTContext &context, |
2277 | | SourceLoc atLoc, |
2278 | | SourceRange range, |
2279 | 135k | ArrayRef<Identifier> spiGroups) { |
2280 | 135k | unsigned size = totalSizeToAlloc<Identifier>(spiGroups.size()); |
2281 | 135k | void *mem = context.Allocate(size, alignof(SPIAccessControlAttr)); |
2282 | 135k | return new (mem) SPIAccessControlAttr(atLoc, range, spiGroups); |
2283 | 135k | } |
2284 | | |
2285 | | SPIAccessControlAttr *SPIAccessControlAttr::clone(ASTContext &C, |
2286 | 9 | bool implicit) const { |
2287 | 9 | auto *attr = SPIAccessControlAttr::create( |
2288 | 9 | C, implicit ? SourceLoc() : AtLoc, implicit ? SourceRange() : getRange(), |
2289 | 9 | getSPIGroups()); |
2290 | 9 | attr->setImplicit(implicit); |
2291 | 9 | return attr; |
2292 | 9 | } |
2293 | | |
2294 | | DifferentiableAttr::DifferentiableAttr(bool implicit, SourceLoc atLoc, |
2295 | | SourceRange baseRange, |
2296 | | enum DifferentiabilityKind diffKind, |
2297 | | ArrayRef<ParsedAutoDiffParameter> params, |
2298 | | TrailingWhereClause *clause) |
2299 | | : DeclAttribute(DAK_Differentiable, atLoc, baseRange, implicit), |
2300 | | DifferentiabilityKind(diffKind), NumParsedParameters(params.size()), |
2301 | 3.80k | WhereClause(clause) { |
2302 | 3.80k | assert((diffKind != DifferentiabilityKind::Normal && |
2303 | 3.80k | diffKind != DifferentiabilityKind::Forward) && |
2304 | 3.80k | "'Normal' and 'Forward' are not supported"); |
2305 | 0 | std::copy(params.begin(), params.end(), |
2306 | 3.80k | getTrailingObjects<ParsedAutoDiffParameter>()); |
2307 | 3.80k | } |
2308 | | |
2309 | | DifferentiableAttr::DifferentiableAttr(Decl *original, bool implicit, |
2310 | | SourceLoc atLoc, SourceRange baseRange, |
2311 | | enum DifferentiabilityKind diffKind, |
2312 | | IndexSubset *parameterIndices, |
2313 | | GenericSignature derivativeGenSig) |
2314 | | : DeclAttribute(DAK_Differentiable, atLoc, baseRange, implicit), |
2315 | 664 | OriginalDeclaration(original), DifferentiabilityKind(diffKind) { |
2316 | 664 | assert((diffKind != DifferentiabilityKind::Normal && |
2317 | 664 | diffKind != DifferentiabilityKind::Forward) && |
2318 | 664 | "'Normal' and 'Forward' are not supported"); |
2319 | 0 | setParameterIndices(parameterIndices); |
2320 | 664 | setDerivativeGenericSignature(derivativeGenSig); |
2321 | 664 | } |
2322 | | |
2323 | | DifferentiableAttr * |
2324 | | DifferentiableAttr::create(ASTContext &context, bool implicit, |
2325 | | SourceLoc atLoc, SourceRange baseRange, |
2326 | | enum DifferentiabilityKind diffKind, |
2327 | | ArrayRef<ParsedAutoDiffParameter> parameters, |
2328 | 3.80k | TrailingWhereClause *clause) { |
2329 | 3.80k | unsigned size = totalSizeToAlloc<ParsedAutoDiffParameter>(parameters.size()); |
2330 | 3.80k | void *mem = context.Allocate(size, alignof(DifferentiableAttr)); |
2331 | 3.80k | return new (mem) DifferentiableAttr(implicit, atLoc, baseRange, diffKind, |
2332 | 3.80k | parameters, clause); |
2333 | 3.80k | } |
2334 | | |
2335 | | DifferentiableAttr * |
2336 | | DifferentiableAttr::create(AbstractFunctionDecl *original, bool implicit, |
2337 | | SourceLoc atLoc, SourceRange baseRange, |
2338 | | enum DifferentiabilityKind diffKind, |
2339 | | IndexSubset *parameterIndices, |
2340 | 664 | GenericSignature derivativeGenSig) { |
2341 | 664 | auto &ctx = original->getASTContext(); |
2342 | | |
2343 | 664 | size_t size = totalSizeToAlloc<ParsedAutoDiffParameter>(0); |
2344 | 664 | void *mem = ctx.Allocate(size, alignof(DifferentiableAttr)); |
2345 | 664 | return new (mem) DifferentiableAttr(original, implicit, atLoc, baseRange, |
2346 | 664 | diffKind, parameterIndices, |
2347 | 664 | derivativeGenSig); |
2348 | 664 | } |
2349 | | |
2350 | 3.80k | void DifferentiableAttr::setOriginalDeclaration(Decl *originalDeclaration) { |
2351 | 3.80k | assert(originalDeclaration && "Original declaration must be non-null"); |
2352 | 0 | assert(!OriginalDeclaration && |
2353 | 3.80k | "Original declaration cannot have already been set"); |
2354 | 0 | OriginalDeclaration = originalDeclaration; |
2355 | 3.80k | } |
2356 | | |
2357 | 33.5k | bool DifferentiableAttr::hasBeenTypeChecked() const { |
2358 | 33.5k | return ParameterIndicesAndBit.getInt(); |
2359 | 33.5k | } |
2360 | | |
2361 | 33.5k | IndexSubset *DifferentiableAttr::getParameterIndices() const { |
2362 | 33.5k | assert(getOriginalDeclaration() && |
2363 | 33.5k | "Original declaration must have been resolved"); |
2364 | 0 | auto &ctx = getOriginalDeclaration()->getASTContext(); |
2365 | 33.5k | return evaluateOrDefault(ctx.evaluator, |
2366 | 33.5k | DifferentiableAttributeTypeCheckRequest{ |
2367 | 33.5k | const_cast<DifferentiableAttr *>(this)}, |
2368 | 33.5k | nullptr); |
2369 | 33.5k | } |
2370 | | |
2371 | 976 | void DifferentiableAttr::setParameterIndices(IndexSubset *paramIndices) { |
2372 | 976 | assert(getOriginalDeclaration() && |
2373 | 976 | "Original declaration must have been resolved"); |
2374 | 0 | auto &ctx = getOriginalDeclaration()->getASTContext(); |
2375 | 976 | ctx.evaluator.cacheOutput( |
2376 | 976 | DifferentiableAttributeTypeCheckRequest{ |
2377 | 976 | const_cast<DifferentiableAttr *>(this)}, |
2378 | 976 | std::move(paramIndices)); |
2379 | 976 | } |
2380 | | |
2381 | | GenericEnvironment *DifferentiableAttr::getDerivativeGenericEnvironment( |
2382 | 84 | AbstractFunctionDecl *original) const { |
2383 | 84 | if (auto derivativeGenSig = getDerivativeGenericSignature()) |
2384 | 84 | return derivativeGenSig.getGenericEnvironment(); |
2385 | 0 | return original->getGenericEnvironment(); |
2386 | 84 | } |
2387 | | |
2388 | 304 | void DeclNameRefWithLoc::print(ASTPrinter &Printer) const { |
2389 | 304 | Printer << Name; |
2390 | 304 | if (AccessorKind) |
2391 | 16 | Printer << '.' << getAccessorLabel(*AccessorKind); |
2392 | 304 | } |
2393 | | |
2394 | | void DifferentiableAttr::print(llvm::raw_ostream &OS, const Decl *D, |
2395 | 116 | bool omitWrtClause) const { |
2396 | 116 | StreamPrinter P(OS); |
2397 | 116 | P << "@" << getAttrName(); |
2398 | 116 | printDifferentiableAttrArguments(this, P, PrintOptions(), D, omitWrtClause); |
2399 | 116 | } |
2400 | | |
2401 | | DerivativeAttr::DerivativeAttr(bool implicit, SourceLoc atLoc, |
2402 | | SourceRange baseRange, TypeRepr *baseTypeRepr, |
2403 | | DeclNameRefWithLoc originalName, |
2404 | | ArrayRef<ParsedAutoDiffParameter> params) |
2405 | | : DeclAttribute(DAK_Derivative, atLoc, baseRange, implicit), |
2406 | | BaseTypeRepr(baseTypeRepr), OriginalFunctionName(std::move(originalName)), |
2407 | 1.83k | NumParsedParameters(params.size()) { |
2408 | 1.83k | std::copy(params.begin(), params.end(), |
2409 | 1.83k | getTrailingObjects<ParsedAutoDiffParameter>()); |
2410 | 1.83k | } |
2411 | | |
2412 | | DerivativeAttr::DerivativeAttr(bool implicit, SourceLoc atLoc, |
2413 | | SourceRange baseRange, TypeRepr *baseTypeRepr, |
2414 | | DeclNameRefWithLoc originalName, |
2415 | | IndexSubset *parameterIndices) |
2416 | | : DeclAttribute(DAK_Derivative, atLoc, baseRange, implicit), |
2417 | | BaseTypeRepr(baseTypeRepr), OriginalFunctionName(std::move(originalName)), |
2418 | 96 | ParameterIndices(parameterIndices) {} |
2419 | | |
2420 | | DerivativeAttr * |
2421 | | DerivativeAttr::create(ASTContext &context, bool implicit, SourceLoc atLoc, |
2422 | | SourceRange baseRange, TypeRepr *baseTypeRepr, |
2423 | | DeclNameRefWithLoc originalName, |
2424 | 1.83k | ArrayRef<ParsedAutoDiffParameter> params) { |
2425 | 1.83k | unsigned size = totalSizeToAlloc<ParsedAutoDiffParameter>(params.size()); |
2426 | 1.83k | void *mem = context.Allocate(size, alignof(DerivativeAttr)); |
2427 | 1.83k | return new (mem) DerivativeAttr(implicit, atLoc, baseRange, baseTypeRepr, |
2428 | 1.83k | std::move(originalName), params); |
2429 | 1.83k | } |
2430 | | |
2431 | | DerivativeAttr *DerivativeAttr::create(ASTContext &context, bool implicit, |
2432 | | SourceLoc atLoc, SourceRange baseRange, |
2433 | | TypeRepr *baseTypeRepr, |
2434 | | DeclNameRefWithLoc originalName, |
2435 | 96 | IndexSubset *parameterIndices) { |
2436 | 96 | void *mem = context.Allocate(sizeof(DerivativeAttr), alignof(DerivativeAttr)); |
2437 | 96 | return new (mem) DerivativeAttr(implicit, atLoc, baseRange, baseTypeRepr, |
2438 | 96 | std::move(originalName), parameterIndices); |
2439 | 96 | } |
2440 | | |
2441 | | AbstractFunctionDecl * |
2442 | 2.26k | DerivativeAttr::getOriginalFunction(ASTContext &context) const { |
2443 | 2.26k | return evaluateOrDefault( |
2444 | 2.26k | context.evaluator, |
2445 | 2.26k | DerivativeAttrOriginalDeclRequest{const_cast<DerivativeAttr *>(this)}, |
2446 | 2.26k | nullptr); |
2447 | 2.26k | } |
2448 | | |
2449 | 1.57k | void DerivativeAttr::setOriginalFunction(AbstractFunctionDecl *decl) { |
2450 | 1.57k | assert(!OriginalFunction && "cannot overwrite original function"); |
2451 | 0 | OriginalFunction = decl; |
2452 | 1.57k | } |
2453 | | |
2454 | | void DerivativeAttr::setOriginalFunctionResolver( |
2455 | 96 | LazyMemberLoader *resolver, uint64_t resolverContextData) { |
2456 | 96 | assert(!OriginalFunction && "cannot overwrite original function"); |
2457 | 0 | OriginalFunction = resolver; |
2458 | 96 | ResolverContextData = resolverContextData; |
2459 | 96 | } |
2460 | | |
2461 | 1.93k | void DerivativeAttr::setOriginalDeclaration(Decl *originalDeclaration) { |
2462 | 1.93k | assert(originalDeclaration && "Original declaration must be non-null"); |
2463 | 0 | assert(!OriginalDeclaration && |
2464 | 1.93k | "Original declaration cannot have already been set"); |
2465 | 0 | OriginalDeclaration = originalDeclaration; |
2466 | 1.93k | } |
2467 | | |
2468 | | TransposeAttr::TransposeAttr(bool implicit, SourceLoc atLoc, |
2469 | | SourceRange baseRange, TypeRepr *baseTypeRepr, |
2470 | | DeclNameRefWithLoc originalName, |
2471 | | ArrayRef<ParsedAutoDiffParameter> params) |
2472 | | : DeclAttribute(DAK_Transpose, atLoc, baseRange, implicit), |
2473 | | BaseTypeRepr(baseTypeRepr), OriginalFunctionName(std::move(originalName)), |
2474 | 600 | NumParsedParameters(params.size()) { |
2475 | 600 | std::uninitialized_copy(params.begin(), params.end(), |
2476 | 600 | getTrailingObjects<ParsedAutoDiffParameter>()); |
2477 | 600 | } |
2478 | | |
2479 | | TransposeAttr::TransposeAttr(bool implicit, SourceLoc atLoc, |
2480 | | SourceRange baseRange, TypeRepr *baseTypeRepr, |
2481 | | DeclNameRefWithLoc originalName, |
2482 | | IndexSubset *parameterIndices) |
2483 | | : DeclAttribute(DAK_Transpose, atLoc, baseRange, implicit), |
2484 | | BaseTypeRepr(baseTypeRepr), OriginalFunctionName(std::move(originalName)), |
2485 | 28 | ParameterIndices(parameterIndices) {} |
2486 | | |
2487 | | TransposeAttr *TransposeAttr::create(ASTContext &context, bool implicit, |
2488 | | SourceLoc atLoc, SourceRange baseRange, |
2489 | | TypeRepr *baseType, |
2490 | | DeclNameRefWithLoc originalName, |
2491 | 600 | ArrayRef<ParsedAutoDiffParameter> params) { |
2492 | 600 | unsigned size = totalSizeToAlloc<ParsedAutoDiffParameter>(params.size()); |
2493 | 600 | void *mem = context.Allocate(size, alignof(TransposeAttr)); |
2494 | 600 | return new (mem) TransposeAttr(implicit, atLoc, baseRange, baseType, |
2495 | 600 | std::move(originalName), params); |
2496 | 600 | } |
2497 | | |
2498 | | TransposeAttr *TransposeAttr::create(ASTContext &context, bool implicit, |
2499 | | SourceLoc atLoc, SourceRange baseRange, |
2500 | | TypeRepr *baseType, |
2501 | | DeclNameRefWithLoc originalName, |
2502 | 28 | IndexSubset *parameterIndices) { |
2503 | 28 | void *mem = context.Allocate(sizeof(TransposeAttr), alignof(TransposeAttr)); |
2504 | 28 | return new (mem) TransposeAttr(implicit, atLoc, baseRange, baseType, |
2505 | 28 | std::move(originalName), parameterIndices); |
2506 | 28 | } |
2507 | | |
2508 | | StorageRestrictionsAttr::StorageRestrictionsAttr( |
2509 | | SourceLoc AtLoc, SourceRange Range, ArrayRef<Identifier> initializes, |
2510 | | ArrayRef<Identifier> accesses, bool Implicit) |
2511 | | : DeclAttribute(DAK_StorageRestrictions, AtLoc, Range, Implicit), |
2512 | | NumInitializes(initializes.size()), |
2513 | 804 | NumAccesses(accesses.size()) { |
2514 | 804 | std::uninitialized_copy(initializes.begin(), initializes.end(), |
2515 | 804 | getTrailingObjects<Identifier>()); |
2516 | 804 | std::uninitialized_copy(accesses.begin(), accesses.end(), |
2517 | 804 | getTrailingObjects<Identifier>() + NumInitializes); |
2518 | 804 | } |
2519 | | |
2520 | | StorageRestrictionsAttr * |
2521 | | StorageRestrictionsAttr::create( |
2522 | | ASTContext &ctx, SourceLoc atLoc, SourceRange range, |
2523 | 804 | ArrayRef<Identifier> initializes, ArrayRef<Identifier> accesses) { |
2524 | 804 | unsigned size = |
2525 | 804 | totalSizeToAlloc<Identifier>(initializes.size() + accesses.size()); |
2526 | 804 | void *mem = ctx.Allocate(size, alignof(StorageRestrictionsAttr)); |
2527 | 804 | return new (mem) StorageRestrictionsAttr(atLoc, range, initializes, accesses, |
2528 | 804 | /*implicit=*/false); |
2529 | 804 | } |
2530 | | |
2531 | | ImplementsAttr::ImplementsAttr(SourceLoc atLoc, SourceRange range, |
2532 | | TypeRepr *TyR, |
2533 | | DeclName MemberName, |
2534 | | DeclNameLoc MemberNameLoc) |
2535 | | : DeclAttribute(DAK_Implements, atLoc, range, /*Implicit=*/false), |
2536 | | TyR(TyR), |
2537 | | MemberName(MemberName), |
2538 | 9.55k | MemberNameLoc(MemberNameLoc) { |
2539 | 9.55k | } |
2540 | | |
2541 | | ImplementsAttr *ImplementsAttr::create(ASTContext &Ctx, SourceLoc atLoc, |
2542 | | SourceRange range, |
2543 | | TypeRepr *TyR, |
2544 | | DeclName MemberName, |
2545 | 105 | DeclNameLoc MemberNameLoc) { |
2546 | 105 | void *mem = Ctx.Allocate(sizeof(ImplementsAttr), alignof(ImplementsAttr)); |
2547 | 105 | return new (mem) ImplementsAttr(atLoc, range, TyR, |
2548 | 105 | MemberName, MemberNameLoc); |
2549 | 105 | } |
2550 | | |
2551 | | ImplementsAttr *ImplementsAttr::create(DeclContext *DC, |
2552 | | ProtocolDecl *Proto, |
2553 | 9.44k | DeclName MemberName) { |
2554 | 9.44k | auto &ctx = DC->getASTContext(); |
2555 | 9.44k | void *mem = ctx.Allocate(sizeof(ImplementsAttr), alignof(ImplementsAttr)); |
2556 | 9.44k | auto *attr = new (mem) ImplementsAttr( |
2557 | 9.44k | SourceLoc(), SourceRange(), nullptr, |
2558 | 9.44k | MemberName, DeclNameLoc()); |
2559 | 9.44k | ctx.evaluator.cacheOutput(ImplementsAttrProtocolRequest{attr, DC}, |
2560 | 9.44k | std::move(Proto)); |
2561 | 9.44k | return attr; |
2562 | 9.44k | } |
2563 | | |
2564 | 2.08k | ProtocolDecl *ImplementsAttr::getProtocol(DeclContext *dc) const { |
2565 | 2.08k | return evaluateOrDefault(dc->getASTContext().evaluator, |
2566 | 2.08k | ImplementsAttrProtocolRequest{this, dc}, nullptr); |
2567 | 2.08k | } |
2568 | | |
2569 | | CustomAttr::CustomAttr(SourceLoc atLoc, SourceRange range, TypeExpr *type, |
2570 | | PatternBindingInitializer *initContext, |
2571 | | ArgumentList *argList, bool implicit) |
2572 | | : DeclAttribute(DAK_Custom, atLoc, range, implicit), typeExpr(type), |
2573 | 27.7k | argList(argList), initContext(initContext) { |
2574 | 27.7k | assert(type); |
2575 | 0 | isArgUnsafeBit = false; |
2576 | 27.7k | } |
2577 | | |
2578 | | CustomAttr *CustomAttr::create(ASTContext &ctx, SourceLoc atLoc, TypeExpr *type, |
2579 | | PatternBindingInitializer *initContext, |
2580 | 27.7k | ArgumentList *argList, bool implicit) { |
2581 | 27.7k | assert(type); |
2582 | 0 | SourceRange range(atLoc, type->getSourceRange().End); |
2583 | 27.7k | if (argList) |
2584 | 8.50k | range.End = argList->getEndLoc(); |
2585 | | |
2586 | 27.7k | return new (ctx) |
2587 | 27.7k | CustomAttr(atLoc, range, type, initContext, argList, implicit); |
2588 | 27.7k | } |
2589 | | |
2590 | 154k | TypeRepr *CustomAttr::getTypeRepr() const { return typeExpr->getTypeRepr(); } |
2591 | 34.8k | Type CustomAttr::getType() const { return typeExpr->getInstanceType(); } |
2592 | | |
2593 | 3 | void CustomAttr::resetTypeInformation(TypeExpr *info) { typeExpr = info; } |
2594 | | |
2595 | 9.45k | void CustomAttr::setType(Type ty) { |
2596 | 9.45k | assert(ty); |
2597 | 0 | typeExpr->setType(MetatypeType::get(ty)); |
2598 | 9.45k | } |
2599 | | |
2600 | 8.17k | bool CustomAttr::isArgUnsafe() const { |
2601 | 8.17k | if (isArgUnsafeBit) |
2602 | 336 | return true; |
2603 | | |
2604 | 7.83k | auto args = getArgs(); |
2605 | 7.83k | if (!args) |
2606 | 7.44k | return false; |
2607 | | |
2608 | 393 | auto *unary = args->getUnlabeledUnaryExpr(); |
2609 | 393 | if (!unary) |
2610 | 48 | return false; |
2611 | | |
2612 | 345 | if (auto declRef = dyn_cast<UnresolvedDeclRefExpr>(unary)) { |
2613 | 318 | if (declRef->getName().isSimpleName("unsafe")) |
2614 | 306 | isArgUnsafeBit = true; |
2615 | 318 | } |
2616 | | |
2617 | 345 | return isArgUnsafeBit; |
2618 | 393 | } |
2619 | | |
2620 | | MacroRoleAttr::MacroRoleAttr(SourceLoc atLoc, SourceRange range, |
2621 | | MacroSyntax syntax, SourceLoc lParenLoc, |
2622 | | MacroRole role, |
2623 | | ArrayRef<MacroIntroducedDeclName> names, |
2624 | | ArrayRef<TypeExpr *> conformances, |
2625 | | SourceLoc rParenLoc, bool implicit) |
2626 | | : DeclAttribute(DAK_MacroRole, atLoc, range, implicit), |
2627 | | syntax(syntax), role(role), numNames(names.size()), |
2628 | | numConformances(conformances.size()), lParenLoc(lParenLoc), |
2629 | 20.2k | rParenLoc(rParenLoc) { |
2630 | 20.2k | auto *trailingNamesBuffer = getTrailingObjects<MacroIntroducedDeclName>(); |
2631 | 20.2k | std::uninitialized_copy(names.begin(), names.end(), trailingNamesBuffer); |
2632 | | |
2633 | 20.2k | auto *trailingConformancesBuffer = getTrailingObjects<TypeExpr *>(); |
2634 | 20.2k | std::uninitialized_copy(conformances.begin(), conformances.end(), |
2635 | 20.2k | trailingConformancesBuffer); |
2636 | 20.2k | } |
2637 | | |
2638 | | MacroRoleAttr * |
2639 | | MacroRoleAttr::create(ASTContext &ctx, SourceLoc atLoc, SourceRange range, |
2640 | | MacroSyntax syntax, SourceLoc lParenLoc, MacroRole role, |
2641 | | ArrayRef<MacroIntroducedDeclName> names, |
2642 | | ArrayRef<TypeExpr *> conformances, |
2643 | 20.2k | SourceLoc rParenLoc, bool implicit) { |
2644 | 20.2k | unsigned size = |
2645 | 20.2k | totalSizeToAlloc<MacroIntroducedDeclName, TypeExpr *>( |
2646 | 20.2k | names.size(), conformances.size()); |
2647 | 20.2k | auto *mem = ctx.Allocate(size, alignof(MacroRoleAttr)); |
2648 | 20.2k | return new (mem) MacroRoleAttr(atLoc, range, syntax, lParenLoc, role, names, |
2649 | 20.2k | conformances, rParenLoc, implicit); |
2650 | 20.2k | } |
2651 | | |
2652 | 25.1k | ArrayRef<MacroIntroducedDeclName> MacroRoleAttr::getNames() const { |
2653 | 25.1k | return { |
2654 | 25.1k | getTrailingObjects<MacroIntroducedDeclName>(), |
2655 | 25.1k | numNames |
2656 | 25.1k | }; |
2657 | 25.1k | } |
2658 | | |
2659 | 3.34k | ArrayRef<TypeExpr *> MacroRoleAttr::getConformances() const { |
2660 | 3.34k | return { |
2661 | 3.34k | getTrailingObjects<TypeExpr *>(), |
2662 | 3.34k | numConformances |
2663 | 3.34k | }; |
2664 | 3.34k | } |
2665 | | |
2666 | 7.21k | bool MacroRoleAttr::hasNameKind(MacroIntroducedDeclNameKind kind) const { |
2667 | 10.3k | return llvm::find_if(getNames(), [kind](MacroIntroducedDeclName name) { |
2668 | 10.3k | return name.getKind() == kind; |
2669 | 10.3k | }) != getNames().end(); |
2670 | 7.21k | } |
2671 | | |
2672 | 237 | StringRef ExternAttr::getCName(const FuncDecl *D) const { |
2673 | 237 | if (auto cName = this->Name) |
2674 | 147 | return cName.value(); |
2675 | | // If no name was specified, fall back on the Swift base name without mangling. |
2676 | | // Base name is always available and non-empty for FuncDecl. |
2677 | 90 | return D->getBaseIdentifier().str(); |
2678 | 237 | } |
2679 | | |
2680 | 2.80M | ExternAttr *ExternAttr::find(DeclAttributes &attrs, ExternKind kind) { |
2681 | 3.17M | for (DeclAttribute *attr : attrs) { |
2682 | 3.17M | if (auto *externAttr = dyn_cast<ExternAttr>(attr)) { |
2683 | 567 | if (externAttr->getExternKind() == kind) |
2684 | 375 | return externAttr; |
2685 | 567 | } |
2686 | 3.17M | } |
2687 | 2.80M | return nullptr; |
2688 | 2.80M | } |
2689 | | |
2690 | | const DeclAttribute * |
2691 | 1.93M | DeclAttributes::getEffectiveSendableAttr() const { |
2692 | 1.93M | const NonSendableAttr *assumedAttr = nullptr; |
2693 | | |
2694 | 1.93M | for (auto attr : getAttributes<NonSendableAttr>()) { |
2695 | 53.8k | if (attr->Specificity == NonSendableKind::Specific) |
2696 | 357 | return attr; |
2697 | 53.4k | if (!assumedAttr) |
2698 | 53.4k | assumedAttr = attr; |
2699 | 53.4k | } |
2700 | | |
2701 | 1.93M | if (auto sendableAttr = getAttribute<SendableAttr>()) |
2702 | 33.3k | return sendableAttr; |
2703 | | |
2704 | 1.90M | return assumedAttr; |
2705 | 1.93M | } |
2706 | | |
2707 | | ArrayRef<VarDecl *> StorageRestrictionsAttr::getInitializesProperties( |
2708 | 8.88k | AccessorDecl *attachedTo) const { |
2709 | 8.88k | auto &ctx = attachedTo->getASTContext(); |
2710 | 8.88k | return evaluateOrDefault(ctx.evaluator, |
2711 | 8.88k | InitAccessorReferencedVariablesRequest{ |
2712 | 8.88k | const_cast<StorageRestrictionsAttr *>(this), |
2713 | 8.88k | attachedTo, getInitializesNames()}, |
2714 | 8.88k | {}); |
2715 | 8.88k | } |
2716 | | |
2717 | | ArrayRef<VarDecl *> |
2718 | 4.73k | StorageRestrictionsAttr::getAccessesProperties(AccessorDecl *attachedTo) const { |
2719 | 4.73k | auto &ctx = attachedTo->getASTContext(); |
2720 | 4.73k | return evaluateOrDefault(ctx.evaluator, |
2721 | 4.73k | InitAccessorReferencedVariablesRequest{ |
2722 | 4.73k | const_cast<StorageRestrictionsAttr *>(this), |
2723 | 4.73k | attachedTo, getAccessesNames()}, |
2724 | 4.73k | {}); |
2725 | 4.73k | } |
2726 | | |
2727 | 0 | void swift::simple_display(llvm::raw_ostream &out, const DeclAttribute *attr) { |
2728 | 0 | if (attr) |
2729 | 0 | attr->print(out); |
2730 | 0 | } |
2731 | | |
2732 | | bool swift::hasAttribute( |
2733 | 60 | const LangOptions &langOpts, llvm::StringRef attributeName) { |
2734 | 60 | DeclAttrKind kind = DeclAttribute::getAttrKindFromString(attributeName); |
2735 | 60 | if (kind == DAK_Count) |
2736 | 45 | return false; |
2737 | | |
2738 | 15 | if (DeclAttribute::isUserInaccessible(kind)) |
2739 | 3 | return false; |
2740 | 12 | if (DeclAttribute::isDeclModifier(kind)) |
2741 | 3 | return false; |
2742 | 9 | if (DeclAttribute::shouldBeRejectedByParser(kind)) |
2743 | 0 | return false; |
2744 | 9 | if (DeclAttribute::isSilOnly(kind)) |
2745 | 0 | return false; |
2746 | 9 | if (DeclAttribute::isConcurrencyOnly(kind)) |
2747 | 0 | return false; |
2748 | | |
2749 | 9 | return true; |
2750 | 9 | } |