summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-02-08 19:01:05 +0000
committerJohn McCall <rjmccall@apple.com>2011-02-08 19:01:05 +0000
commitd396b97c5a2223e399808cc797fa85b27e17631a (patch)
tree0b5e35127faa35c277bebea311b8de13198b593f
parent86e48b6940cc744dbb5ca8f91f6a3d9a4bf254b6 (diff)
downloadbcm5719-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.h2
-rw-r--r--clang/lib/AST/Decl.cpp31
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) ==
OpenPOWER on IntegriCloud