Add testcase for C++ chained PCH and fix the bugs it uncovered in name lookup.

llvm-svn: 111882
This commit is contained in:
Sebastian Redl 2010-08-24 00:50:16 +00:00
parent a4071b4fac
commit 9617e7e8c7
5 changed files with 65 additions and 15 deletions

View File

@ -3192,9 +3192,10 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
llvm::SmallVector<NamedDecl *, 64> Decls;
// There might be visible decls in multiple parts of the chain, for the TU
// and namespaces.
// and namespaces. For any given name, the last available results replace
// all earlier ones. For this reason, we walk in reverse.
DeclContextInfos &Infos = DeclContextOffsets[DC];
for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
for (DeclContextInfos::reverse_iterator I = Infos.rbegin(), E = Infos.rend();
I != E; ++I) {
if (!I->NameLookupTableData)
continue;
@ -3208,6 +3209,7 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
ASTDeclContextNameLookupTrait::data_type Data = *Pos;
for (; Data.first != Data.second; ++Data.first)
Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first)));
break;
}
++NumVisibleDeclContextsRead;

View File

@ -2101,23 +2101,13 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
ASTDeclContextNameLookupTrait Trait(*this);
// Create the hash table.
llvm::SmallVector<NamedDecl *, 16> Decls;
for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
D != DEnd; ++D) {
DeclarationName Name = D->first;
DeclContext::lookup_result Result = D->second.getLookupResult();
// Need to filter these results to only include decls that are not from
// an existing PCH.
Decls.clear();
for (; Result.first != Result.second; ++Result.first) {
if ((*Result.first)->getPCHLevel() == 0)
Decls.push_back(*Result.first);
}
if (!Decls.empty()) {
Result.first = Decls.data();
Result.second = Result.first + Decls.size();
Generator.insert(Name, Result, Trait);
}
// For any name that appears in this table, the results are complete, i.e.
// they overwrite results from previous PCHs. Merging is always a mess.
Generator.insert(Name, Result, Trait);
}
// Create the on-disk hash table in a buffer.

View File

@ -0,0 +1,15 @@
// Primary header for C++ chained PCH test
void f();
// Name not appearing in dependent
void pf();
namespace ns {
void g();
void pg();
}
template <typename T>
struct S {};

View File

@ -0,0 +1,20 @@
// Dependent header for C++ chained PCH test
// Overload function from primary
void f(int);
// Add function with different name
void f2();
// Reopen namespace
namespace ns {
// Overload function from primary
void g(int);
// Add different name
void g2();
}
// Specialize template from primary
template <>
struct S<int> { typedef int I; };

View File

@ -0,0 +1,23 @@
// Test C++ chained PCH functionality
// Without PCH
// RUN: %clang_cc1 -fsyntax-only -verify -include %S/Inputs/chain-cxx1.h -include %S/Inputs/chain-cxx2.h %s
// With PCH
// RUN: %clang_cc1 -x c++ -emit-pch -o %t1 %S/Inputs/chain-cxx1.h
// RUN: %clang_cc1 -x c++ -emit-pch -o %t2 %S/Inputs/chain-cxx2.h -include-pch %t1 -chained-pch
// RUN: %clang_cc1 -fsyntax-only -verify -include-pch %t2 %s
void test() {
f();
f(1);
pf();
f2();
ns::g();
ns::g(1);
ns::pg();
ns::g2();
//typedef S<int>::I J;
}