[cfe-commits] r111635 - in /cfe/trunk: include/clang/Basic/OnDiskHashTable.h include/clang/Serialization/ASTBitCodes.h include/clang/Serialization/ASTReader.h include/clang/Serialization/ASTWriter.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Aug 20 09:04:27 PDT 2010


Author: akirtzidis
Date: Fri Aug 20 11:04:27 2010
New Revision: 111635

URL: http://llvm.org/viewvc/llvm-project?rev=111635&view=rev
Log:
Introduce the mechanism for building an AST on-disk hash table for name lookup inside a DeclContext but don't use it yet.

Modified:
    cfe/trunk/include/clang/Basic/OnDiskHashTable.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/Basic/OnDiskHashTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OnDiskHashTable.h?rev=111635&r1=111634&r2=111635&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OnDiskHashTable.h (original)
+++ cfe/trunk/include/clang/Basic/OnDiskHashTable.h Fri Aug 20 11:04:27 2010
@@ -124,8 +124,9 @@
     Item *next;
     const uint32_t hash;
 
-    Item(typename Info::key_type_ref k, typename Info::data_type_ref d)
-    : key(k), data(d), next(0), hash(Info::ComputeHash(k)) {}
+    Item(typename Info::key_type_ref k, typename Info::data_type_ref d,
+         Info &InfoObj)
+    : key(k), data(d), next(0), hash(InfoObj.ComputeHash(k)) {}
   };
 
   class Bucket {
@@ -168,10 +169,17 @@
 
   void insert(typename Info::key_type_ref key,
               typename Info::data_type_ref data) {
+    Info InfoObj;
+    insert(key, data, InfoObj);
+  }
+
+  void insert(typename Info::key_type_ref key,
+              typename Info::data_type_ref data, Info &InfoObj) {
 
     ++NumEntries;
     if (4*NumEntries >= 3*NumBuckets) resize(NumBuckets*2);
-    insert(Buckets, NumBuckets, new (BA.Allocate<Item>()) Item(key, data));
+    insert(Buckets, NumBuckets, new (BA.Allocate<Item>()) Item(key, data,
+                                                               InfoObj));
   }
 
   io::Offset Emit(llvm::raw_ostream &out) {
@@ -278,8 +286,8 @@
       InfoPtr = &InfoObj;
 
     using namespace io;
-    const internal_key_type& iKey = Info::GetInternalKey(eKey);
-    unsigned key_hash = Info::ComputeHash(iKey);
+    const internal_key_type& iKey = InfoObj.GetInternalKey(eKey);
+    unsigned key_hash = InfoObj.ComputeHash(iKey);
 
     // Each bucket is just a 32-bit offset into the hash table file.
     unsigned idx = key_hash & (NumBuckets - 1);

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=111635&r1=111634&r2=111635&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Aug 20 11:04:27 2010
@@ -20,6 +20,7 @@
 #include "clang/AST/Type.h"
 #include "llvm/Bitcode/BitCodes.h"
 #include "llvm/System/DataTypes.h"
+#include "llvm/ADT/DenseMap.h"
 
 namespace clang {
   namespace serialization {
@@ -81,6 +82,36 @@
       }
     };
 
+    /// A structure for putting "fast"-unqualified QualTypes into a
+    /// DenseMap.  This uses the standard pointer hash function.
+    struct UnsafeQualTypeDenseMapInfo {
+      static inline bool isEqual(QualType A, QualType B) { return A == B; }
+      static inline QualType getEmptyKey() {
+        return QualType::getFromOpaquePtr((void*) 1);
+      }
+      static inline QualType getTombstoneKey() {
+        return QualType::getFromOpaquePtr((void*) 2);
+      }
+      static inline unsigned getHashValue(QualType T) {
+        assert(!T.getLocalFastQualifiers() && 
+               "hash invalid for types with fast quals");
+        uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+        return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
+      }
+    };
+
+    /// \brief Map that provides the ID numbers of each type within the
+    /// output stream, plus those deserialized from a chained PCH.
+    ///
+    /// The ID numbers of types are consecutive (in order of discovery)
+    /// and start at 1. 0 is reserved for NULL. When types are actually
+    /// stored in the stream, the ID number is shifted by 2 bits to
+    /// allow for the const/volatile qualifiers.
+    ///
+    /// Keys in the map never have const/volatile qualifiers.
+    typedef llvm::DenseMap<QualType, TypeIdx, UnsafeQualTypeDenseMapInfo>
+        TypeIdxMap;
+
     /// \brief An ID number that refers to an identifier in an AST
     /// file.
     typedef uint32_t IdentID;

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=111635&r1=111634&r2=111635&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Aug 20 11:04:27 2010
@@ -27,7 +27,6 @@
 #include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
@@ -315,6 +314,17 @@
   /// ID = (I + 1) << FastQual::Width has already been loaded
   std::vector<QualType> TypesLoaded;
 
+  /// \brief Map that provides the ID numbers of each type within the
+  /// output stream, plus those deserialized from a chained PCH.
+  ///
+  /// The ID numbers of types are consecutive (in order of discovery)
+  /// and start at 1. 0 is reserved for NULL. When types are actually
+  /// stored in the stream, the ID number is shifted by 2 bits to
+  /// allow for the const/volatile qualifiers.
+  ///
+  /// Keys in the map never have const/volatile qualifiers.
+  serialization::TypeIdxMap TypeIdxs;
+
   /// \brief Declarations that have already been loaded from the chain.
   ///
   /// When the pointer at index I is non-NULL, the declaration with ID
@@ -720,6 +730,16 @@
   /// type.
   QualType GetType(serialization::TypeID ID);
 
+  /// \brief Returns the type ID associated with the given type.
+  /// If the type didn't come from the AST file the ID that is returned is
+  /// marked as "doesn't exist in AST".
+  serialization::TypeID GetTypeID(QualType T) const;
+
+  /// \brief Returns the type index associated with the given type.
+  /// If the type didn't come from the AST file the index that is returned is
+  /// marked as "doesn't exist in AST".
+  serialization::TypeIdx GetTypeIdx(QualType T) const;
+
   /// \brief Resolve a declaration ID into a declaration, potentially
   /// building a new declaration.
   Decl *GetDecl(serialization::DeclID ID);

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=111635&r1=111634&r2=111635&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Fri Aug 20 11:04:27 2010
@@ -20,7 +20,6 @@
 #include "clang/Serialization/ASTBitCodes.h"
 #include "clang/Serialization/ASTDeserializationListener.h"
 #include "clang/Sema/SemaConsumer.h"
-#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
@@ -50,24 +49,6 @@
 class SwitchCase;
 class TargetInfo;
 
-/// A structure for putting "fast"-unqualified QualTypes into a
-/// DenseMap.  This uses the standard pointer hash function.
-struct UnsafeQualTypeDenseMapInfo {
-  static inline bool isEqual(QualType A, QualType B) { return A == B; }
-  static inline QualType getEmptyKey() {
-    return QualType::getFromOpaquePtr((void*) 1);
-  }
-  static inline QualType getTombstoneKey() {
-    return QualType::getFromOpaquePtr((void*) 2);
-  }
-  static inline unsigned getHashValue(QualType T) {
-    assert(!T.getLocalFastQualifiers() && 
-           "hash invalid for types with fast quals");
-    uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
-    return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
-  }
-};
-
 /// \brief Writes an AST file containing the contents of a translation unit.
 ///
 /// The ASTWriter class produces a bitstream containing the serialized
@@ -146,8 +127,7 @@
   /// allow for the const/volatile qualifiers.
   ///
   /// Keys in the map never have const/volatile qualifiers.
-  llvm::DenseMap<QualType, serialization::TypeIdx, UnsafeQualTypeDenseMapInfo>
-      TypeIdxs;
+  serialization::TypeIdxMap TypeIdxs;
 
   /// \brief Offset of each type in the bitstream, indexed by
   /// the type's ID.
@@ -368,13 +348,13 @@
   serialization::TypeID GetOrCreateTypeID(QualType T);
 
   /// \brief Determine the type ID of an already-emitted type.
-  serialization::TypeID getTypeID(QualType T);
+  serialization::TypeID getTypeID(QualType T) const;
 
   /// \brief Force a type to be emitted and get its index.
   serialization::TypeIdx GetOrCreateTypeIdx(QualType T);
 
   /// \brief Determine the type index of an already-emitted type.
-  serialization::TypeIdx getTypeIdx(QualType T);
+  serialization::TypeIdx getTypeIdx(QualType T) const;
 
   /// \brief Emits a reference to a declarator info.
   void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record);

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=111635&r1=111634&r2=111635&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Aug 20 11:04:27 2010
@@ -704,6 +704,148 @@
 typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
   ASTIdentifierLookupTable;
 
+namespace {
+class ASTDeclContextNameLookupTrait {
+  ASTReader &Reader;
+
+public:
+  /// \brief Pair of begin/end iterators for DeclIDs.
+  typedef std::pair<DeclID *, DeclID *> data_type;
+
+  /// \brief Special internal key for declaration names.
+  /// The hash table creates keys for comparison; we do not create
+  /// a DeclarationName for the internal key to avoid deserializing types.
+  struct DeclNameKey {
+    DeclarationName::NameKind Kind;
+    uint64_t Data;
+    DeclNameKey() : Kind((DeclarationName::NameKind)0), Data(0) { }
+  };
+
+  typedef DeclarationName external_key_type;
+  typedef DeclNameKey internal_key_type;
+
+  explicit ASTDeclContextNameLookupTrait(ASTReader &Reader) : Reader(Reader) { }
+
+  static bool EqualKey(const internal_key_type& a,
+                       const internal_key_type& b) {
+    return a.Kind == b.Kind && a.Data == b.Data;
+  }
+
+  unsigned ComputeHash(const DeclNameKey &Key) const {
+    llvm::FoldingSetNodeID ID;
+    ID.AddInteger(Key.Kind);
+
+    switch (Key.Kind) {
+    case DeclarationName::Identifier:
+    case DeclarationName::CXXLiteralOperatorName:
+      ID.AddString(((IdentifierInfo*)Key.Data)->getName());
+      break;
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      ID.AddInteger(serialization::ComputeHash(Selector(Key.Data)));
+      break;
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+      ID.AddInteger((TypeID)Key.Data);
+      break;
+    case DeclarationName::CXXOperatorName:
+      ID.AddInteger((OverloadedOperatorKind)Key.Data);
+      break;
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+
+    return ID.ComputeHash();
+  }
+
+  internal_key_type GetInternalKey(const external_key_type& Name) const {
+    DeclNameKey Key;
+    Key.Kind = Name.getNameKind();
+    switch (Name.getNameKind()) {
+    case DeclarationName::Identifier:
+      Key.Data = (uint64_t)Name.getAsIdentifierInfo();
+      break;
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      Key.Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
+      break;
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+      Key.Data = Reader.GetTypeID(Name.getCXXNameType());
+      break;
+    case DeclarationName::CXXOperatorName:
+      Key.Data = Name.getCXXOverloadedOperator();
+      break;
+    case DeclarationName::CXXLiteralOperatorName:
+      Key.Data = (uint64_t)Name.getCXXLiteralIdentifier();
+      break;
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+    
+    return Key;
+  }
+
+  static std::pair<unsigned, unsigned>
+  ReadKeyDataLength(const unsigned char*& d) {
+    using namespace clang::io;
+    unsigned KeyLen = ReadUnalignedLE16(d);
+    unsigned DataLen = ReadUnalignedLE16(d);
+    return std::make_pair(KeyLen, DataLen);
+  }
+
+  internal_key_type ReadKey(const unsigned char* d, unsigned) {
+    using namespace clang::io;
+
+    DeclNameKey Key;
+    Key.Kind = (DeclarationName::NameKind)*d++;
+    switch (Key.Kind) {
+    case DeclarationName::Identifier:
+      Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
+      break;
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      Key.Data = 
+         (uint64_t)Reader.DecodeSelector(ReadUnalignedLE32(d)).getAsOpaquePtr();
+      break;
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+      Key.Data = ReadUnalignedLE32(d); // TypeID
+      break;
+    case DeclarationName::CXXOperatorName:
+      Key.Data = *d++; // OverloadedOperatorKind
+      break;
+    case DeclarationName::CXXLiteralOperatorName:
+      Key.Data = (uint64_t)Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
+      break;
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+    
+    return Key;
+  }
+
+  data_type ReadData(internal_key_type, const unsigned char* d,
+                     unsigned DataLen) {
+    using namespace clang::io;
+    unsigned NumDecls = ReadUnalignedLE16(d);
+    DeclID *Start = (DeclID *)d;
+    return std::make_pair(Start, Start + NumDecls);
+  }
+};
+
+} // end anonymous namespace
+
+/// \brief The on-disk hash table used for the DeclContext's Name lookup table.
+typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
+  ASTDeclContextNameLookupTable;
+
 void ASTReader::Error(const char *Msg) {
   Diag(diag::err_fe_pch_malformed) << Msg;
 }
@@ -2825,6 +2967,7 @@
   if (TypesLoaded[Index].isNull()) {
     TypesLoaded[Index] = ReadTypeRecord(Index);
     TypesLoaded[Index]->setFromAST();
+    TypeIdxs[TypesLoaded[Index]] = TypeIdx::fromTypeID(ID);
     if (DeserializationListener)
       DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),
                                         TypesLoaded[Index]);
@@ -2833,6 +2976,27 @@
   return TypesLoaded[Index].withFastQualifiers(FastQuals);
 }
 
+TypeID ASTReader::GetTypeID(QualType T) const {
+  return MakeTypeID(T,
+              std::bind1st(std::mem_fun(&ASTReader::GetTypeIdx), this));
+}
+
+TypeIdx ASTReader::GetTypeIdx(QualType T) const {
+  if (T.isNull())
+    return TypeIdx();
+  assert(!T.getLocalFastQualifiers());
+
+  TypeIdxMap::const_iterator I = TypeIdxs.find(T);
+  // GetTypeIdx is mostly used for computing the hash of DeclarationNames and
+  // comparing keys of ASTDeclContextNameLookupTable.
+  // If the type didn't come from the AST file use a specially marked index
+  // so that any hash/key comparison fail since no such index is stored
+  // in a AST file.
+  if (I == TypeIdxs.end())
+    return TypeIdx(-1);
+  return I->second;
+}
+
 TemplateArgumentLocInfo
 ASTReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
                                       llvm::BitstreamCursor &DeclsCursor,

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=111635&r1=111634&r2=111635&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Aug 20 11:04:27 2010
@@ -1653,6 +1653,7 @@
   // Create and write out the blob that contains selectors and the method pool.
   {
     OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator;
+    ASTMethodPoolTrait Trait(*this);
 
     // Create the on-disk hash table representation. We walk through every
     // selector we've seen and look it up in the method pool.
@@ -1692,7 +1693,7 @@
         // A new method pool entry.
         ++NumTableEntries;
       }
-      Generator.insert(S, Data);
+      Generator.insert(S, Data, Trait);
     }
 
     // Create the on-disk hash table in a buffer.
@@ -1877,6 +1878,7 @@
   // strings.
   {
     OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator;
+    ASTIdentifierTableTrait Trait(*this, PP);
 
     // Look for any identifiers that were named while processing the
     // headers, but are otherwise not needed. We add these to the hash
@@ -1896,7 +1898,7 @@
          ID != IDEnd; ++ID) {
       assert(ID->first && "NULL identifier in identifier table");
       if (!Chain || !ID->first->isFromAST())
-        Generator.insert(ID->first, ID->second);
+        Generator.insert(ID->first, ID->second, Trait);
     }
 
     // Create the on-disk hash table in a buffer.
@@ -1940,6 +1942,127 @@
 }
 
 //===----------------------------------------------------------------------===//
