]> granicus.if.org Git - clang/commitdiff
Clear the linkage cache recursively. Fixes PR8926.
authorJohn McCall <rjmccall@apple.com>
Tue, 8 Feb 2011 19:01:05 +0000 (19:01 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 8 Feb 2011 19:01:05 +0000 (19:01 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125104 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
lib/AST/Decl.cpp

index f81f9d0ca46691677692c8b393b12f1f55e67ccc..e8431c11061eb0441184baf7655bea70b6d5234b 100644 (file)
@@ -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.
index 4fb47bfcdc50ccc0a2623f6a6d1b6682b90a0ea0..11614df500350c1c6d569639881e1f656c7e2071 100644 (file)
@@ -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) ==