More refactoring; allow ConstructorLookup to find constructors in classes.

Swift SVN r2171
This commit is contained in:
Eli Friedman
2012-06-07 23:57:18 +00:00
parent 72e1bed79e
commit 18dfa5cf7d
4 changed files with 162 additions and 181 deletions

View File

@@ -223,177 +223,6 @@ void Module::lookupValue(AccessPathTy AccessPath, Identifier Name,
.lookupValue(AccessPath, Name, LookupKind, TU, Result);
}
static void DoGlobalExtensionLookup(Type BaseType, Identifier Name,
ArrayRef<ValueDecl*> BaseMembers,
Module *CurModule,
Module *BaseModule,
SmallVectorImpl<ValueDecl*> &Result) {
bool CurModuleHasTypeDecl = false;
llvm::SmallPtrSet<CanType, 8> CurModuleTypes;
bool NameBindingLookup = CurModule->ASTStage == Module::Parsed;
// Find all extensions in this module.
for (ExtensionDecl *ED : CurModule->lookupExtensions(BaseType)) {
for (Decl *Member : ED->getMembers()) {
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member)) {
if (VD->getName() == Name) {
Result.push_back(VD);
if (!NameBindingLookup)
CurModuleTypes.insert(VD->getType()->getCanonicalType());
CurModuleHasTypeDecl |= isa<MetaTypeType>(VD->getType());
}
}
}
}
if (BaseModule == CurModule) {
for (ValueDecl *VD : BaseMembers) {
if (VD->getName() == Name) {
Result.push_back(VD);
if (!NameBindingLookup)
CurModuleTypes.insert(VD->getType()->getCanonicalType());
CurModuleHasTypeDecl |= isa<MetaTypeType>(VD->getType());
}
}
}
// The builtin module has no imports.
if (isa<BuiltinModule>(CurModule)) return;
// If we find a type in the current module, don't look into any
// imported modules.
if (CurModuleHasTypeDecl) return;
TranslationUnit &TU = *cast<TranslationUnit>(CurModule);
// Otherwise, check our imported extensions as well.
// FIXME: Implement DAG-based shadowing rules.
llvm::SmallPtrSet<Module *, 16> Visited;
for (auto &ImpEntry : TU.getImportedModules()) {
if (!Visited.insert(ImpEntry.second))
continue;
for (ExtensionDecl *ED : ImpEntry.second->lookupExtensions(BaseType)) {
for (Decl *Member : ED->getMembers()) {
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member)) {
if (VD->getName() == Name &&
(NameBindingLookup || isa<TypeDecl>(VD) ||
!CurModuleTypes.count(VD->getType()->getCanonicalType()))) {
Result.push_back(VD);
}
}
}
}
}
if (BaseModule != CurModule) {
for (ValueDecl *VD : BaseMembers) {
if (VD->getName() == Name &&
(NameBindingLookup || isa<TypeDecl>(VD) ||
!CurModuleTypes.count(VD->getType()->getCanonicalType()))) {
Result.push_back(VD);
}
}
}
}
/// lookupGlobalExtensionMethods - Lookup the extensions members for the
/// specified BaseType with the specified type, and return them in Result.
void Module::lookupMembers(Type BaseType, Identifier Name,
SmallVectorImpl<ValueDecl*> &Result) {
assert(Result.empty() &&
"This expects that the input list is empty, could be generalized");
TypeDecl *D;
ArrayRef<ValueDecl*> BaseMembers;
SmallVector<ValueDecl*, 2> BaseMembersStorage;
if (StructType *ST = BaseType->getAs<StructType>()) {
// FIXME: Refuse to look up "constructors" until we have real constructors.
if (ST->getDecl()->getName() == Name)
return;
D = ST->getDecl();
for (Decl* Member : ST->getDecl()->getMembers()) {
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member))
BaseMembersStorage.push_back(VD);
}
BaseMembers = BaseMembersStorage;
} else if (ClassType *CT = BaseType->getAs<ClassType>()) {
D = CT->getDecl();
for (Decl* Member : CT->getDecl()->getMembers()) {
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member))
BaseMembersStorage.push_back(VD);
}
BaseMembers = BaseMembersStorage;
} else if (OneOfType *OOT = BaseType->getAs<OneOfType>()) {
// FIXME: Refuse to look up "constructors" until we have real constructors.
if (OOT->getDecl()->getName() == Name)
return;
D = OOT->getDecl();
for (Decl* Member : OOT->getDecl()->getMembers()) {
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member))
BaseMembersStorage.push_back(VD);
}
BaseMembers = BaseMembersStorage;
} else {
return;
}
DeclContext *DC = D->getDeclContext();
while (!DC->isModuleContext())
DC = DC->getParent();
DoGlobalExtensionLookup(BaseType, Name, BaseMembers, this, cast<Module>(DC),
Result);
}
/// lookupGlobalExtensionMethods - Lookup the extensions members for the
/// specified BaseType with the specified type, and return them in Result.
void Module::lookupValueConstructors(Type BaseType,
SmallVectorImpl<ValueDecl*> &Result) {
assert(Result.empty() &&
"This expects that the input list is empty, could be generalized");
TypeDecl *D;
Identifier Constructor = Ctx.getIdentifier("constructor");
ArrayRef<ValueDecl*> BaseMembers;
SmallVector<ValueDecl*, 2> BaseMembersStorage;
if (StructType *ST = BaseType->getAs<StructType>()) {
D = ST->getDecl();
for (Decl* Member : ST->getDecl()->getMembers()) {
if (ValueDecl *VD = dyn_cast<ValueDecl>(Member))
BaseMembersStorage.push_back(VD);
}
BaseMembers = BaseMembersStorage;
} else if (OneOfType *OOT = BaseType->getAs<OneOfType>()) {
D = OOT->getDecl();
for (Decl* Member : OOT->getDecl()->getMembers()) {
// FIXME: We shouldn't be injecting OneOfElementDecls into the results
// like this.
if (OneOfElementDecl *OOED = dyn_cast<OneOfElementDecl>(Member))
Result.push_back(OOED);
else if (ValueDecl *VD = dyn_cast<ValueDecl>(Member))
BaseMembersStorage.push_back(VD);
}
} else {
return;
}
DeclContext *DC = D->getDeclContext();
if (!DC->isModuleContext()) {
for (ValueDecl *VD : BaseMembers) {
if (VD->getName() == Constructor)
Result.push_back(VD);
}
return;
}
DoGlobalExtensionLookup(BaseType, Constructor, BaseMembers, this,
cast<Module>(DC), Result);
}
//===----------------------------------------------------------------------===//
// TranslationUnit Implementation
//===----------------------------------------------------------------------===//