]> granicus.if.org Git - clang/commitdiff
Add testcase for C++ chained PCH and fix the bugs it uncovered in name lookup.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Tue, 24 Aug 2010 00:50:16 +0000 (00:50 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Tue, 24 Aug 2010 00:50:16 +0000 (00:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111882 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp
test/PCH/Inputs/chain-cxx1.h [new file with mode: 0644]
test/PCH/Inputs/chain-cxx2.h [new file with mode: 0644]
test/PCH/chain-cxx.cpp [new file with mode: 0644]

index 8167a0f5faff7b0673a84cb2a00087aa200de973..38b343ffe83d4713253c479453507f7b75f818d8 100644 (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;
index dc9f4d409af9b131f387d3984ac72db9716c7e81..43bb7ad4c7a5a6d52adbbb3902963d60840843bb 100644 (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.
diff --git a/test/PCH/Inputs/chain-cxx1.h b/test/PCH/Inputs/chain-cxx1.h
new file mode 100644 (file)
index 0000000..747bdbc
--- /dev/null
@@ -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 {};
diff --git a/test/PCH/Inputs/chain-cxx2.h b/test/PCH/Inputs/chain-cxx2.h
new file mode 100644 (file)
index 0000000..ff22e53
--- /dev/null
@@ -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; };
diff --git a/test/PCH/chain-cxx.cpp b/test/PCH/chain-cxx.cpp
new file mode 100644 (file)
index 0000000..450a791
--- /dev/null
@@ -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;
+}