r228978 - [modules] When collecting declarations to complete a redeclaration chain for an

Richard Smith richard-llvm at metafoo.co.uk
Thu Feb 12 15:21:45 PST 2015


Author: rsmith
Date: Thu Feb 12 17:21:45 2015
New Revision: 228978

URL: http://llvm.org/viewvc/llvm-project?rev=228978&view=rev
Log:
[modules] When collecting declarations to complete a redeclaration chain for an
entity, put the originally-canonical decl IDs in the right places in the redecl
chain rather than reordering them all to the start. If we don't ensure that the
redecl chain order is consistent with the topological module order, we can fail
to make a declaration visible if later declarations are in more IDNSs than
earlier ones (for instance, because the earlier decls are invisible friends).

Added:
    cfe/trunk/test/Modules/Inputs/merge-decl-order/
    cfe/trunk/test/Modules/Inputs/merge-decl-order/a.h
    cfe/trunk/test/Modules/Inputs/merge-decl-order/b.h
    cfe/trunk/test/Modules/Inputs/merge-decl-order/module.modulemap
    cfe/trunk/test/Modules/merge-decl-order.cpp
Modified:
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/test/Modules/cxx-templates.cpp

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=228978&r1=228977&r2=228978&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Feb 12 17:21:45 2015
@@ -3264,47 +3264,53 @@ void ASTReader::loadDeclUpdateRecords(se
 }
 
 namespace {
-  /// \brief Module visitor class that finds all of the redeclarations of a 
-  /// 
+  /// \brief Module visitor class that finds all of the redeclarations of a
+  /// redeclarable declaration.
   class RedeclChainVisitor {
     ASTReader &Reader;
     SmallVectorImpl<DeclID> &SearchDecls;
     llvm::SmallPtrSetImpl<Decl *> &Deserialized;
     GlobalDeclID CanonID;
     SmallVector<Decl *, 4> Chain;
-    
+
   public:
     RedeclChainVisitor(ASTReader &Reader, SmallVectorImpl<DeclID> &SearchDecls,
                        llvm::SmallPtrSetImpl<Decl *> &Deserialized,
                        GlobalDeclID CanonID)
       : Reader(Reader), SearchDecls(SearchDecls), Deserialized(Deserialized),
-        CanonID(CanonID) { 
-      for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I)
-        addToChain(Reader.GetDecl(SearchDecls[I]));
+        CanonID(CanonID) {
+      // Ensure that the canonical ID goes at the start of the chain.
+      addToChain(Reader.GetDecl(CanonID));
     }
-    
+
     static bool visit(ModuleFile &M, bool Preorder, void *UserData) {
       if (Preorder)
         return false;
-      
+
       return static_cast<RedeclChainVisitor *>(UserData)->visit(M);
     }
-    
+
     void addToChain(Decl *D) {
       if (!D)
         return;
-      
+
       if (Deserialized.erase(D))
         Chain.push_back(D);
     }
-    
+
     void searchForID(ModuleFile &M, GlobalDeclID GlobalID) {
       // Map global ID of the first declaration down to the local ID
       // used in this module file.
       DeclID ID = Reader.mapGlobalIDToModuleFileGlobalID(M, GlobalID);
       if (!ID)
         return;
-      
+
+      // If the search decl was from this module, add it to the chain before any
+      // of its redeclarations in this module or users of it, and after any from
+      // imported modules.
+      if (CanonID != GlobalID && Reader.isDeclIDFromModule(GlobalID, M))
+        addToChain(Reader.GetDecl(GlobalID));
+
       // Perform a binary search to find the local redeclarations for this
       // declaration (if any).
       const LocalRedeclarationsInfo Compare = { ID, 0 };

Added: cfe/trunk/test/Modules/Inputs/merge-decl-order/a.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/merge-decl-order/a.h?rev=228978&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/merge-decl-order/a.h (added)
+++ cfe/trunk/test/Modules/Inputs/merge-decl-order/a.h Thu Feb 12 17:21:45 2015
@@ -0,0 +1,2 @@
+namespace N { struct SA { friend struct foo; }; }
+namespace N { struct foo; }

Added: cfe/trunk/test/Modules/Inputs/merge-decl-order/b.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/merge-decl-order/b.h?rev=228978&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/merge-decl-order/b.h (added)
+++ cfe/trunk/test/Modules/Inputs/merge-decl-order/b.h Thu Feb 12 17:21:45 2015
@@ -0,0 +1,2 @@
+namespace N { struct SB { friend struct foo; }; }
+#include "a.h"

Added: cfe/trunk/test/Modules/Inputs/merge-decl-order/module.modulemap
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/merge-decl-order/module.modulemap?rev=228978&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/merge-decl-order/module.modulemap (added)
+++ cfe/trunk/test/Modules/Inputs/merge-decl-order/module.modulemap Thu Feb 12 17:21:45 2015
@@ -0,0 +1,2 @@
+module a { header "a.h" export * }
+module b { header "b.h" export * }

Modified: cfe/trunk/test/Modules/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-templates.cpp?rev=228978&r1=228977&r2=228978&view=diff
==============================================================================
--- cfe/trunk/test/Modules/cxx-templates.cpp (original)
+++ cfe/trunk/test/Modules/cxx-templates.cpp Thu Feb 12 17:21:45 2015
@@ -189,11 +189,11 @@ namespace Std {
 // CHECK-NAMESPACE-N-NEXT: `-FunctionTemplate {{.*}} 'f'
 
 // CHECK-DUMP:      ClassTemplateDecl {{.*}} <{{.*[/\\]}}cxx-templates-common.h:1:1, {{.*}}>  col:{{.*}} in cxx_templates_common SomeTemplate
-// CHECK-DUMP:        ClassTemplateSpecializationDecl {{.*}} prev [[CHAR2:[^ ]*]] {{.*}} SomeTemplate
+// CHECK-DUMP:        ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate
 // CHECK-DUMP-NEXT:     TemplateArgument type 'char [2]'
-// CHECK-DUMP:        ClassTemplateSpecializationDecl [[CHAR2]] {{.*}} SomeTemplate definition
+// CHECK-DUMP:        ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition
 // CHECK-DUMP-NEXT:     TemplateArgument type 'char [2]'
-// CHECK-DUMP:        ClassTemplateSpecializationDecl {{.*}} prev [[CHAR1:[^ ]*]] {{.*}} SomeTemplate
+// CHECK-DUMP:        ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate
 // CHECK-DUMP-NEXT:     TemplateArgument type 'char [1]'
-// CHECK-DUMP:        ClassTemplateSpecializationDecl [[CHAR1]] {{.*}} SomeTemplate definition
+// CHECK-DUMP:        ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition
 // CHECK-DUMP-NEXT:     TemplateArgument type 'char [1]'

Added: cfe/trunk/test/Modules/merge-decl-order.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/merge-decl-order.cpp?rev=228978&view=auto
==============================================================================
--- cfe/trunk/test/Modules/merge-decl-order.cpp (added)
+++ cfe/trunk/test/Modules/merge-decl-order.cpp Thu Feb 12 17:21:45 2015
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/merge-decl-order -verify %s
+// expected-no-diagnostics
+
+// Check that we include all decls from 'a' before the decls from 'b' in foo's
+// redecl chain. If we don't, then name lookup only finds invisible friend
+// declarations and the lookup below will fail.
+#include "b.h"
+N::foo *use;





More information about the cfe-commits mailing list