Skip to content

Commit bb6dcef

Browse files
authored
Merge pull request #80035 from tshortli/import-clang-availability-domains
ClangImporter: Look up availability domains in Clang modules
2 parents 275a679 + e96b44b commit bb6dcef

18 files changed

+499
-32
lines changed

include/swift/AST/DeclContext.h

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define SWIFT_DECLCONTEXT_H
2121

2222
#include "swift/AST/ASTAllocated.h"
23+
#include "swift/AST/AvailabilityDomain.h"
2324
#include "swift/AST/Identifier.h"
2425
#include "swift/AST/LookupKinds.h"
2526
#include "swift/AST/ResilienceExpansion.h"
@@ -667,6 +668,12 @@ class alignas(1 << DeclContextAlignInBits) DeclContext
667668
ObjCSelector selector,
668669
SmallVectorImpl<AbstractFunctionDecl *> &results) const;
669670

671+
/// Look up the custom availability domains matching the given identifier that
672+
/// are visible from this context.
673+
void
674+
lookupAvailabilityDomains(Identifier identifier,
675+
SmallVectorImpl<AvailabilityDomain> &results) const;
676+
670677
/// Looks up an infix operator with a given \p name.
671678
///
672679
/// This returns a vector of results, as it's possible to find multiple infix

include/swift/AST/FileUnit.h

+8
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,14 @@ class FileUnit : public DeclContext, public ASTAllocated<FileUnit> {
126126
const ModuleDecl *importedModule,
127127
llvm::SmallSetVector<Identifier, 4> &spiGroups) const {};
128128

129+
/// Find all availability domains defined in this module with the given
130+
/// identifier.
131+
///
132+
/// This does a simple local lookup, not recursively looking through imports.
133+
virtual void lookupAvailabilityDomains(
134+
Identifier identifier,
135+
SmallVectorImpl<AvailabilityDomain> &results) const {};
136+
129137
virtual std::optional<Fingerprint>
130138
loadFingerprint(const IterableDeclContext *IDC) const {
131139
return std::nullopt;

include/swift/AST/Module.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,12 @@ class ModuleDecl
970970
const ModuleDecl *importedModule,
971971
llvm::SmallSetVector<Identifier, 4> &spiGroups) const;
972972

973+
/// Finds the custom availability domain defined by this module with the
974+
/// given identifier and if one exists adds it to results.
975+
void
976+
lookupAvailabilityDomains(Identifier identifier,
977+
SmallVectorImpl<AvailabilityDomain> &results) const;
978+
973979
// Is \p attr accessible as an explicitly imported SPI from this module?
974980
bool isImportedAsSPI(const SpecializeAttr *attr,
975981
const ValueDecl *targetDecl) const;
@@ -1234,11 +1240,6 @@ class ModuleDecl
12341240
/// An empty `Version` is returned if the information is not available.
12351241
version::Version getLanguageVersionBuiltWith() const;
12361242

1237-
/// Returns the custom availability domain defined by this module with the
1238-
/// given identifier, if one exists.
1239-
std::optional<AvailabilityDomain>
1240-
getAvailabilityDomainForIdentifier(Identifier identifier) const;
1241-
12421243
void setAvailabilityDomains(const AvailabilityDomainMap &&map) {
12431244
AvailabilityDomains = std::move(map);
12441245
}

include/swift/ClangImporter/ClangModule.h

+4
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ class ClangModuleUnit final : public LoadedFile {
9090
ObjCSelector selector,
9191
SmallVectorImpl<AbstractFunctionDecl *> &results) const override;
9292

93+
void lookupAvailabilityDomains(
94+
Identifier identifier,
95+
SmallVectorImpl<AvailabilityDomain> &results) const override;
96+
9397
virtual void getTopLevelDecls(SmallVectorImpl<Decl*> &results) const override;
9498

9599
virtual void getDisplayDecls(SmallVectorImpl<Decl*> &results, bool recursive = false) const override;

lib/AST/AvailabilityDomain.cpp

+7-16
Original file line numberDiff line numberDiff line change
@@ -288,21 +288,6 @@ void CustomAvailabilityDomain::Profile(llvm::FoldingSetNodeID &ID,
288288
ID.AddInteger(static_cast<unsigned>(kind));
289289
}
290290

