[cfe-commits] r154784 - in /cfe/trunk: include/clang/AST/DeclLookups.h include/clang/AST/ExternalASTSource.h include/clang/Basic/OnDiskHashTable.h include/clang/Serialization/ASTReader.h lib/AST/ExternalASTSource.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderInternals.h test/CodeCompletion/preamble.c test/CodeCompletion/some_struct.h test/PCH/typo2.cpp

Nick Lewycky nicholas at mxc.ca
Sun Apr 15 19:51:46 PDT 2012


Author: nicholas
Date: Sun Apr 15 21:51:46 2012
New Revision: 154784

URL: http://llvm.org/viewvc/llvm-project?rev=154784&view=rev
Log:
Implement the all_lookups_iterator for PCH as a follow-up to r153970. This
includes a patch from Matthias Kleine with a regression testcase!

Adds a new iterator 'data_iterator' to OnDiskHashTable which doesn't try to
reconstruct the external_key from the internal_key, which is useful for traits
that don't store enough information to do that mapping in their key. Also
deletes the 'item_iterator' from OnDiskHashTable as dead code.

Added:
    cfe/trunk/test/CodeCompletion/preamble.c
    cfe/trunk/test/CodeCompletion/some_struct.h
    cfe/trunk/test/PCH/typo2.cpp
Modified:
    cfe/trunk/include/clang/AST/DeclLookups.h
    cfe/trunk/include/clang/AST/ExternalASTSource.h
    cfe/trunk/include/clang/Basic/OnDiskHashTable.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/AST/ExternalASTSource.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTReaderInternals.h

Modified: cfe/trunk/include/clang/AST/DeclLookups.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclLookups.h?rev=154784&r1=154783&r2=154784&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclLookups.h (original)
+++ cfe/trunk/include/clang/AST/DeclLookups.h Sun Apr 15 21:51:46 2012
@@ -67,6 +67,8 @@
 
 DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
   DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
+  if (hasExternalVisibleStorage())
+    getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
   if (StoredDeclsMap *Map = Primary->buildLookup())
     return all_lookups_iterator(Map->begin(), Map->end());
   return all_lookups_iterator();
@@ -74,6 +76,8 @@
 
 DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
   DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
+  if (hasExternalVisibleStorage())
+    getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
   if (StoredDeclsMap *Map = Primary->buildLookup())
     return all_lookups_iterator(Map->end(), Map->end());
   return all_lookups_iterator();

Modified: cfe/trunk/include/clang/AST/ExternalASTSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExternalASTSource.h?rev=154784&r1=154783&r2=154784&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExternalASTSource.h (original)
+++ cfe/trunk/include/clang/AST/ExternalASTSource.h Sun Apr 15 21:51:46 2012
@@ -126,6 +126,12 @@
   virtual DeclContextLookupResult
   FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
 
+  /// \brief Ensures that the table of all visible declarations inside this
+  /// context is up to date.
+  ///
+  /// The default implementation of this functino is a no-op.
+  virtual void completeVisibleDeclsMap(const DeclContext *DC);
+
   /// \brief Finds all declarations lexically contained within the given
   /// DeclContext, after applying an optional filter predicate.
   ///

