Clear the linkage cache recursively. Fixes PR8926.

llvm-svn: 125104
This commit is contained in:
John McCall 2011-02-08 19:01:05 +00:00
parent 86e48b6940
commit d396b97c5a
2 changed files with 32 additions and 1 deletions

View File

@ -274,7 +274,7 @@ public:
/// \brief Clear the linkage cache in response to a change /// \brief Clear the linkage cache in response to a change
/// to the declaration. /// to the declaration.
void ClearLinkageCache() { HasCachedLinkage = 0; } void ClearLinkageCache();
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl. /// the underlying named decl.

View File

@ -579,6 +579,37 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
return LV; return LV;
} }
static void clearLinkageForClass(const CXXRecordDecl *record) {
for (CXXRecordDecl::decl_iterator
i = record->decls_begin(), e = record->decls_end(); i != e; ++i) {
Decl *child = *i;
if (isa<NamedDecl>(child))
cast<NamedDecl>(child)->ClearLinkageCache();
}
}
void NamedDecl::ClearLinkageCache() {
// Note that we can't skip clearing the linkage of children just
// because the parent doesn't have cached linkage: we don't cache
// when computing linkage for parent contexts.
HasCachedLinkage = 0;
// If we're changing the linkage of a class, we need to reset the
// linkage of child declarations, too.
if (const CXXRecordDecl *record = dyn_cast<CXXRecordDecl>(this))
clearLinkageForClass(record);
if (const ClassTemplateDecl *temp = dyn_cast<ClassTemplateDecl>(this)) {
// Clear linkage for the template pattern.
CXXRecordDecl *record = temp->getTemplatedDecl();
record->HasCachedLinkage = 0;
clearLinkageForClass(record);
// ...do we need to clear linkage for specializations, too?
}
}
Linkage NamedDecl::getLinkage() const { Linkage NamedDecl::getLinkage() const {
if (HasCachedLinkage) { if (HasCachedLinkage) {
assert(Linkage(CachedLinkage) == assert(Linkage(CachedLinkage) ==