[cfe-commits] r109119 - in /cfe/trunk: include/clang/Frontend/PCHReader.h lib/Frontend/PCHReader.cpp lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriter.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Thu Jul 22 10:01:14 PDT 2010


Author: cornedbee
Date: Thu Jul 22 12:01:13 2010
New Revision: 109119

URL: http://llvm.org/viewvc/llvm-project?rev=109119&view=rev
Log:
Allow loading declcontext information from any file in the chain. Properly write source locations to dependent files. WIP

Modified:
    cfe/trunk/include/clang/Frontend/PCHReader.h
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp

Modified: cfe/trunk/include/clang/Frontend/PCHReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHReader.h?rev=109119&r1=109118&r2=109119&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHReader.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHReader.h Thu Jul 22 12:01:13 2010
@@ -300,7 +300,14 @@
   /// = I + 1 has already been loaded.
   std::vector<Decl *> DeclsLoaded;
 
-  typedef llvm::DenseMap<const DeclContext *, std::pair<uint64_t, uint64_t> >
+  /// \brief Information about the contents of a DeclContext.
+  struct DeclContextInfo {
+    llvm::BitstreamCursor *Stream;
+    uint64_t OffsetToLexicalDecls;
+    uint64_t OffsetToVisibleDecls;
+  };
+  typedef llvm::SmallVector<DeclContextInfo, 1> DeclContextInfos;
+  typedef llvm::DenseMap<const DeclContext *, DeclContextInfos>
     DeclContextOffsetsMap;
 
   /// \brief Offsets of the lexical and visible declarations for each
@@ -644,6 +651,11 @@
   /// \brief Read preprocessed entities into the 
   virtual void ReadPreprocessedEntities();
 
