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:
Becca Royal-Gordon
2024-09-26 15:20:32 -07:00
parent 01b8bbea89
commit 08e2a4ddae
28 changed files with 629 additions and 140 deletions

View File

@@ -330,6 +330,7 @@ bool ModuleFile::mayHaveDiagnosticsPointingAtBuffer() const {
ModuleFile::~ModuleFile() { }
void ModuleFile::lookupValue(DeclName name,
OptionSet<ModuleLookupFlags> flags,
SmallVectorImpl<ValueDecl*> &results) {
PrettyStackTraceModuleFile stackEntry(*this);
@@ -350,7 +351,8 @@ void ModuleFile::lookupValue(DeclName name,
}
auto VD = cast<ValueDecl>(declOrError.get());
if (name.isSimpleName() || VD->getName().matchesRef(name))
results.push_back(VD);
if (ABIRoleInfo(VD).matchesOptions(flags))
results.push_back(VD);
}
}
}
@@ -368,7 +370,8 @@ void ModuleFile::lookupValue(DeclName name,
continue;
}
auto VD = cast<ValueDecl>(declOrError.get());
results.push_back(VD);
if (ABIRoleInfo(VD).matchesOptions(flags))
results.push_back(VD);
}
}
}
@@ -453,7 +456,8 @@ TypeDecl *ModuleFile::lookupNestedType(Identifier name,
diagnoseAndConsumeError(typeOrErr.takeError());
continue;
}
return cast<TypeDecl>(typeOrErr.get());
if (ABIRoleInfo(typeOrErr.get()).providesAPI()) // FIXME: flags?
return cast<TypeDecl>(typeOrErr.get());
}
}
}
@@ -622,6 +626,8 @@ void ModuleFile::lookupVisibleDecls(ImportPath::Access accessPath,
diagnoseAndConsumeError(declOrError.takeError());
return;
}
if (!ABIRoleInfo(declOrError.get()).providesAPI()) // FIXME: flags?
return;
consumer.foundDecl(cast<ValueDecl>(declOrError.get()),
DeclVisibilityKind::VisibleAtTopLevel);
};
@@ -1005,6 +1011,8 @@ void ModuleFile::getTopLevelDecls(
consumeError(declOrError.takeError());
continue;
}
if (!ABIRoleInfo(declOrError.get()).providesAPI()) // FIXME: flags
continue;
results.push_back(declOrError.get());
}
}
@@ -1053,6 +1061,8 @@ ModuleFile::getLocalTypeDecls(SmallVectorImpl<TypeDecl *> &results) {
for (auto DeclID : Core->LocalTypeDecls->data()) {
auto TD = cast<TypeDecl>(getDecl(DeclID));
if (!ABIRoleInfo(TD).providesAPI()) // FIXME: flags
continue;
results.push_back(TD);
}
}