From: Sebastian Redl Date: Tue, 24 Aug 2010 00:50:16 +0000 (+0000) Subject: Add testcase for C++ chained PCH and fix the bugs it uncovered in name lookup. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5967d6228f183a5fa384f2f1918df679ed2d8666;p=clang Add testcase for C++ chained PCH and fix the bugs it uncovered in name lookup. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111882 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 8167a0f5fa..38b343ffe8 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -3192,9 +3192,10 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, llvm::SmallVector 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(GetDecl(*Data.first))); + break; } ++NumVisibleDeclContextsRead; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index dc9f4d409a..43bb7ad4c7 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2101,23 +2101,13 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { ASTDeclContextNameLookupTrait Trait(*this); // Create the hash table. - llvm::SmallVector 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. diff --git a/test/PCH/Inputs/chain-cxx1.h b/test/PCH/Inputs/chain-cxx1.h new file mode 100644 index 0000000000..747bdbc7f4 --- /dev/null +++ b/test/PCH/Inputs/chain-cxx1.h @@ -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 +struct S {}; diff --git a/test/PCH/Inputs/chain-cxx2.h b/test/PCH/Inputs/chain-cxx2.h new file mode 100644 index 0000000000..ff22e538d4 --- /dev/null +++ b/test/PCH/Inputs/chain-cxx2.h @@ -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 { typedef int I; }; diff --git a/test/PCH/chain-cxx.cpp b/test/PCH/chain-cxx.cpp new file mode 100644 index 0000000000..450a791828 --- /dev/null +++ b/test/PCH/chain-cxx.cpp @@ -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::I J; +}