diff options
| author | John McCall <rjmccall@apple.com> | 2011-02-08 19:01:05 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2011-02-08 19:01:05 +0000 |
| commit | d396b97c5a2223e399808cc797fa85b27e17631a (patch) | |
| tree | 0b5e35127faa35c277bebea311b8de13198b593f | |
| parent | 86e48b6940cc744dbb5ca8f91f6a3d9a4bf254b6 (diff) | |
| download | bcm5719-llvm-d396b97c5a2223e399808cc797fa85b27e17631a.tar.gz bcm5719-llvm-d396b97c5a2223e399808cc797fa85b27e17631a.zip | |
Clear the linkage cache recursively. Fixes PR8926.
llvm-svn: 125104
| -rw-r--r-- | clang/include/clang/AST/Decl.h | 2 | ||||
| -rw-r--r-- | clang/lib/AST/Decl.cpp | 31 |
2 files changed, 32 insertions, 1 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index f81f9d0ca46..e8431c11061 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -274,7 +274,7 @@ public: /// \brief Clear the linkage cache in response to a change /// to the declaration. - void ClearLinkageCache() { HasCachedLinkage = 0; } + void ClearLinkageCache(); /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for /// the underlying named decl. diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 4fb47bfcdc5..11614df5003 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -579,6 +579,37 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) { 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 { if (HasCachedLinkage) { assert(Linkage(CachedLinkage) == |