291-
static std::optional<AvailabilityDomain>
292-
getAvailabilityDomainForName(Identifier identifier,
293-
const DeclContext *declContext) {
294-
if (auto builtinDomain = AvailabilityDomain::builtinDomainForString(
295-
identifier.str(), declContext))
296-
return builtinDomain;
297-
298-
auto &ctx = declContext->getASTContext();
299-
if (auto customDomain =
300-
ctx.MainModule->getAvailabilityDomainForIdentifier(identifier))
301-
return customDomain;
302-
303-
return std::nullopt;
304-
}
305-
306291
std::optional<AvailabilityDomain>
307292
AvailabilityDomainOrIdentifier::lookUpInDeclContext(
308293
SourceLoc loc, const DeclContext *declContext) const {
@@ -312,7 +297,13 @@ AvailabilityDomainOrIdentifier::lookUpInDeclContext(
312297
auto &diags = ctx.Diags;
313298
std::optional<AvailabilityDomain> domain;
314299
auto identifier = getAsIdentifier().value();
315-
domain = getAvailabilityDomainForName(identifier, declContext);
300+
301+
llvm::SmallVector<AvailabilityDomain> results;
302+
declContext->lookupAvailabilityDomains(identifier, results);
303+
if (results.size() > 0) {
304+
// FIXME: [availability] Diagnose ambiguity if necessary.
305+
domain = results.front();
306+
}
316307

317308
if (!domain) {
318309
auto domainString = identifier.str();

lib/AST/Module.cpp

+12-9
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,18 @@ void ModuleDecl::lookupImportedSPIGroups(
10901090
FORWARD(lookupImportedSPIGroups, (importedModule, spiGroups));
10911091
}
10921092

1093+
void ModuleDecl::lookupAvailabilityDomains(
1094+
Identifier identifier,
1095+
llvm::SmallVectorImpl<AvailabilityDomain> &results) const {
1096+
auto iter = AvailabilityDomains.find(identifier);
1097+
if (iter != AvailabilityDomains.end()) {
1098+
results.push_back(AvailabilityDomain::forCustom(iter->getSecond()));
1099+
return;
1100+
}
1101+
1102+
FORWARD(lookupAvailabilityDomains, (identifier, results));
1103+
}
1104+
10931105
void BuiltinUnit::lookupValue(DeclName name, NLKind lookupKind,
10941106
OptionSet<ModuleLookupFlags> Flags,
10951107
SmallVectorImpl<ValueDecl*> &result) const {
@@ -4172,15 +4184,6 @@ version::Version ModuleDecl::getLanguageVersionBuiltWith() const {
41724184
return version::Version();
41734185
}
41744186

4175-
std::optional<AvailabilityDomain>
4176-
ModuleDecl::getAvailabilityDomainForIdentifier(Identifier identifier) const {
4177-
auto iter = AvailabilityDomains.find(identifier);
4178-
if (iter == AvailabilityDomains.end())
4179-
return std::nullopt;
4180-
4181-
return AvailabilityDomain::forCustom(iter->getSecond());
4182-
}
4183-
41844187
//===----------------------------------------------------------------------===//
41854188
// MARK: SwiftSettings
41864189
//===----------------------------------------------------------------------===//

lib/AST/NameLookup.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -2893,6 +2893,21 @@ void DeclContext::lookupAllObjCMethods(
28932893
results.end());
28942894
}
28952895

2896+
void DeclContext::lookupAvailabilityDomains(
2897+
Identifier identifier, SmallVectorImpl<AvailabilityDomain> &results) const {
2898+
if (auto builtinDomain =
2899+
AvailabilityDomain::builtinDomainForString(identifier.str(), this)) {
2900+
results.push_back(*builtinDomain);
2901+
return;
2902+
}
2903+
2904+
// FIXME: [availability] Find the file/module scope decl context and look up
2905+
// the domain in that context using a request to cache the results.
2906+
for (auto import : namelookup::getAllImports(this)) {
2907+
import.importedModule->lookupAvailabilityDomains(identifier, results);
2908+
}
2909+
}
2910+
28962911
/// Given a set of type declarations, find all of the nominal type declarations
28972912
/// that they reference, looking through typealiases as appropriate.
28982913
static TinyPtrVector<NominalTypeDecl *>

lib/ClangImporter/ClangImporter.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -4103,6 +4103,39 @@ void ClangModuleUnit::lookupObjCMethods(
41034103
}
41044104
}
41054105

4106+
void ClangModuleUnit::lookupAvailabilityDomains(
4107+
Identifier identifier, SmallVectorImpl<AvailabilityDomain> &results) const {
4108+
auto lookupTable = owner.findLookupTable(clangModule);
4109+
if (!lookupTable)
4110+
return;
4111+
4112+
auto varDecl = lookupTable->lookupAvailabilityDomainDecl(identifier.str());
4113+
if (!varDecl)
4114+
return;
4115+
4116+
auto featureInfo = getClangASTContext().getFeatureAvailInfo(varDecl);
4117+
if (featureInfo.first.empty())
4118+
return;
4119+
4120+
auto getDomainKind = [](clang::FeatureAvailKind featureAvailKind) {
4121+
switch (featureAvailKind) {
4122+
case clang::FeatureAvailKind::None:
4123+
llvm_unreachable("unexpected kind");
4124+
case clang::FeatureAvailKind::Available:
4125+
return CustomAvailabilityDomain::Kind::Enabled;
4126+
case clang::FeatureAvailKind::Unavailable:
4127+
return CustomAvailabilityDomain::Kind::Disabled;
4128+
case clang::FeatureAvailKind::Dynamic:
4129+
return CustomAvailabilityDomain::Kind::Dynamic;
4130+
}
4131+
};
4132+
4133+
auto domain = AvailabilityDomain::forCustom(CustomAvailabilityDomain::get(
4134+
featureInfo.first, getParentModule(),
4135+
getDomainKind(featureInfo.second.Kind), getASTContext()));
4136+
results.push_back(domain);
4137+
}
4138+
41064139
void ClangModuleUnit::collectLinkLibraries(
41074140
ModuleDecl::LinkLibraryCallback callback) const {
41084141
if (!clangModule)

lib/ClangImporter/ImportDecl.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -9186,6 +9186,34 @@ void ClangImporter::Implementation::importAttributes(
91869186
MappedDecl->getAttrs().add(AvAttr);
91879187
}
91889188

9189+
// __attribute__((availability(domain:)))
9190+
//
9191+
if (auto avail = dyn_cast<clang::DomainAvailabilityAttr>(*AI)) {
9192+
auto *declContext = MappedDecl->getInnermostDeclContext();
9193+
9194+
// FIXME: [availability] Don't look up the availability domain. Clang
9195+
// should be serializing the resolved VarDecl for the availability domain
9196+
// it found when type checking the attribute.
9197+
auto domainIdentifier = SwiftContext.getIdentifier(avail->getDomain());
9198+
llvm::SmallVector<AvailabilityDomain, 4> results;
9199+
declContext->lookupAvailabilityDomains(domainIdentifier, results);
9200+
9201+
if (results.size() > 0) {
9202+
// FIXME: [availability] Diagnose ambiguous availabilty domain name?
9203+
auto AttrKind = avail->getUnavailable()
9204+
? AvailableAttr::Kind::Unavailable
9205+
: AvailableAttr::Kind::Default;
9206+
9207+
auto avAttr = new (C) AvailableAttr(
9208+
SourceLoc(), SourceRange(), results.front(), SourceLoc(), AttrKind,
9209+
/*Message=*/"", /*Rename=*/"", /*Introduced=*/{}, SourceRange(),
9210+
/*Deprecated=*/{}, SourceRange(), /*Obsoleted=*/{}, SourceRange(),
9211+
/*Implicit=*/false, /*IsSPI=*/false);
9212+
9213+
MappedDecl->getAttrs().add(avAttr);
9214+
}
9215+
}
9216+
91899217
// __attribute__((swift_attr("attribute"))) are handled by
91909218
// importSwiftAttrAttributes(). Other attributes are ignored.
91919219
}

0 commit comments

Comments
 (0)