mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[AST] Stash an archetype builder in an "incomplete" generic environment.
This eliminates the really gross registration of archetype builders within the ASTContext, and is another little step toward lazily constructing archetypes.
This commit is contained in:
@@ -762,8 +762,13 @@ public:
|
|||||||
|
|
||||||
/// Retrieve or create the stored archetype builder for the given
|
/// Retrieve or create the stored archetype builder for the given
|
||||||
/// canonical generic signature and module.
|
/// canonical generic signature and module.
|
||||||
std::pair<ArchetypeBuilder *, GenericEnvironment *>
|
ArchetypeBuilder *getOrCreateArchetypeBuilder(CanGenericSignature sig,
|
||||||
getOrCreateArchetypeBuilder(CanGenericSignature sig, ModuleDecl *mod);
|
ModuleDecl *mod);
|
||||||
|
|
||||||
|
/// Retrieve or create the canonical generic environment of a canonical
|
||||||
|
/// archetype builder.
|
||||||
|
GenericEnvironment *getOrCreateCanonicalGenericEnvironment(
|
||||||
|
ArchetypeBuilder *builder);
|
||||||
|
|
||||||
/// Retrieve the inherited name set for the given class.
|
/// Retrieve the inherited name set for the given class.
|
||||||
const InheritedNameSet *getAllPropertyNames(ClassDecl *classDecl,
|
const InheritedNameSet *getAllPropertyNames(ClassDecl *classDecl,
|
||||||
@@ -796,26 +801,6 @@ private:
|
|||||||
DeclContext *gpContext,
|
DeclContext *gpContext,
|
||||||
ArrayRef<Substitution> Subs) const;
|
ArrayRef<Substitution> Subs) const;
|
||||||
|
|
||||||
/// Retrieve the archetype builder and potential archetype
|
|
||||||
/// corresponding to the given archetype type.
|
|
||||||
///
|
|
||||||
/// This facility is only used by the archetype builder when forming
|
|
||||||
/// archetypes.a
|
|
||||||
std::pair<ArchetypeBuilder *, ArchetypeBuilder::PotentialArchetype *>
|
|
||||||
getLazyArchetype(const ArchetypeType *archetype);
|
|
||||||
|
|
||||||
/// Register information for a lazily-constructed archetype.
|
|
||||||
void registerLazyArchetype(
|
|
||||||
const ArchetypeType *archetype,
|
|
||||||
ArchetypeBuilder &builder,
|
|
||||||
ArchetypeBuilder::PotentialArchetype *potentialArchetype);
|
|
||||||
|
|
||||||
/// Unregister information about the given lazily-constructed archetype.
|
|
||||||
void unregisterLazyArchetype(const ArchetypeType *archetype);
|
|
||||||
|
|
||||||
friend class ArchetypeType;
|
|
||||||
friend class ArchetypeBuilder::PotentialArchetype;
|
|
||||||
|
|
||||||
/// Provide context-level uniquing for SIL lowered type layouts.
|
/// Provide context-level uniquing for SIL lowered type layouts.
|
||||||
friend SILLayout;
|
friend SILLayout;
|
||||||
llvm::FoldingSet<SILLayout> *&getSILLayouts();
|
llvm::FoldingSet<SILLayout> *&getSILLayouts();
|
||||||
|
|||||||
@@ -33,12 +33,20 @@ class SILType;
|
|||||||
/// generic parameters of a DeclContext.
|
/// generic parameters of a DeclContext.
|
||||||
class alignas(1 << DeclAlignInBits) GenericEnvironment final {
|
class alignas(1 << DeclAlignInBits) GenericEnvironment final {
|
||||||
GenericSignature *Signature;
|
GenericSignature *Signature;
|
||||||
|
ArchetypeBuilder *Builder;
|
||||||
TypeSubstitutionMap ArchetypeToInterfaceMap;
|
TypeSubstitutionMap ArchetypeToInterfaceMap;
|
||||||
TypeSubstitutionMap InterfaceToArchetypeMap;
|
TypeSubstitutionMap InterfaceToArchetypeMap;
|
||||||
|
|
||||||
GenericEnvironment(GenericSignature *signature,
|
GenericEnvironment(GenericSignature *signature,
|
||||||
|
ArchetypeBuilder *builder,
|
||||||
TypeSubstitutionMap interfaceToArchetypeMap);
|
TypeSubstitutionMap interfaceToArchetypeMap);
|
||||||
|
|
||||||
|
friend class ArchetypeType;
|
||||||
|
friend class ArchetypeBuilder;
|
||||||
|
|
||||||
|
ArchetypeBuilder *getArchetypeBuilder() const { return Builder; }
|
||||||
|
void clearArchetypeBuilder() { Builder = nullptr; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GenericSignature *getGenericSignature() const {
|
GenericSignature *getGenericSignature() const {
|
||||||
return Signature;
|
return Signature;
|
||||||
@@ -53,15 +61,14 @@ public:
|
|||||||
bool containsPrimaryArchetype(ArchetypeType *archetype) const;
|
bool containsPrimaryArchetype(ArchetypeType *archetype) const;
|
||||||
|
|
||||||
static
|
static
|
||||||
GenericEnvironment *get(ASTContext &ctx,
|
GenericEnvironment *get(GenericSignature *signature,
|
||||||
GenericSignature *signature,
|
|
||||||
TypeSubstitutionMap interfaceToArchetypeMap);
|
TypeSubstitutionMap interfaceToArchetypeMap);
|
||||||
|
|
||||||
/// Create a new, "incomplete" generic environment that will be populated
|
/// Create a new, "incomplete" generic environment that will be populated
|
||||||
/// by calls to \c addMapping().
|
/// by calls to \c addMapping().
|
||||||
static
|
static
|
||||||
GenericEnvironment *getIncomplete(ASTContext &ctx,
|
GenericEnvironment *getIncomplete(GenericSignature *signature,
|
||||||
GenericSignature *signature);
|
ArchetypeBuilder *builder);
|
||||||
|
|
||||||
/// Add a mapping of a generic parameter to a specific type (which may be
|
/// Add a mapping of a generic parameter to a specific type (which may be
|
||||||
/// an archetype)
|
/// an archetype)
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ class alignas(1 << TypeAlignInBits) GenericSignature final
|
|||||||
/// Retrieve the archetype builder for the given generic signature.
|
/// Retrieve the archetype builder for the given generic signature.
|
||||||
ArchetypeBuilder *getArchetypeBuilder(ModuleDecl &mod);
|
ArchetypeBuilder *getArchetypeBuilder(ModuleDecl &mod);
|
||||||
|
|
||||||
|
friend class ArchetypeType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Create a new generic signature with the given type parameters and
|
/// Create a new generic signature with the given type parameters and
|
||||||
/// requirements.
|
/// requirements.
|
||||||
|
|||||||
@@ -207,19 +207,16 @@ struct ASTContext::Implementation {
|
|||||||
llvm::DenseMap<Decl *, std::pair<LazyMemberLoader *, uint64_t>>
|
llvm::DenseMap<Decl *, std::pair<LazyMemberLoader *, uint64_t>>
|
||||||
ConformanceLoaders;
|
ConformanceLoaders;
|
||||||
|
|
||||||
/// Mapping from archetypes with lazily-resolved nested types to the
|
/// Stored archetype builders for canonical generic signatures.
|
||||||
/// archetype builder and potential archetype corresponding to that
|
|
||||||
/// archetype.
|
|
||||||
llvm::DenseMap<const ArchetypeType *,
|
|
||||||
std::pair<ArchetypeBuilder *,
|
|
||||||
ArchetypeBuilder::PotentialArchetype *>>
|
|
||||||
LazyArchetypes;
|
|
||||||
|
|
||||||
/// \brief Stored archetype builders and their corresponding (canonical)
|
|
||||||
/// generic environments.
|
|
||||||
llvm::DenseMap<std::pair<GenericSignature *, ModuleDecl *>,
|
llvm::DenseMap<std::pair<GenericSignature *, ModuleDecl *>,
|
||||||
std::pair<std::unique_ptr<ArchetypeBuilder>,
|
std::unique_ptr<ArchetypeBuilder>>
|
||||||
GenericEnvironment *>> ArchetypeBuilders;
|
ArchetypeBuilders;
|
||||||
|
|
||||||
|
/// Canonical generic environments for canonical generic signatures.
|
||||||
|
///
|
||||||
|
/// The keys are the archetype builders in \c ArchetypeBuilders.
|
||||||
|
llvm::DenseMap<ArchetypeBuilder *, GenericEnvironment *>
|
||||||
|
CanonicalGenericEnvironments;
|
||||||
|
|
||||||
/// The set of property names that show up in the defining module of a
|
/// The set of property names that show up in the defining module of a
|
||||||
/// class.
|
/// class.
|
||||||
@@ -1254,25 +1251,36 @@ void ASTContext::getVisibleTopLevelClangModules(
|
|||||||
collectAllModules(Modules);
|
collectAllModules(Modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ArchetypeBuilder *, GenericEnvironment *>
|
ArchetypeBuilder *ASTContext::getOrCreateArchetypeBuilder(
|
||||||
ASTContext::getOrCreateArchetypeBuilder(CanGenericSignature sig,
|
CanGenericSignature sig,
|
||||||
ModuleDecl *mod) {
|
ModuleDecl *mod) {
|
||||||
// Check whether we already have an archetype builder for this
|
// Check whether we already have an archetype builder for this
|
||||||
// signature and module.
|
// signature and module.
|
||||||
auto known = Impl.ArchetypeBuilders.find({sig, mod});
|
auto known = Impl.ArchetypeBuilders.find({sig, mod});
|
||||||
if (known != Impl.ArchetypeBuilders.end())
|
if (known != Impl.ArchetypeBuilders.end())
|
||||||
return { known->second.first.get(), known->second.second };
|
return known->second.get();
|
||||||
|
|
||||||
// Create a new archetype builder with the given signature.
|
// Create a new archetype builder with the given signature.
|
||||||
auto builder = new ArchetypeBuilder(*mod);
|
auto builder = new ArchetypeBuilder(*mod);
|
||||||
builder->addGenericSignature(sig, nullptr);
|
builder->addGenericSignature(sig, nullptr);
|
||||||
|
|
||||||
// Store this archetype builder and its generic environment.
|
|
||||||
auto genericEnv = builder->getGenericEnvironment(sig);
|
|
||||||
Impl.ArchetypeBuilders[{sig, mod}]
|
|
||||||
= { std::unique_ptr<ArchetypeBuilder>(builder), genericEnv };
|
|
||||||
|
|
||||||
return { builder, genericEnv };
|
// Store this archetype builder (no generic environment yet).
|
||||||
|
Impl.ArchetypeBuilders[{sig, mod}] =
|
||||||
|
std::unique_ptr<ArchetypeBuilder>(builder);
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericEnvironment *ASTContext::getOrCreateCanonicalGenericEnvironment(
|
||||||
|
ArchetypeBuilder *builder) {
|
||||||
|
auto known = Impl.CanonicalGenericEnvironments.find(builder);
|
||||||
|
if (known != Impl.CanonicalGenericEnvironments.find(builder))
|
||||||
|
return known->second;
|
||||||
|
|
||||||
|
auto sig = builder->getGenericSignature();
|
||||||
|
auto env = builder->getGenericEnvironment(sig);
|
||||||
|
Impl.CanonicalGenericEnvironments[builder] = env;
|
||||||
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
Module *
|
Module *
|
||||||
@@ -3551,22 +3559,24 @@ GenericSignature *GenericSignature::get(ArrayRef<GenericTypeParamType *> params,
|
|||||||
}
|
}
|
||||||
|
|
||||||
GenericEnvironment *
|
GenericEnvironment *
|
||||||
GenericEnvironment::get(ASTContext &ctx,
|
GenericEnvironment::get(GenericSignature *signature,
|
||||||
GenericSignature *signature,
|
|
||||||
TypeSubstitutionMap interfaceToArchetypeMap) {
|
TypeSubstitutionMap interfaceToArchetypeMap) {
|
||||||
assert(!interfaceToArchetypeMap.empty());
|
assert(!interfaceToArchetypeMap.empty());
|
||||||
assert(interfaceToArchetypeMap.size() == signature->getGenericParams().size()
|
assert(interfaceToArchetypeMap.size() == signature->getGenericParams().size()
|
||||||
&& "incorrect number of parameters");
|
&& "incorrect number of parameters");
|
||||||
|
|
||||||
|
|
||||||
return new (ctx) GenericEnvironment(signature, interfaceToArchetypeMap);
|
ASTContext &ctx = signature->getASTContext();
|
||||||
|
return new (ctx) GenericEnvironment(signature, nullptr,
|
||||||
|
interfaceToArchetypeMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericEnvironment *GenericEnvironment::getIncomplete(
|
GenericEnvironment *GenericEnvironment::getIncomplete(
|
||||||
ASTContext &ctx,
|
GenericSignature *signature,
|
||||||
GenericSignature *signature) {
|
ArchetypeBuilder *builder) {
|
||||||
TypeSubstitutionMap empty;
|
TypeSubstitutionMap empty;
|
||||||
return new (ctx) GenericEnvironment(signature, empty);
|
auto &ctx = signature->getASTContext();
|
||||||
|
return new (ctx) GenericEnvironment(signature, builder, empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclName::CompoundDeclName::Profile(llvm::FoldingSetNodeID &id,
|
void DeclName::CompoundDeclName::Profile(llvm::FoldingSetNodeID &id,
|
||||||
@@ -3886,27 +3896,6 @@ Type ASTContext::getBridgedToObjC(const DeclContext *dc, Type type,
|
|||||||
return Type();
|
return Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ArchetypeBuilder *, ArchetypeBuilder::PotentialArchetype *>
|
|
||||||
ASTContext::getLazyArchetype(const ArchetypeType *archetype) {
|
|
||||||
auto known = Impl.LazyArchetypes.find(archetype);
|
|
||||||
assert(known != Impl.LazyArchetypes.end());
|
|
||||||
return known->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASTContext::registerLazyArchetype(
|
|
||||||
const ArchetypeType *archetype,
|
|
||||||
ArchetypeBuilder &builder,
|
|
||||||
ArchetypeBuilder::PotentialArchetype *potentialArchetype) {
|
|
||||||
assert(Impl.LazyArchetypes.count(archetype) == 0);
|
|
||||||
Impl.LazyArchetypes[archetype] = { &builder, potentialArchetype };
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASTContext::unregisterLazyArchetype(const ArchetypeType *archetype) {
|
|
||||||
auto known = Impl.LazyArchetypes.find(archetype);
|
|
||||||
assert(known != Impl.LazyArchetypes.end());
|
|
||||||
Impl.LazyArchetypes.erase(known);
|
|
||||||
}
|
|
||||||
|
|
||||||
const InheritedNameSet *ASTContext::getAllPropertyNames(ClassDecl *classDecl,
|
const InheritedNameSet *ASTContext::getAllPropertyNames(ClassDecl *classDecl,
|
||||||
bool forInstance) {
|
bool forInstance) {
|
||||||
// If this class was defined in Objective-C, perform the lookup based on
|
// If this class was defined in Objective-C, perform the lookup based on
|
||||||
|
|||||||
@@ -767,7 +767,6 @@ ArchetypeBuilder::PotentialArchetype::getTypeInContext(
|
|||||||
// Collect the set of nested types of this archetype, and put them into
|
// Collect the set of nested types of this archetype, and put them into
|
||||||
// the archetype itself.
|
// the archetype itself.
|
||||||
if (!representative->getNestedTypes().empty()) {
|
if (!representative->getNestedTypes().empty()) {
|
||||||
ctx.registerLazyArchetype(arch, builder, this);
|
|
||||||
SmallVector<std::pair<Identifier, NestedType>, 4> FlatNestedTypes;
|
SmallVector<std::pair<Identifier, NestedType>, 4> FlatNestedTypes;
|
||||||
for (auto Nested : representative->getNestedTypes()) {
|
for (auto Nested : representative->getNestedTypes()) {
|
||||||
// Skip type aliases, which are just shortcuts.
|
// Skip type aliases, which are just shortcuts.
|
||||||
@@ -790,8 +789,6 @@ ArchetypeBuilder::PotentialArchetype::getTypeInContext(
|
|||||||
|
|
||||||
// Force the resolution of the nested types.
|
// Force the resolution of the nested types.
|
||||||
(void)arch->getAllNestedTypes();
|
(void)arch->getAllNestedTypes();
|
||||||
|
|
||||||
ctx.unregisterLazyArchetype(arch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NestedType::forArchetype(arch);
|
return NestedType::forArchetype(arch);
|
||||||
@@ -799,15 +796,15 @@ ArchetypeBuilder::PotentialArchetype::getTypeInContext(
|
|||||||
|
|
||||||
void ArchetypeType::resolveNestedType(
|
void ArchetypeType::resolveNestedType(
|
||||||
std::pair<Identifier, NestedType> &nested) const {
|
std::pair<Identifier, NestedType> &nested) const {
|
||||||
auto &ctx = const_cast<ArchetypeType *>(this)->getASTContext();
|
|
||||||
auto lazyArchetype = ctx.getLazyArchetype(this);
|
|
||||||
|
|
||||||
ArchetypeBuilder &builder = *lazyArchetype.first;
|
|
||||||
auto genericEnv = getGenericEnvironment();
|
auto genericEnv = getGenericEnvironment();
|
||||||
auto potentialArchetype =
|
auto &builder = *genericEnv->getArchetypeBuilder();
|
||||||
lazyArchetype.second->getNestedType(nested.first, builder);
|
|
||||||
|
|
||||||
auto result = potentialArchetype->getTypeInContext(builder, genericEnv);
|
Type interfaceType =
|
||||||
|
genericEnv->mapTypeOutOfContext(&builder.getModule(),
|
||||||
|
const_cast<ArchetypeType *>(this));
|
||||||
|
auto parentPA = builder.resolveArchetype(interfaceType);
|
||||||
|
auto memberPA = parentPA->getNestedType(nested.first, builder);
|
||||||
|
auto result = memberPA->getTypeInContext(builder, genericEnv);
|
||||||
assert(!nested.second ||
|
assert(!nested.second ||
|
||||||
nested.second.getValue()->isEqual(result.getValue()) ||
|
nested.second.getValue()->isEqual(result.getValue()) ||
|
||||||
(nested.second.getValue()->hasError() &&
|
(nested.second.getValue()->hasError() &&
|
||||||
@@ -2235,11 +2232,10 @@ GenericSignature *ArchetypeBuilder::getGenericSignature() {
|
|||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericEnvironment *ArchetypeBuilder::getGenericEnvironment(GenericSignature *signature) {
|
GenericEnvironment *ArchetypeBuilder::getGenericEnvironment(
|
||||||
TypeSubstitutionMap interfaceToArchetypeMap;
|
GenericSignature *signature) {
|
||||||
|
|
||||||
// Compute the archetypes for the generic parameters.
|
// Compute the archetypes for the generic parameters.
|
||||||
auto genericEnv = GenericEnvironment::getIncomplete(Context, signature);
|
auto genericEnv = GenericEnvironment::getIncomplete(signature, this);
|
||||||
for (auto pa : Impl->PotentialArchetypes) {
|
for (auto pa : Impl->PotentialArchetypes) {
|
||||||
Type contextType = pa->getTypeInContext(*this, genericEnv).getValue();
|
Type contextType = pa->getTypeInContext(*this, genericEnv).getValue();
|
||||||
if (!genericEnv->getMappingIfPresent(pa->getGenericParamKey()))
|
if (!genericEnv->getMappingIfPresent(pa->getGenericParamKey()))
|
||||||
@@ -2268,6 +2264,7 @@ GenericEnvironment *ArchetypeBuilder::getGenericEnvironment(GenericSignature *si
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
genericEnv->clearArchetypeBuilder();
|
||||||
return genericEnv;
|
return genericEnv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -198,8 +198,7 @@ getBuiltinGenericFunction(Identifier Id,
|
|||||||
GenericSignature *Sig =
|
GenericSignature *Sig =
|
||||||
GenericSignature::get(GenericParamTypes, { });
|
GenericSignature::get(GenericParamTypes, { });
|
||||||
GenericEnvironment *Env =
|
GenericEnvironment *Env =
|
||||||
GenericEnvironment::get(Context, Sig,
|
GenericEnvironment::get(Sig, InterfaceToArchetypeMap);
|
||||||
InterfaceToArchetypeMap);
|
|
||||||
|
|
||||||
Type InterfaceType = GenericFunctionType::get(Sig, ArgParamType, ResType,
|
Type InterfaceType = GenericFunctionType::get(Sig, ArgParamType, ResType,
|
||||||
AnyFunctionType::ExtInfo());
|
AnyFunctionType::ExtInfo());
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ using namespace swift;
|
|||||||
|
|
||||||
GenericEnvironment::GenericEnvironment(
|
GenericEnvironment::GenericEnvironment(
|
||||||
GenericSignature *signature,
|
GenericSignature *signature,
|
||||||
|
ArchetypeBuilder *builder,
|
||||||
TypeSubstitutionMap interfaceToArchetypeMap)
|
TypeSubstitutionMap interfaceToArchetypeMap)
|
||||||
: Signature(signature)
|
: Signature(signature), Builder(builder)
|
||||||
{
|
{
|
||||||
// Build a mapping in both directions, making sure to canonicalize the
|
// Build a mapping in both directions, making sure to canonicalize the
|
||||||
// interface type where it is used as a key, so that substitution can
|
// interface type where it is used as a key, so that substitution can
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ ArchetypeBuilder *GenericSignature::getArchetypeBuilder(ModuleDecl &mod) {
|
|||||||
|
|
||||||
// Archetype builders are stored on the ASTContext.
|
// Archetype builders are stored on the ASTContext.
|
||||||
return getASTContext().getOrCreateArchetypeBuilder(CanGenericSignature(this),
|
return getASTContext().getOrCreateArchetypeBuilder(CanGenericSignature(this),
|
||||||
&mod).first;
|
&mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenericSignature::isCanonical() const {
|
bool GenericSignature::isCanonical() const {
|
||||||
@@ -522,8 +522,8 @@ CanType GenericSignature::getCanonicalTypeInContext(Type type, ModuleDecl &mod)
|
|||||||
GenericEnvironment *CanGenericSignature::getGenericEnvironment(
|
GenericEnvironment *CanGenericSignature::getGenericEnvironment(
|
||||||
ModuleDecl &module) const {
|
ModuleDecl &module) const {
|
||||||
// Archetype builders are stored on the ASTContext.
|
// Archetype builders are stored on the ASTContext.
|
||||||
return module.getASTContext().getOrCreateArchetypeBuilder(*this, &module)
|
return module.getASTContext().getOrCreateCanonicalGenericEnvironment(
|
||||||
.second;
|
module.getASTContext().getOrCreateArchetypeBuilder(*this, &module));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned GenericParamKey::findIndexIn(
|
unsigned GenericParamKey::findIndexIn(
|
||||||
|
|||||||
@@ -952,8 +952,7 @@ GenericEnvironment *ModuleFile::readGenericEnvironment(
|
|||||||
assert(!interfaceToArchetypeMap.empty() &&
|
assert(!interfaceToArchetypeMap.empty() &&
|
||||||
"no archetypes in generic function?");
|
"no archetypes in generic function?");
|
||||||
|
|
||||||
return GenericEnvironment::get(getContext(), signature,
|
return GenericEnvironment::get(signature, interfaceToArchetypeMap);
|
||||||
interfaceToArchetypeMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericEnvironment *ModuleFile::maybeReadGenericEnvironment() {
|
GenericEnvironment *ModuleFile::maybeReadGenericEnvironment() {
|
||||||
|
|||||||
Reference in New Issue
Block a user