Modified: cfe/trunk/include/clang/Basic/OnDiskHashTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OnDiskHashTable.h?rev=154784&r1=154783&r2=154784&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OnDiskHashTable.h (original)
+++ cfe/trunk/include/clang/Basic/OnDiskHashTable.h Sun Apr 15 21:51:46 2012
@@ -132,7 +132,7 @@
   class Bucket {
   public:
     io::Offset off;
-    Item*  head;
+    Item* head;
     unsigned length;
 
     Bucket() {}
@@ -201,6 +201,7 @@
 
       // Write out the number of items in the bucket.
       Emit16(out, B.length);
+      assert(B.length != 0  && "Bucket has a head but zero length?");
 
       // Write out the entries in the bucket.
       for (Item *I = B.head; I ; I = I->next) {
@@ -398,31 +399,30 @@
   }
   key_iterator key_end() { return key_iterator(); }
 
-  /// \brief Iterates over all the entries in the table, returning
-  /// a key/data pair.
-  class item_iterator {
+  /// \brief Iterates over all the entries in the table, returning the data.
+  class data_iterator {
     const unsigned char* Ptr;
     unsigned NumItemsInBucketLeft;
     unsigned NumEntriesLeft;
     Info *InfoObj;
   public:
-    typedef std::pair<external_key_type, data_type> value_type;
+    typedef data_type value_type;
 
-    item_iterator(const unsigned char* const Ptr, unsigned NumEntries,
+    data_iterator(const unsigned char* const Ptr, unsigned NumEntries,
                   Info *InfoObj)
       : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries),
         InfoObj(InfoObj) { }
-    item_iterator()
+    data_iterator()
       : Ptr(0), NumItemsInBucketLeft(0), NumEntriesLeft(0), InfoObj(0) { }
 
-    bool operator==(const item_iterator& X) const {
+    bool operator==(const data_iterator& X) const {
       return X.NumEntriesLeft == NumEntriesLeft;
     }
-    bool operator!=(const item_iterator& X) const {
+    bool operator!=(const data_iterator& X) const {
       return X.NumEntriesLeft != NumEntriesLeft;
     }
 
-    item_iterator& operator++() {  // Preincrement
+    data_iterator& operator++() {  // Preincrement
       if (!NumItemsInBucketLeft) {
         // 'Items' starts with a 16-bit unsigned integer representing the
         // number of items in this bucket.
@@ -438,8 +438,8 @@
       --NumEntriesLeft;
       return *this;
     }
-    item_iterator operator++(int) {  // Postincrement
-      item_iterator tmp = *this; ++*this; return tmp;
+    data_iterator operator++(int) {  // Postincrement
+      data_iterator tmp = *this; ++*this; return tmp;
     }
 
     value_type operator*() const {
@@ -454,15 +454,14 @@
       // Read the key.
       const internal_key_type& Key =
         InfoObj->ReadKey(LocalPtr, L.first);
-      return std::make_pair(InfoObj->GetExternalKey(Key),
-                          InfoObj->ReadData(Key, LocalPtr + L.first, L.second));
+      return InfoObj->ReadData(Key, LocalPtr + L.first, L.second);
     }
   };
 
-  item_iterator item_begin() {
-    return item_iterator(Base + 4, getNumEntries(), &InfoObj);
+  data_iterator data_begin() {
+    return data_iterator(Base + 4, getNumEntries(), &InfoObj);
   }
-  item_iterator item_end() { return item_iterator(); }
+  data_iterator data_end() { return data_iterator(); }
 
   Info &getInfoObj() { return InfoObj; }
 

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=154784&r1=154783&r2=154784&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Sun Apr 15 21:51:46 2012
@@ -1472,7 +1472,7 @@
                      llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos);
 
   /// \brief Load all external visible decls in the given DeclContext.
-  void completeVisibleDeclsMap(DeclContext *DC);
+  void completeVisibleDeclsMap(const DeclContext *DC);
 
   /// \brief Retrieve the AST context that this AST reader supplements.
   ASTContext &getContext() { return Context; }

Modified: cfe/trunk/lib/AST/ExternalASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExternalASTSource.cpp?rev=154784&r1=154783&r2=154784&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExternalASTSource.cpp (original)
+++ cfe/trunk/lib/AST/ExternalASTSource.cpp Sun Apr 15 21:51:46 2012
@@ -49,7 +49,10 @@
   return DeclContext::lookup_result();
 }
 
-ExternalLoadResult 
+void ExternalASTSource::completeVisibleDeclsMap(const DeclContext *DC) {
+}
+
+ExternalLoadResult
 ExternalASTSource::FindExternalLexicalDecls(const DeclContext *DC,
                                             bool (*isKindWeWant)(Decl::Kind),
                                          SmallVectorImpl<Decl*> &Result) {

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=154784&r1=154783&r2=154784&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Sun Apr 15 21:51:46 2012
@@ -27,7 +27,6 @@
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLocVisitor.h"
-#include "llvm/Support/SaveAndRestore.h"
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/PreprocessingRecord.h"
 #include "clang/Lex/Preprocessor.h"
@@ -46,6 +45,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/SaveAndRestore.h"
 #include "llvm/Support/system_error.h"
 #include <algorithm>
 #include <iterator>
@@ -664,46 +664,6 @@
   return Key;
 }
 
-ASTDeclContextNameLookupTrait::external_key_type 
-ASTDeclContextNameLookupTrait::GetExternalKey(
-                                          const internal_key_type& Key) const {
-  ASTContext &Context = Reader.getContext();
-  switch (Key.Kind) {
-  case DeclarationName::Identifier:
-    return DeclarationName((IdentifierInfo*)Key.Data);
-
-  case DeclarationName::ObjCZeroArgSelector:
-  case DeclarationName::ObjCOneArgSelector:
-  case DeclarationName::ObjCMultiArgSelector:
-    return DeclarationName(Selector(Key.Data));
-
-  case DeclarationName::CXXConstructorName:
-    return Context.DeclarationNames.getCXXConstructorName(
-             Context.getCanonicalType(Reader.getLocalType(F, Key.Data)));
-
-  case DeclarationName::CXXDestructorName:
-    return Context.DeclarationNames.getCXXDestructorName(
-             Context.getCanonicalType(Reader.getLocalType(F, Key.Data)));
-
-  case DeclarationName::CXXConversionFunctionName:
-    return Context.DeclarationNames.getCXXConversionFunctionName(
-             Context.getCanonicalType(Reader.getLocalType(F, Key.Data)));
-
-  case DeclarationName::CXXOperatorName:
-    return Context.DeclarationNames.getCXXOperatorName(
-                                       (OverloadedOperatorKind)Key.Data);
-
-  case DeclarationName::CXXLiteralOperatorName:
-    return Context.DeclarationNames.getCXXLiteralOperatorName(
-                                                   (IdentifierInfo*)Key.Data);
-
-  case DeclarationName::CXXUsingDirective:
-    return DeclarationName::getUsingDirectiveName();
-  }
-
-  llvm_unreachable("Invalid Name Kind ?");
-}
-
 std::pair<unsigned, unsigned>
 ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
   using namespace clang::io;
@@ -749,7 +709,7 @@
 ASTDeclContextNameLookupTrait::data_type 
 ASTDeclContextNameLookupTrait::ReadData(internal_key_type, 
                                         const unsigned char* d,
-                                      unsigned DataLen) {
+                                        unsigned DataLen) {
   using namespace clang::io;
   unsigned NumDecls = ReadUnalignedLE16(d);
   LE32DeclID *Start = (LE32DeclID *)d;
@@ -4973,48 +4933,95 @@
 }
 
 namespace {
-  /// \brief ModuleFile visitor used to complete the visible decls map of a
+  /// \brief ModuleFile visitor used to retrieve all visible names in a
   /// declaration context.
-  class DeclContextVisibleDeclMapVisitor {
+  class DeclContextAllNamesVisitor {
     ASTReader &Reader;
-    DeclContext *DC;
+    llvm::SmallVectorImpl<const DeclContext *> &Contexts;
+    const DeclContext *DC;
+    llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > &Decls;
 
   public:
-    DeclContextVisibleDeclMapVisitor(ASTReader &Reader, DeclContext *DC)
-      : Reader(Reader), DC(DC) { }
+    DeclContextAllNamesVisitor(ASTReader &Reader,
+                               SmallVectorImpl<const DeclContext *> &Contexts,
+                               llvm::DenseMap<DeclarationName,
+                                           SmallVector<NamedDecl *, 8> > &Decls)
+      : Reader(Reader), Contexts(Contexts), Decls(Decls) { }
 
     static bool visit(ModuleFile &M, void *UserData) {
-      return static_cast<DeclContextVisibleDeclMapVisitor*>(UserData)->visit(M);
-    }
+      DeclContextAllNamesVisitor *This
+        = static_cast<DeclContextAllNamesVisitor *>(UserData);
 
-    bool visit(ModuleFile &M) {
       // Check whether we have any visible declaration information for
       // this context in this module.
-      ModuleFile::DeclContextInfosMap::iterator
-        Info = M.DeclContextInfos.find(DC);
-      if (Info == M.DeclContextInfos.end() || 
-          !Info->second.NameLookupTableData)
+      ModuleFile::DeclContextInfosMap::iterator Info;
+      bool FoundInfo = false;
+      for (unsigned I = 0, N = This->Contexts.size(); I != N; ++I) {
+        Info = M.DeclContextInfos.find(This->Contexts[I]);
+        if (Info != M.DeclContextInfos.end() &&
+            Info->second.NameLookupTableData) {
+          FoundInfo = true;
+          break;
+        }
+      }
+
+      if (!FoundInfo)
         return false;
-      
-      // Look for this name within this module.
+
       ASTDeclContextNameLookupTable *LookupTable =
         Info->second.NameLookupTableData;
-      for (ASTDeclContextNameLookupTable::key_iterator
-             I = LookupTable->key_begin(),
-             E = LookupTable->key_end(); I != E; ++I) {
-        DC->lookup(*I); // Force loading of the visible decls for the decl name.
+      bool FoundAnything = false;
+      for (ASTDeclContextNameLookupTable::data_iterator
+	     I = LookupTable->data_begin(), E = LookupTable->data_end();
+	   I != E; ++I) {
+        ASTDeclContextNameLookupTrait::data_type Data = *I;
+        for (; Data.first != Data.second; ++Data.first) {
+          NamedDecl *ND = This->Reader.GetLocalDeclAs<NamedDecl>(M,
+                                                                 *Data.first);
+          if (!ND)
+            continue;
+
+          // Record this declaration.
+          FoundAnything = true;
+          This->Decls[ND->getDeclName()].push_back(ND);
+        }
       }
 
-      return false;
+      return FoundAnything;
     }
   };
 }
 
-void ASTReader::completeVisibleDeclsMap(DeclContext *DC) {
+void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
   if (!DC->hasExternalVisibleStorage())
     return;
-  DeclContextVisibleDeclMapVisitor Visitor(*this, DC);
-  ModuleMgr.visit(&DeclContextVisibleDeclMapVisitor::visit, &Visitor);
+  llvm::DenseMap<DeclarationName, llvm::SmallVector<NamedDecl*, 8> > Decls;
+
+  // Compute the declaration contexts we need to look into. Multiple such
+  // declaration contexts occur when two declaration contexts from disjoint
+  // modules get merged, e.g., when two namespaces with the same name are
+  // independently defined in separate modules.
+  SmallVector<const DeclContext *, 2> Contexts;
+  Contexts.push_back(DC);
+
+  if (DC->isNamespace()) {
+    MergedDeclsMap::iterator Merged
+      = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
+    if (Merged != MergedDecls.end()) {
+      for (unsigned I = 0, N = Merged->second.size(); I != N; ++I)
+        Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));
+    }
+  }
+
+  DeclContextAllNamesVisitor Visitor(*this, Contexts, Decls);
+  ModuleMgr.visit(&DeclContextAllNamesVisitor::visit, &Visitor);
+  ++NumVisibleDeclContextsRead;
+
+  for (llvm::DenseMap<DeclarationName,
+                      llvm::SmallVector<NamedDecl*, 8> >::iterator
+         I = Decls.begin(), E = Decls.end(); I != E; ++I) {
+    SetExternalVisibleDeclsForName(DC, I->first, I->second);
+  }
 }
 
 /// \brief Under non-PCH compilation the consumer receives the objc methods

Modified: cfe/trunk/lib/Serialization/ASTReaderInternals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderInternals.h?rev=154784&r1=154783&r2=154784&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderInternals.h (original)
+++ cfe/trunk/lib/Serialization/ASTReaderInternals.h Sun Apr 15 21:51:46 2012
@@ -57,8 +57,7 @@
   typedef DeclarationName external_key_type;
   typedef DeclNameKey internal_key_type;
 
-  explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, 
-                                         ModuleFile &F) 
+  explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F)
     : Reader(Reader), F(F) { }
 
   static bool EqualKey(const internal_key_type& a,
@@ -68,9 +67,8 @@
 
   unsigned ComputeHash(const DeclNameKey &Key) const;
   internal_key_type GetInternalKey(const external_key_type& Name) const;
-  external_key_type GetExternalKey(const internal_key_type& Key) const;
 
-  static std::pair<unsigned, unsigned> 
+  static std::pair<unsigned, unsigned>
   ReadKeyDataLength(const unsigned char*& d);
 
   internal_key_type ReadKey(const unsigned char* d, unsigned);

Added: cfe/trunk/test/CodeCompletion/preamble.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/preamble.c?rev=154784&view=auto
==============================================================================
--- cfe/trunk/test/CodeCompletion/preamble.c (added)
+++ cfe/trunk/test/CodeCompletion/preamble.c Sun Apr 15 21:51:46 2012
@@ -0,0 +1,7 @@
+#include "some_struct.h"
+void foo() {
+  struct X x;
+  x.
+
+// RUN: CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:4:5 -Xclang -code-completion-patterns  %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: FieldDecl:{ResultType int}{TypedText m} (35) (parent: StructDecl 'X')

Added: cfe/trunk/test/CodeCompletion/some_struct.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/some_struct.h?rev=154784&view=auto
==============================================================================
--- cfe/trunk/test/CodeCompletion/some_struct.h (added)
+++ cfe/trunk/test/CodeCompletion/some_struct.h Sun Apr 15 21:51:46 2012
@@ -0,0 +1 @@
+struct X { int m; };

Added: cfe/trunk/test/PCH/typo2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/typo2.cpp?rev=154784&view=auto
==============================================================================
--- cfe/trunk/test/PCH/typo2.cpp (added)
+++ cfe/trunk/test/PCH/typo2.cpp Sun Apr 15 21:51:46 2012
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -include-pch %t.pch %s -verify
+
+#ifndef HEADER_INCLUDED
+#define HEADER_INCLUDED
+
+void func(struct Test);  // expected-note{{'Test' declared here}}
+
+#else
+
+::Yest *T;  // expected-error{{did you mean 'Test'}}
+
+#endif





More information about the cfe-commits mailing list