+// DeclContext's Name Lookup Table Serialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+// Trait used for the on-disk hash table used in the method pool.
+class ASTDeclContextNameLookupTrait {
+  ASTWriter &Writer;
+
+public:
+  typedef DeclarationName key_type;
+  typedef key_type key_type_ref;
+
+  typedef DeclContext::lookup_result data_type;
+  typedef const data_type& data_type_ref;
+
+  explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { }
+
+  unsigned ComputeHash(DeclarationName Name) {
+    llvm::FoldingSetNodeID ID;
+    ID.AddInteger(Name.getNameKind());
+
+    switch (Name.getNameKind()) {
+    case DeclarationName::Identifier:
+      ID.AddString(Name.getAsIdentifierInfo()->getName());
+      break;
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      ID.AddInteger(serialization::ComputeHash(Name.getObjCSelector()));
+      break;
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+      ID.AddInteger(Writer.GetOrCreateTypeID(Name.getCXXNameType()));
+      break;
+    case DeclarationName::CXXOperatorName:
+      ID.AddInteger(Name.getCXXOverloadedOperator());
+      break;
+    case DeclarationName::CXXLiteralOperatorName:
+      ID.AddString(Name.getCXXLiteralIdentifier()->getName());
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+
+    return ID.ComputeHash();
+  }
+
+  std::pair<unsigned,unsigned>
+    EmitKeyDataLength(llvm::raw_ostream& Out, DeclarationName Name,
+                      data_type_ref Lookup) {
+    unsigned KeyLen = 1;
+    switch (Name.getNameKind()) {
+    case DeclarationName::Identifier:
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+    case DeclarationName::CXXLiteralOperatorName:
+      KeyLen += 4;
+      break;
+    case DeclarationName::CXXOperatorName:
+      KeyLen += 1;
+      break;
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+    clang::io::Emit16(Out, KeyLen);
+
+    // 2 bytes for num of decls and 4 for each DeclID.
+    unsigned DataLen = 2 + 4 * (Lookup.second - Lookup.first);
+    clang::io::Emit16(Out, DataLen);
+
+    return std::make_pair(KeyLen, DataLen);
+  }
+
+  void EmitKey(llvm::raw_ostream& Out, DeclarationName Name, unsigned) {
+    using namespace clang::io;
+
+    assert(Name.getNameKind() < 0x100 && "Invalid name kind ?");
+    Emit8(Out, Name.getNameKind());
+    switch (Name.getNameKind()) {
+    case DeclarationName::Identifier:
+      Emit32(Out, Writer.getIdentifierRef(Name.getAsIdentifierInfo()));
+      break;
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      Emit32(Out, Writer.getSelectorRef(Name.getObjCSelector()));
+      break;
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+      Emit32(Out, Writer.getTypeID(Name.getCXXNameType()));
+      break;
+    case DeclarationName::CXXOperatorName:
+      assert(Name.getCXXOverloadedOperator() < 0x100 && "Invalid operator ?");
+      Emit8(Out, Name.getCXXOverloadedOperator());
+      break;
+    case DeclarationName::CXXLiteralOperatorName:
+      Emit32(Out, Writer.getIdentifierRef(Name.getCXXLiteralIdentifier()));
+      break;
+    case DeclarationName::CXXUsingDirective:
+      break;
+    }
+  }
+
+  void EmitData(llvm::raw_ostream& Out, key_type_ref,
+                data_type Lookup, unsigned DataLen) {
+    uint64_t Start = Out.tell(); (void)Start;
+    clang::io::Emit16(Out, Lookup.second - Lookup.first);
+    for (; Lookup.first != Lookup.second; ++Lookup.first)
+      clang::io::Emit32(Out, Writer.GetDeclRef(*Lookup.first));
+
+    assert(Out.tell() - Start == DataLen && "Data length is wrong");
+  }
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
 // General Serialization Routines
 //===----------------------------------------------------------------------===//
 
@@ -2587,7 +2710,7 @@
               std::bind1st(std::mem_fun(&ASTWriter::GetOrCreateTypeIdx), this));
 }
 
-TypeID ASTWriter::getTypeID(QualType T) {
+TypeID ASTWriter::getTypeID(QualType T) const {
   return MakeTypeID(T,
               std::bind1st(std::mem_fun(&ASTWriter::getTypeIdx), this));
 }
@@ -2607,13 +2730,14 @@
   return Idx;
 }
 
-TypeIdx ASTWriter::getTypeIdx(QualType T) {
+TypeIdx ASTWriter::getTypeIdx(QualType T) const {
   if (T.isNull())
     return TypeIdx();
   assert(!T.getLocalFastQualifiers());
 
-  assert(TypeIdxs.find(T) != TypeIdxs.end() && "Type not emitted!");
-  return TypeIdxs[T];
+  TypeIdxMap::const_iterator I = TypeIdxs.find(T);
+  assert(I != TypeIdxs.end() && "Type not emitted!");
+  return I->second;
 }
 
 void ASTWriter::AddDeclRef(const Decl *D, RecordData &Record) {





More information about the cfe-commits mailing list