mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Type check ABI decls
Sema now type-checks the alternate ABI-providing decls inside of @abi attributes. Making this work—particularly, making redeclaration checking work—required making name lookup aware of ABI decls. Name lookup now evaluates both API-providing and ABI-providing declarations. In most cases, it will filter ABI-only decls out unless a specific flag is passed, in which case it will filter API-only decls out instead. Calls that simply retrieve a list of declarations, like `IterableDeclContext::getMembers()` and friends, typically only return API-providing decls; you have to access the ABI-providing ones through those. As part of that work, I have also added some basic compiler interfaces for working with the API-providing and ABI-providing variants. `ABIRole` encodes whether a declaration provides only API, only ABI, or both, and `ABIRoleInfo` combines that with a pointer to the counterpart providing the other role (for a declaration that provides both, that’ll just be a pointer to `this`). Decl checking of behavior specific to @abi will come in a future commit. Note that this probably doesn’t properly exercise some of the new code (ASTScope::lookupEnclosingABIAttributeScope(), for instance); I expect that to happen only once we can rename types using an @abi attribute, since that will create distinguishable behavior differences when resolving TypeReprs in other @abi attributes.
This commit is contained in:
@@ -150,6 +150,11 @@ class swift::SourceLookupCache {
|
||||
void add(ValueDecl *VD) {
|
||||
if (!VD->hasName()) return;
|
||||
VD->getName().addToLookupTable(Members, VD);
|
||||
|
||||
auto abiRole = ABIRoleInfo(VD);
|
||||
if (!abiRole.providesABI() && abiRole.getCounterpart())
|
||||
abiRole.getCounterpart()->getName()
|
||||
.addToLookupTable(Members, abiRole.getCounterpart());
|
||||
}
|
||||
|
||||
void clear() {
|
||||
@@ -546,7 +551,8 @@ void SourceLookupCache::lookupValue(DeclName Name, NLKind LookupKind,
|
||||
if (I != TopLevelValues.end()) {
|
||||
Result.reserve(I->second.size());
|
||||
for (ValueDecl *Elt : I->second)
|
||||
Result.push_back(Elt);
|
||||
if (ABIRoleInfo(Elt).matchesOptions(Flags))
|
||||
Result.push_back(Elt);
|
||||
}
|
||||
|
||||
// If we aren't supposed to find names introduced by macros, we're done.
|
||||
@@ -639,7 +645,8 @@ void SourceLookupCache::lookupVisibleDecls(ImportPath::Access AccessPath,
|
||||
if (I == TopLevelValues.end()) return;
|
||||
|
||||
for (auto vd : I->second)
|
||||
Consumer.foundDecl(vd, DeclVisibilityKind::VisibleAtTopLevel);
|
||||
if (ABIRoleInfo(vd).matchesOptions(OptionSet<ModuleLookupFlags>())) // FIXME: figure this out
|
||||
Consumer.foundDecl(vd, DeclVisibilityKind::VisibleAtTopLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -649,7 +656,8 @@ void SourceLookupCache::lookupVisibleDecls(ImportPath::Access AccessPath,
|
||||
// entry for the simple name so that we report each declaration once.
|
||||
if (tlv.first.isSimpleName() && !vd->getName().isSimpleName())
|
||||
continue;
|
||||
Consumer.foundDecl(vd, DeclVisibilityKind::VisibleAtTopLevel);
|
||||
if (ABIRoleInfo(vd).matchesOptions(OptionSet<ModuleLookupFlags>())) // FIXME: figure this out
|
||||
Consumer.foundDecl(vd, DeclVisibilityKind::VisibleAtTopLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,7 +682,8 @@ void SourceLookupCache::lookupVisibleDecls(ImportPath::Access AccessPath,
|
||||
});
|
||||
}
|
||||
for (auto *vd : macroExpandedDecls) {
|
||||
Consumer.foundDecl(vd, DeclVisibilityKind::VisibleAtTopLevel);
|
||||
if (ABIRoleInfo(vd).matchesOptions(OptionSet<ModuleLookupFlags>())) // FIXME: figure this out
|
||||
Consumer.foundDecl(vd, DeclVisibilityKind::VisibleAtTopLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -692,8 +701,9 @@ void SourceLookupCache::lookupClassMembers(ImportPath::Access accessPath,
|
||||
for (ValueDecl *vd : member.second) {
|
||||
auto *nominal = vd->getDeclContext()->getSelfNominalTypeDecl();
|
||||
if (nominal && nominal->getName() == accessPath.front().Item)
|
||||
consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup,
|
||||
DynamicLookupInfo::AnyObject);
|
||||
if (ABIRoleInfo(vd).matchesOptions(OptionSet<ModuleLookupFlags>())) // FIXME: figure this out
|
||||
consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup,
|
||||
DynamicLookupInfo::AnyObject);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -706,8 +716,9 @@ void SourceLookupCache::lookupClassMembers(ImportPath::Access accessPath,
|
||||
continue;
|
||||
|
||||
for (ValueDecl *vd : member.second)
|
||||
consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup,
|
||||
DynamicLookupInfo::AnyObject);
|
||||
if (ABIRoleInfo(vd).matchesOptions(OptionSet<ModuleLookupFlags>())) // FIXME: figure this out
|
||||
consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup,
|
||||
DynamicLookupInfo::AnyObject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -724,7 +735,8 @@ void SourceLookupCache::lookupClassMember(ImportPath::Access accessPath,
|
||||
for (ValueDecl *vd : iter->second) {
|
||||
auto *nominal = vd->getDeclContext()->getSelfNominalTypeDecl();
|
||||
if (nominal && nominal->getName() == accessPath.front().Item)
|
||||
results.push_back(vd);
|
||||
if (ABIRoleInfo(vd).matchesOptions(OptionSet<ModuleLookupFlags>())) // FIXME: figure this out
|
||||
results.push_back(vd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3848,7 +3860,7 @@ void SynthesizedFileUnit::lookupValue(
|
||||
SmallVectorImpl<ValueDecl *> &result) const {
|
||||
for (auto *decl : TopLevelDecls) {
|
||||
if (auto VD = dyn_cast<ValueDecl>(decl)) {
|
||||
if (VD->getName().matchesRef(name)) {
|
||||
if (VD->getName().matchesRef(name) && ABIRoleInfo(VD).matchesOptions(Flags)) {
|
||||
result.push_back(VD);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user