mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Parsable interface and type reconstruction support for opaque types.
When printing a swiftinterface, represent opaque result types using an attribute that refers to the mangled name of the defining decl for the opaque type. To turn this back into a reference to the right decl's implicit OpaqueTypeDecl, use type reconstruction. Since type reconstruction doesn't normally concern itself with non-type decls, set up a lookup table in SourceFiles and ModuleFiles to let us handle the mapping from mangled name to opaque type decl in type reconstruction. (Since we're invoking type reconstruction during type checking, when the module hasn't yet been fully validated, we need to plumb a LazyResolver into the ASTBuilder in an unsightly way. Maybe there's a better way to do this... Longer term, at least, this surface design gives space for doing things more the right way--a more request-ified decl validator ought to be able to naturally lazily service this request without the LazyResolver reference, and if type reconstruction in the future learns how to reconstruct non-type decls, then the lookup tables can go away.)
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "swift/AST/Module.h"
|
||||
#include "swift/AST/AccessScope.h"
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/ASTMangler.h"
|
||||
#include "swift/AST/ASTPrinter.h"
|
||||
#include "swift/AST/ASTScope.h"
|
||||
#include "swift/AST/ASTWalker.h"
|
||||
@@ -36,6 +37,7 @@
|
||||
#include "swift/Basic/Compiler.h"
|
||||
#include "swift/Basic/SourceManager.h"
|
||||
#include "swift/Basic/Statistic.h"
|
||||
#include "swift/Demangling/ManglingMacros.h"
|
||||
#include "swift/Parse/Token.h"
|
||||
#include "swift/Strings.h"
|
||||
#include "swift/Syntax/SyntaxNodes.h"
|
||||
@@ -410,6 +412,17 @@ TypeDecl * ModuleDecl::lookupLocalType(StringRef MangledName) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OpaqueTypeDecl *
|
||||
ModuleDecl::lookupOpaqueResultType(StringRef MangledName,
|
||||
LazyResolver *resolver) {
|
||||
for (auto file : getFiles()) {
|
||||
auto OTD = file->lookupOpaqueResultType(MangledName, resolver);
|
||||
if (OTD)
|
||||
return OTD;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ModuleDecl::lookupMember(SmallVectorImpl<ValueDecl*> &results,
|
||||
DeclContext *container, DeclName name,
|
||||
Identifier privateDiscriminator) const {
|
||||
@@ -445,7 +458,7 @@ void ModuleDecl::lookupMember(SmallVectorImpl<ValueDecl*> &results,
|
||||
// one...unless we're already in a private context, in which case everything
|
||||
// is private and a discriminator is unnecessary.
|
||||
if (alreadyInPrivateContext) {
|
||||
assert(privateDiscriminator.empty() && "unnecessary private-discriminator");
|
||||
assert(privateDiscriminator.empty() && "unnecessary private discriminator");
|
||||
// Don't remove anything; everything here is private anyway.
|
||||
|
||||
} else if (privateDiscriminator.empty()) {
|
||||
@@ -566,6 +579,14 @@ void SourceFile::getLocalTypeDecls(SmallVectorImpl<TypeDecl*> &Results) const {
|
||||
Results.append(LocalTypeDecls.begin(), LocalTypeDecls.end());
|
||||
}
|
||||
|
||||
void
|
||||
SourceFile::getOpaqueReturnTypeDecls(SmallVectorImpl<OpaqueTypeDecl*> &Results)
|
||||
const {
|
||||
for (auto &member : ValidatedOpaqueReturnTypes) {
|
||||
Results.push_back(member.second);
|
||||
}
|
||||
}
|
||||
|
||||
TypeDecl *SourceFile::lookupLocalType(llvm::StringRef mangledName) const {
|
||||
ASTContext &ctx = getASTContext();
|
||||
for (auto typeDecl : LocalTypeDecls) {
|
||||
@@ -1738,6 +1759,41 @@ void SourceFile::createReferencedNameTracker() {
|
||||
ReferencedNames.emplace(ReferencedNameTracker());
|
||||
}
|
||||
|
||||
OpaqueTypeDecl *
|
||||
SourceFile::lookupOpaqueResultType(StringRef MangledName,
|
||||
LazyResolver *resolver) {
|
||||
// Check already-validated decls.
|
||||
auto found = ValidatedOpaqueReturnTypes.find(MangledName);
|
||||
if (found != ValidatedOpaqueReturnTypes.end())
|
||||
return found->second;
|
||||
|
||||
// If there are unvalidated decls with opaque types, go through and validate
|
||||
// them now.
|
||||
if (resolver && !UnvalidatedDeclsWithOpaqueReturnTypes.empty()) {
|
||||
while (!UnvalidatedDeclsWithOpaqueReturnTypes.empty()) {
|
||||
ValueDecl *decl = *UnvalidatedDeclsWithOpaqueReturnTypes.begin();
|
||||
UnvalidatedDeclsWithOpaqueReturnTypes.erase(decl);
|
||||
resolver->resolveDeclSignature(decl);
|
||||
}
|
||||
|
||||
found = ValidatedOpaqueReturnTypes.find(MangledName);
|
||||
if (found != ValidatedOpaqueReturnTypes.end())
|
||||
return found->second;
|
||||
}
|
||||
|
||||
// Otherwise, we don't have a matching opaque decl.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SourceFile::markDeclWithOpaqueResultTypeAsValidated(ValueDecl *vd) {
|
||||
UnvalidatedDeclsWithOpaqueReturnTypes.erase(vd);
|
||||
if (auto opaqueDecl = vd->getOpaqueResultTypeDecl()) {
|
||||
Mangle::ASTMangler mangler;
|
||||
auto name = mangler.mangleDeclAsUSR(vd, MANGLING_PREFIX_STR);
|
||||
ValidatedOpaqueReturnTypes.insert({name, opaqueDecl});
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Miscellaneous
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user