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