diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-08-02 16:26:37 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-08-02 16:26:37 +0000 |
commit | a119da0761cb6b85f53857eaee50f6ad8c5ea0a0 (patch) | |
tree | a173065d2d94f754efd844d593041b76b8bdffec /include/clang/Serialization | |
parent | 8df5c9b5d65beec807e4e77dae2813dd193f77dd (diff) |
Implement a proper local -> global type ID remapping scheme in the AST
reader. This scheme permits an AST file to be loaded with its type IDs
shifted anywhere in the type ID space.
At present, the type indices are still allocated in the same boring
way they always have been, just by adding up the number of types in
each PCH file within the chain. However, I've done testing with this
patch by randomly sliding the base indices at load time, to ensure
that remapping is occurring as expected. I may eventually formalize
this in some testing flag, but loading multiple (non-chained) AST
files at once will eventually exercise the same code.
There is one known problem with this patch, which involves name lookup
of operator names (e.g., "x.operator int*()") in cases where multiple
PCH files in the chain. The hash function itself depends on having a
stable type ID, which doesn't happen with chained PCH and *certainly*
doesn't happen when sliding type IDs around. We'll need another
approach. I'll tackle that next.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136693 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Serialization')
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 6 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 27 | ||||
-rw-r--r-- | include/clang/Serialization/ContinuousRangeMap.h | 9 |
3 files changed, 33 insertions, 9 deletions
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 97b4cfc028..21fb8fa4ed 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -84,9 +84,15 @@ namespace clang { uint32_t getIndex() const { return Idx; } TypeID asTypeID(unsigned FastQuals) const { + if (Idx == uint32_t(-1)) + return TypeID(-1); + return (Idx << Qualifiers::FastWidth) | FastQuals; } static TypeIdx fromTypeID(TypeID ID) { + if (ID == TypeID(-1)) + return TypeIdx(-1); + return TypeIdx(ID >> Qualifiers::FastWidth); } }; diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index e28179d335..e167985e30 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -380,9 +380,26 @@ public: /// type ID, or the representation of a Type*. const uint32_t *TypeOffsets; - /// \brief Base type ID for types local to this module. - serialization::TypeID BaseTypeID; - + /// \brief Base type ID for types local to this module as represented in + /// the global type ID space. + serialization::TypeID GlobalBaseTypeIndex; + + /// \brief Remapping table for type IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> TypeRemap; + + /// \brief Base type ID for types local to this module as represented in + /// the module's type ID space. + serialization::TypeID LocalBaseTypeIndex; + + /// \brief Remapping table that maps from a type as represented as a module + /// and local type index to the index used within the current module to + /// refer to that same type. + /// + /// This mapping is effectively the reverse of the normal \c TypeRemap, and + /// is used specifically by ASTReader::GetTypeIdx() to help map between + /// global type IDs and a module's view of the same type ID as a hash value. + llvm::DenseMap<Module *, int> ReverseTypeRemap; + // === Miscellaneous === /// \brief Diagnostic IDs and their mappings that the user changed. @@ -1233,6 +1250,10 @@ public: /// \brief Map a local type ID within a given AST file into a global type ID. serialization::TypeID getGlobalTypeID(Module &F, unsigned LocalID) const; + /// \brief Map a global type ID to an ID as it would be locally expressed + /// in the given model. + unsigned getLocalTypeID(Module &M, serialization::TypeID GlobalID); + /// \brief Read a type from the current position in the given record, which /// was read from the given AST file. QualType readType(Module &F, const RecordData &Record, unsigned &Idx) { diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h index 820086e820..42b8954b54 100644 --- a/include/clang/Serialization/ContinuousRangeMap.h +++ b/include/clang/Serialization/ContinuousRangeMap.h @@ -34,7 +34,7 @@ namespace clang { template <typename Int, typename V, unsigned InitialCapacity> class ContinuousRangeMap { public: - typedef std::pair<const Int, V> value_type; + typedef std::pair<Int, V> value_type; typedef value_type &reference; typedef const value_type &const_reference; typedef value_type *pointer; @@ -94,7 +94,6 @@ public: /// from a set of values. class Builder { ContinuousRangeMap &Self; - SmallVector<std::pair<Int, V>, InitialCapacity> Elements; Builder(const Builder&); // DO NOT IMPLEMENT Builder &operator=(const Builder&); // DO NOT IMPLEMENT @@ -103,13 +102,11 @@ public: explicit Builder(ContinuousRangeMap &Self) : Self(Self) { } ~Builder() { - std::sort(Elements.begin(), Elements.end(), Compare()); - for (unsigned I = 0, N = Elements.size(); I != N; ++I) - Self.insert(Elements[I]); + std::sort(Self.Rep.begin(), Self.Rep.end(), Compare()); } void insert(const value_type &Val) { - Elements.push_back(Val); + Self.Rep.push_back(Val); } }; friend class Builder; |