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:
Joe Groff
2019-04-10 11:11:14 -07:00
parent 733b08bdf0
commit 399332b75b
29 changed files with 613 additions and 47 deletions

View File

@@ -59,6 +59,7 @@ namespace swift {
class FileUnit;
class FuncDecl;
class InfixOperatorDecl;
class LazyResolver;
class LinkLibrary;
class LookupCache;
class ModuleLoader;
@@ -341,6 +342,11 @@ public:
/// This does a simple local lookup, not recursively looking through imports.
TypeDecl *lookupLocalType(StringRef MangledName) const;
/// Look up an opaque return type by the mangled name of the declaration
/// that defines it.
OpaqueTypeDecl *lookupOpaqueResultType(StringRef MangledName,
LazyResolver *resolver);
/// Find ValueDecls in the module and pass them to the given consumer object.
///
/// This does a simple local lookup, not recursively looking through imports.
@@ -642,6 +648,13 @@ public:
virtual TypeDecl *lookupLocalType(StringRef MangledName) const {
return nullptr;
}
/// Look up an opaque return type by the mangled name of the declaration
/// that defines it.
virtual OpaqueTypeDecl *lookupOpaqueResultType(StringRef MangledName,
LazyResolver *resolver) {
return nullptr;
}
/// Directly look for a nested type declared within this module inside the
/// given nominal type (including any extensions).
@@ -740,6 +753,9 @@ public:
/// This does a simple local lookup, not recursively looking through imports.
/// The order of the results is not guaranteed to be meaningful.
virtual void getLocalTypeDecls(SmallVectorImpl<TypeDecl*> &results) const {}
virtual void
getOpaqueReturnTypeDecls(SmallVectorImpl<OpaqueTypeDecl*> &results) const {}
/// Adds all top-level decls to the given vector.
///
@@ -982,6 +998,12 @@ public:
/// The list of local type declarations in the source file.
llvm::SetVector<TypeDecl *> LocalTypeDecls;
/// The set of validated opaque return type decls in the source file.
llvm::StringMap<OpaqueTypeDecl *> ValidatedOpaqueReturnTypes;
/// The set of parsed decls with opaque return types that have not yet
/// been validated.
llvm::DenseSet<ValueDecl *> UnvalidatedDeclsWithOpaqueReturnTypes;
/// A set of special declaration attributes which require the
/// Foundation module to be imported to work. If the foundation
@@ -1089,6 +1111,8 @@ public:
virtual void
getLocalTypeDecls(SmallVectorImpl<TypeDecl*> &results) const override;
virtual void
getOpaqueReturnTypeDecls(SmallVectorImpl<OpaqueTypeDecl*> &results) const override;
virtual void
getImportedModules(SmallVectorImpl<ModuleDecl::ImportedModule> &imports,
@@ -1262,6 +1286,15 @@ public:
void setSyntaxRoot(syntax::SourceFileSyntax &&Root);
bool hasSyntaxRoot() const;
OpaqueTypeDecl *lookupOpaqueResultType(StringRef MangledName,
LazyResolver *resolver) override;
void addUnvalidatedDeclWithOpaqueResultType(ValueDecl *vd) {
UnvalidatedDeclsWithOpaqueReturnTypes.insert(vd);
}
void markDeclWithOpaqueResultTypeAsValidated(ValueDecl *vd);
private:
/// If not None, the underlying vector should contain tokens of this source file.
@@ -1300,7 +1333,7 @@ public:
getDiscriminatorForPrivateValue(const ValueDecl *D) const override {
llvm_unreachable("no private values in the Builtin module");
}
static bool classof(const FileUnit *file) {
return file->getKind() == FileUnitKind::Builtin;
}