|
17 | 17 | #include "swift/AST/Module.h"
|
18 | 18 | #include "swift/AST/TypeCheckRequests.h"
|
19 | 19 | #include "swift/Basic/Assertions.h"
|
| 20 | +#include "clang/AST/ASTContext.h" |
| 21 | +#include "clang/AST/Decl.h" |
20 | 22 | #include "llvm/ADT/StringSwitch.h"
|
21 | 23 |
|
22 | 24 | using namespace swift;
|
23 | 25 |
|
| 26 | +CustomAvailabilityDomain::Kind |
| 27 | +getCustomDomainKind(clang::FeatureAvailKind featureAvailKind) { |
| 28 | + switch (featureAvailKind) { |
| 29 | + case clang::FeatureAvailKind::None: |
| 30 | + llvm_unreachable("unexpected kind"); |
| 31 | + case clang::FeatureAvailKind::Available: |
| 32 | + return CustomAvailabilityDomain::Kind::Enabled; |
| 33 | + case clang::FeatureAvailKind::Unavailable: |
| 34 | + return CustomAvailabilityDomain::Kind::Disabled; |
| 35 | + case clang::FeatureAvailKind::Dynamic: |
| 36 | + return CustomAvailabilityDomain::Kind::Dynamic; |
| 37 | + } |
| 38 | +} |
| 39 | + |
| 40 | +static const CustomAvailabilityDomain * |
| 41 | +customDomainForClangDecl(Decl *decl, const ASTContext &ctx) { |
| 42 | + auto *clangDecl = decl->getClangDecl(); |
| 43 | + ASSERT(clangDecl); |
| 44 | + |
| 45 | + auto featureInfo = clangDecl->getASTContext().getFeatureAvailInfo( |
| 46 | + const_cast<clang::Decl *>(clangDecl)); |
| 47 | + |
| 48 | + // Ensure the decl actually represents an availability domain. |
| 49 | + if (featureInfo.first.empty()) |
| 50 | + return nullptr; |
| 51 | + |
| 52 | + if (featureInfo.second.Kind == clang::FeatureAvailKind::None) |
| 53 | + return nullptr; |
| 54 | + |
| 55 | + return CustomAvailabilityDomain::get( |
| 56 | + featureInfo.first, getCustomDomainKind(featureInfo.second.Kind), |
| 57 | + decl->getModuleContext(), decl, ctx); |
| 58 | +} |
| 59 | + |
| 60 | +std::optional<AvailabilityDomain> |
| 61 | +AvailabilityDomain::forCustom(Decl *decl, const ASTContext &ctx) { |
| 62 | + if (!decl) |
| 63 | + return std::nullopt; |
| 64 | + |
| 65 | + if (decl->hasClangNode()) { |
| 66 | + if (auto *customDomain = customDomainForClangDecl(decl, ctx)) |
| 67 | + return AvailabilityDomain::forCustom(customDomain); |
| 68 | + } else { |
| 69 | + // FIXME: [availability] Handle Swift availability domains decls. |
| 70 | + } |
| 71 | + |
| 72 | + return std::nullopt; |
| 73 | +} |
| 74 | + |
24 | 75 | std::optional<AvailabilityDomain>
|
25 | 76 | AvailabilityDomain::builtinDomainForString(StringRef string,
|
26 | 77 | const DeclContext *declContext) {
|
@@ -166,6 +217,13 @@ llvm::StringRef AvailabilityDomain::getNameForAttributePrinting() const {
|
166 | 217 | }
|
167 | 218 | }
|
168 | 219 |
|
| 220 | +Decl *AvailabilityDomain::getDecl() const { |
| 221 | + if (auto *customDomain = getCustomDomain()) |
| 222 | + return customDomain->getDecl(); |
| 223 | + |
| 224 | + return nullptr; |
| 225 | +} |
| 226 | + |
169 | 227 | ModuleDecl *AvailabilityDomain::getModule() const {
|
170 | 228 | if (auto customDomain = getCustomDomain())
|
171 | 229 | return customDomain->getModule();
|
@@ -268,19 +326,17 @@ bool StableAvailabilityDomainComparator::operator()(
|
268 | 326 | }
|
269 | 327 | }
|
270 | 328 |
|
271 |
| -CustomAvailabilityDomain::CustomAvailabilityDomain(Identifier name, |
272 |
| - ModuleDecl *mod, Kind kind) |
273 |
| - : name(name), kind(kind), mod(mod) { |
| 329 | +CustomAvailabilityDomain::CustomAvailabilityDomain(Identifier name, Kind kind, |
| 330 | + ModuleDecl *mod, Decl *decl) |
| 331 | + : name(name), kind(kind), mod(mod), decl(decl) { |
274 | 332 | ASSERT(!name.empty());
|
275 | 333 | ASSERT(mod);
|
276 | 334 | }
|
277 | 335 |
|
278 | 336 | void CustomAvailabilityDomain::Profile(llvm::FoldingSetNodeID &ID,
|
279 |
| - Identifier name, ModuleDecl *mod, |
280 |
| - Kind kind) { |
| 337 | + Identifier name, ModuleDecl *mod) { |
281 | 338 | ID.AddPointer(name.getAsOpaquePointer());
|
282 | 339 | ID.AddPointer(mod);
|
283 |
| - ID.AddInteger(static_cast<unsigned>(kind)); |
284 | 340 | }
|
285 | 341 |
|
286 | 342 | std::optional<AvailabilityDomain>
|
|
0 commit comments