Have the name binder publish the list of imported modules into the TranslationUnit,

making it a real part of the AST.  Also, rework TUModuleCache to do its computation
when it is constructed, instead of trying in each query.


Swift SVN r809
This commit is contained in:
Chris Lattner
2011-11-01 06:19:36 +00:00
parent 1f42ec4679
commit 5d8d0fd2f6
3 changed files with 58 additions and 48 deletions

View File

@@ -94,6 +94,8 @@ namespace {
public:
typedef Module::AccessPathTy AccessPathTy;
TUModuleCache(TranslationUnit &TU);
TypeAliasDecl *lookupType(AccessPathTy AccessPath, Identifier Name,
NLKind LookupKind, TranslationUnit &TU);
void lookupValue(AccessPathTy AccessPath, Identifier Name,
@@ -102,14 +104,29 @@ namespace {
};
} // end anonymous namespace.
static TUModuleCache &getTUCachePimpl(void *&Ptr) {
static TUModuleCache &getTUCachePimpl(void *&Ptr, TranslationUnit &TU) {
// FIXME: This leaks. Sticking this into ASTContext isn't enough because then
// the DenseMap will leak.
if (Ptr == 0)
Ptr = new TUModuleCache();
Ptr = new TUModuleCache(TU);
return *(TUModuleCache*)Ptr;
}
/// Populate our cache on the first name lookup.
TUModuleCache::TUModuleCache(TranslationUnit &TU) {
for (auto Elt : TU.Body->getElements())
if (Decl *D = Elt.dyn_cast<Decl*>()) {
if (TypeAliasDecl *TAD = dyn_cast<TypeAliasDecl>(D))
if (!TAD->Name.empty())
TopLevelTypes[TAD->Name] = TAD;
if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
if (!VD->Name.empty())
TopLevelValues[VD->Name].push_back(VD);
}
}
TypeAliasDecl *TUModuleCache::lookupType(AccessPathTy AccessPath,
Identifier Name, NLKind LookupKind,
TranslationUnit &TU) {
@@ -120,14 +137,6 @@ TypeAliasDecl *TUModuleCache::lookupType(AccessPathTy AccessPath,
if (AccessPath.size() == 1 && AccessPath[0].first != Name)
return 0;
if (TopLevelTypes.empty()) {
for (auto Elt : TU.Body->getElements())
if (Decl *D = Elt.dyn_cast<Decl*>())
if (TypeAliasDecl *TAD = dyn_cast<TypeAliasDecl>(D))
if (!TAD->Name.empty())
TopLevelTypes[TAD->Name] = TAD;
}
auto I = TopLevelTypes.find(Name);
return I != TopLevelTypes.end() ? I->second : 0;
}
@@ -144,15 +153,6 @@ void TUModuleCache::lookupValue(AccessPathTy AccessPath, Identifier Name,
if (AccessPath.size() == 1 && AccessPath[0].first != Name)
return;
// If we haven't built a map of the top-level values, do so now.
if (TopLevelValues.empty()) {
for (auto Elt : TU.Body->getElements())
if (Decl *D = Elt.dyn_cast<Decl*>())
if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
if (!VD->Name.empty())
TopLevelValues[VD->Name].push_back(VD);
}
auto I = TopLevelValues.find(Name);
if (I == TopLevelValues.end()) return;
@@ -185,8 +185,9 @@ TypeAliasDecl *Module::lookupType(AccessPathTy AccessPath, Identifier Name,
// Otherwise must be TranslationUnit. Someday we should generalize this to
// allow modules with multiple translation units.
return getTUCachePimpl(LookupCachePimpl)
.lookupType(AccessPath, Name, LookupKind, *cast<TranslationUnit>(this));
TranslationUnit &TU = *cast<TranslationUnit>(this);
return getTUCachePimpl(LookupCachePimpl, TU)
.lookupType(AccessPath, Name, LookupKind, TU);
}
/// lookupValue - Look up a (possibly overloaded) value set at top-level scope
@@ -204,7 +205,8 @@ void Module::lookupValue(AccessPathTy AccessPath, Identifier Name,
// Otherwise must be TranslationUnit. Someday we should generalize this to
// allow modules with multiple translation units.
return getTUCachePimpl(LookupCachePimpl)
.lookupValue(AccessPath, Name, LookupKind, *cast<TranslationUnit>(this),
Result);
TranslationUnit &TU = *cast<TranslationUnit>(this);
return getTUCachePimpl(LookupCachePimpl, TU)
.lookupValue(AccessPath, Name, LookupKind, TU, Result);
}