|
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