r184679 - When setting the external visible declarations for a decl context, check

Richard Smith richard-llvm at metafoo.co.uk
Sun Jun 23 18:46:42 PDT 2013


Author: rsmith
Date: Sun Jun 23 20:46:41 2013
New Revision: 184679

URL: http://llvm.org/viewvc/llvm-project?rev=184679&view=rev
Log:
When setting the external visible declarations for a decl context, check
whether they replace any existing lookups in the context, rather than
accumulating a bunch of lookup results referring to the same entity.

Modified:
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/test/PCH/cxx-namespaces.cpp
    cfe/trunk/test/PCH/cxx-namespaces.h

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=184679&r1=184678&r2=184679&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Sun Jun 23 20:46:41 2013
@@ -1012,13 +1012,38 @@ ExternalASTSource::SetExternalVisibleDec
     Map = DC->CreateStoredDeclsMap(Context);
 
   StoredDeclsList &List = (*Map)[Name];
-  for (ArrayRef<NamedDecl*>::iterator
-         I = Decls.begin(), E = Decls.end(); I != E; ++I) {
-    if (List.isNull())
-      List.setOnlyValue(*I);
-    else
-      // FIXME: Need declarationReplaces handling for redeclarations in modules.
-      List.AddSubsequentDecl(*I);
+
+  // Clear out any old external visible declarations, to avoid quadratic
+  // performance in the redeclaration checks below.
+  List.removeExternalDecls();
+
+  if (!List.isNull()) {
+    // We have both existing declarations and new declarations for this name.
+    // Some of the declarations may simply replace existing ones. Handle those
+    // first.
+    llvm::SmallVector<unsigned, 8> Skip;
+    for (unsigned I = 0, N = Decls.size(); I != N; ++I)
+      if (List.HandleRedeclaration(Decls[I]))
+        Skip.push_back(I);
+    Skip.push_back(Decls.size());
+
+    // Add in any new declarations.
+    unsigned SkipPos = 0;
+    for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
+      if (I == Skip[SkipPos])
+        ++SkipPos;
+      else
+        List.AddSubsequentDecl(Decls[I]);
+    }
+  } else {
+    // Convert the array to a StoredDeclsList.
+    for (ArrayRef<NamedDecl*>::iterator
+           I = Decls.begin(), E = Decls.end(); I != E; ++I) {
+      if (List.isNull())
+        List.setOnlyValue(*I);
+      else
+        List.AddSubsequentDecl(*I);
+    }
   }
 
   return List.getLookupResult();

Modified: cfe/trunk/test/PCH/cxx-namespaces.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-namespaces.cpp?rev=184679&r1=184678&r2=184679&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-namespaces.cpp (original)
+++ cfe/trunk/test/PCH/cxx-namespaces.cpp Sun Jun 23 20:46:41 2013
@@ -3,10 +3,23 @@
 
 // Test with pch.
 // RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-namespaces.h
-// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -ast-dump -ast-dump-lookups -ast-dump-filter N %s | FileCheck %s
+
+// Test with modules.
+// RUN: %clang_cc1 -fmodules -x c++-header -emit-pch -o %t %S/cxx-namespaces.h
+// RUN: %clang_cc1 -fmodules -include-pch %t -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fmodules -include-pch %t -fsyntax-only -ast-dump -ast-dump-lookups -ast-dump-filter N %s | FileCheck %s
 
 // expected-no-diagnostics
 
 void m() {
   N::x = 0;
+  N::f();
 }
+
+// namespace 'N' should contain only two declarations of 'f'.
+
+// CHECK:      DeclarationName 'f'
+// CHECK-NEXT: |-Function {{.*}} 'f' 'void (
+// CHECK-NEXT: `-Function {{.*}} 'f' 'void (

Modified: cfe/trunk/test/PCH/cxx-namespaces.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-namespaces.h?rev=184679&r1=184678&r2=184679&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-namespaces.h (original)
+++ cfe/trunk/test/PCH/cxx-namespaces.h Sun Jun 23 20:46:41 2013
@@ -4,4 +4,7 @@ namespace N {
     namespace {
         int x;
     }
+
+    void f();
+    void f(int);
 }





More information about the cfe-commits mailing list