+  /// \brief Returns the number of source locations found in this file.
+  unsigned getTotalNumSLocs() const {
+    return TotalNumSLocEntries;
+  }
+
   /// \brief Returns the number of types found in this file.
   unsigned getTotalNumTypes() const {
     return static_cast<unsigned>(TypesLoaded.size());

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=109119&r1=109118&r2=109119&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Thu Jul 22 12:01:13 2010
@@ -1779,6 +1779,10 @@
     for (unsigned J = 0, M = Chain.size(); J != M; ++J) {
       PCHIdentifierLookupTable *IdTable
         = (PCHIdentifierLookupTable *)Chain[J]->IdentifierLookupTable;
+      // Not all PCH files necessarily have identifier tables, only the useful
+      // ones.
+      if (!IdTable)
+        continue;
       for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
         IdentifierInfo *II = Identifiers[I];
         // Look in the on-disk hash tables for an entry for this identifier
@@ -2856,10 +2860,18 @@
 /// source each time it is called, and is meant to be used via a
 /// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
 Stmt *PCHReader::GetExternalDeclStmt(uint64_t Offset) {
-  // Since we know tha this statement is part of a decl, make sure to use the
-  // decl cursor to read it.
-  Chain[0]->DeclsCursor.JumpToBit(Offset);
-  return ReadStmtFromStream(Chain[0]->DeclsCursor);
+  // Offset here is a global offset across the entire chain.
+  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+    PerFileData &F = *Chain[N - I - 1];
+    if (Offset < F.SizeInBits) {
+      // Since we know that this statement is part of a decl, make sure to use
+      // the decl cursor to read it.
+      F.DeclsCursor.JumpToBit(Offset);
+      return ReadStmtFromStream(F.DeclsCursor);
+    }
+    Offset -= F.SizeInBits;
+  }
+  llvm_unreachable("Broken chain");
 }
 
 bool PCHReader::FindExternalLexicalDecls(const DeclContext *DC,
@@ -2867,32 +2879,37 @@
   assert(DC->hasExternalLexicalStorage() &&
          "DeclContext has no lexical decls in storage");
 
-  uint64_t Offset = DeclContextOffsets[DC].first;
-  if (Offset == 0) {
-    Error("DeclContext has no lexical decls in storage");
-    return true;
-  }
-
-  llvm::BitstreamCursor &DeclsCursor = Chain[0]->DeclsCursor;
-
-  // Keep track of where we are in the stream, then jump back there
-  // after reading this context.
-  SavedStreamPosition SavedPosition(DeclsCursor);
+  // There might be lexical decls in multiple parts of the chain, for the TU
+  // at least.
+  DeclContextInfos &Infos = DeclContextOffsets[DC];
+  for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
+       I != E; ++I) {
+    uint64_t Offset = I->OffsetToLexicalDecls;
+    // Offset can be 0 if this file only contains visible decls.
+    if (Offset == 0)
+      continue;
+    llvm::BitstreamCursor &DeclsCursor = *I->Stream;
 
-  // Load the record containing all of the declarations lexically in
-  // this context.
-  DeclsCursor.JumpToBit(Offset);
-  RecordData Record;
-  unsigned Code = DeclsCursor.ReadCode();
-  unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
-  if (RecCode != pch::DECL_CONTEXT_LEXICAL) {
-    Error("Expected lexical block");
-    return true;
+    // Keep track of where we are in the stream, then jump back there
+    // after reading this context.
+    SavedStreamPosition SavedPosition(DeclsCursor);
+
+    // Load the record containing all of the declarations lexically in
+    // this context.
+    DeclsCursor.JumpToBit(Offset);
+    RecordData Record;
+    unsigned Code = DeclsCursor.ReadCode();
+    unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
+    if (RecCode != pch::DECL_CONTEXT_LEXICAL) {
+      Error("Expected lexical block");
+      return true;
+    }
+
+    // Load all of the declaration IDs
+    for (RecordData::iterator J = Record.begin(), F = Record.end(); J != F; ++J)
+      Decls.push_back(GetDecl(*J));
   }
 
-  // Load all of the declaration IDs
-  for (RecordData::iterator I = Record.begin(), E = Record.end(); I != E; ++I)
-    Decls.push_back(GetDecl(*I));
   ++NumLexicalDeclContextsRead;
   return false;
 }
@@ -2902,48 +2919,49 @@
                                           DeclarationName Name) {
   assert(DC->hasExternalVisibleStorage() &&
          "DeclContext has no visible decls in storage");
-  uint64_t Offset = DeclContextOffsets[DC].second;
-  if (Offset == 0) {
-    Error("DeclContext has no visible decls in storage");
-    return DeclContext::lookup_result(DeclContext::lookup_iterator(),
-                                      DeclContext::lookup_iterator());
-  }
 
-  llvm::BitstreamCursor &DeclsCursor = Chain[0]->DeclsCursor;
+  llvm::SmallVector<VisibleDeclaration, 64> Decls;
+  // There might be lexical decls in multiple parts of the chain, for the TU
+  // and namespaces.
+  DeclContextInfos &Infos = DeclContextOffsets[DC];
+  for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
+       I != E; ++I) {
+    uint64_t Offset = I->OffsetToVisibleDecls;
+    if (Offset == 0)
+      continue;
 
-  // Keep track of where we are in the stream, then jump back there
-  // after reading this context.
-  SavedStreamPosition SavedPosition(DeclsCursor);
+    llvm::BitstreamCursor &DeclsCursor = *I->Stream;
 
-  // Load the record containing all of the declarations visible in
-  // this context.
-  DeclsCursor.JumpToBit(Offset);
-  RecordData Record;
-  unsigned Code = DeclsCursor.ReadCode();
-  unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
-  if (RecCode != pch::DECL_CONTEXT_VISIBLE) {
-    Error("Expected visible block");
-    return DeclContext::lookup_result(DeclContext::lookup_iterator(),
-                                      DeclContext::lookup_iterator());
-  }
+    // Keep track of where we are in the stream, then jump back there
+    // after reading this context.
+    SavedStreamPosition SavedPosition(DeclsCursor);
+
+    // Load the record containing all of the declarations visible in
+    // this context.
+    DeclsCursor.JumpToBit(Offset);
+    RecordData Record;
+    unsigned Code = DeclsCursor.ReadCode();
+    unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
+    if (RecCode != pch::DECL_CONTEXT_VISIBLE) {
+      Error("Expected visible block");
+      return DeclContext::lookup_result(DeclContext::lookup_iterator(),
+                                        DeclContext::lookup_iterator());
+    }
 
-  llvm::SmallVector<VisibleDeclaration, 64> Decls;
-  if (Record.empty()) {
-    SetExternalVisibleDecls(DC, Decls);
-    return DeclContext::lookup_result(DeclContext::lookup_iterator(),
-                                      DeclContext::lookup_iterator());
-  }
+    if (Record.empty())
+      continue;
 
-  unsigned Idx = 0;
-  while (Idx < Record.size()) {
-    Decls.push_back(VisibleDeclaration());
-    Decls.back().Name = ReadDeclarationName(Record, Idx);
-
-    unsigned Size = Record[Idx++];
-    llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
-    LoadedDecls.reserve(Size);
-    for (unsigned I = 0; I < Size; ++I)
-      LoadedDecls.push_back(Record[Idx++]);
+    unsigned Idx = 0;
+    while (Idx < Record.size()) {
+      Decls.push_back(VisibleDeclaration());
+      Decls.back().Name = ReadDeclarationName(Record, Idx);
+
+      unsigned Size = Record[Idx++];
+      llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
+      LoadedDecls.reserve(Size);
+      for (unsigned J = 0; J < Size; ++J)
+        LoadedDecls.push_back(Record[Idx++]);
+    }
   }
 
   ++NumVisibleDeclContextsRead;
@@ -3112,6 +3130,8 @@
   for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
     PCHIdentifierLookupTable *IdTable
       = (PCHIdentifierLookupTable *)Chain[N - I - 1]->IdentifierLookupTable;
+    if (!IdTable)
+      continue;
     std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
     PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key);
     if (Pos == IdTable->end())

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=109119&r1=109118&r2=109119&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Thu Jul 22 12:01:13 2010
@@ -1497,7 +1497,12 @@
     if (Offsets.first || Offsets.second) {
       DC->setHasExternalLexicalStorage(Offsets.first != 0);
       DC->setHasExternalVisibleStorage(Offsets.second != 0);
-      DeclContextOffsets[DC] = Offsets;
+      PCHReader::DeclContextInfo Info = {
+        Loc.first,
+        Offsets.first,
+        Offsets.second
+      };
+      DeclContextOffsets[DC].push_back(Info);
     }
   }
   assert(Idx == Record.size());

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=109119&r1=109118&r2=109119&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Thu Jul 22 12:01:13 2010
@@ -1099,8 +1099,10 @@
   // entry, which is always the same dummy entry.
   std::vector<uint32_t> SLocEntryOffsets;
   RecordData PreloadSLocs;
-  SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1);
-  for (unsigned I = 1, N = SourceMgr.sloc_entry_size(); I != N; ++I) {
+  unsigned BaseSLocID = Chain ? Chain->getTotalNumSLocs() : 0;
+  SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1 - BaseSLocID);
+  for (unsigned I = BaseSLocID + 1, N = SourceMgr.sloc_entry_size();
+       I != N; ++I) {
     // Get this source location entry.
     const SrcMgr::SLocEntry *SLoc = &SourceMgr.getSLocEntry(I);
 
@@ -1157,7 +1159,7 @@
         // FIXME: For now, preload all file source locations, so that
         // we get the appropriate File entries in the reader. This is
         // a temporary measure.
-        PreloadSLocs.push_back(SLocEntryOffsets.size());
+        PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size());
       } else {
         // The source location entry is a buffer. The blob associated
         // with this entry contains the contents of the buffer.
@@ -1177,7 +1179,7 @@
                                                   Buffer->getBufferSize() + 1));
 
         if (strcmp(Name, "<built-in>") == 0)
-          PreloadSLocs.push_back(SLocEntryOffsets.size());
+          PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size());
       }
     } else {
       // The source location entry is an instantiation.





More information about the cfe-commits mailing list