Changes in directory llvm/include/llvm/ADT:
CStringMap.h updated: 1.3 -> 1.4 --- Log message: Allow cstringmap to contain strings with nul characters in them. --- Diffs of the changes: (+57 -28) CStringMap.h | 85 +++++++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 57 insertions(+), 28 deletions(-) Index: llvm/include/llvm/ADT/CStringMap.h diff -u llvm/include/llvm/ADT/CStringMap.h:1.3 llvm/include/llvm/ADT/CStringMap.h:1.4 --- llvm/include/llvm/ADT/CStringMap.h:1.3 Sun Oct 29 21:14:15 2006 +++ llvm/include/llvm/ADT/CStringMap.h Thu Feb 8 13:08:37 2007 @@ -19,14 +19,23 @@ namespace llvm { +/// StringMapEntryBase - Shared base class of StringMapEntry instances. +class StringMapEntryBase { + unsigned StrLen; +public: + StringMapEntryBase(unsigned Len) : StrLen(Len) {} + + unsigned getKeyLength() const { return StrLen; } +}; + /// CStringMapVisitor - Subclasses of this class may be implemented to walk all /// of the items in a CStringMap. class CStringMapVisitor { public: virtual ~CStringMapVisitor(); - virtual void Visit(const char *Key, void *Value) const = 0; + virtual void Visit(const char *Key, StringMapEntryBase *Value) const = 0; }; - + /// CStringMapImpl - This is the base class of CStringMap that is shared among /// all of its instantiations. class CStringMapImpl { @@ -39,7 +48,7 @@ unsigned FullHashValue; /// Item - This is a pointer to the actual item object. - void *Item; + StringMapEntryBase *Item; }; ItemBucket *TheTable; @@ -64,66 +73,86 @@ void VisitEntries(const CStringMapVisitor &Visitor) const; }; +/// StringMapEntry - This is used to represent one value that is inserted into +/// a StringMap. It contains the Value itself and the key: the string length +/// and data. +template<typename ValueTy> +class StringMapEntry : public StringMapEntryBase { + ValueTy Val; +public: + StringMapEntry(unsigned StrLen) + : StringMapEntryBase(StrLen), Val() {} + StringMapEntry(unsigned StrLen, const ValueTy &V) + : StringMapEntryBase(StrLen), Val(V) {} + + const ValueTy &getValue() const { return Val; } + ValueTy &getValue() { return Val; } + + void setValue(const ValueTy &V) { Val = V; } + + /// getKeyData - Return the start of the string data that is the key for this + /// value. The string data is always stored immediately after the + /// StringMapEntry object. + const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);} +}; + /// CStringMap - This is an unconventional map that is specialized for handling -/// keys that are "C strings", that is, null-terminated strings. This does some +/// keys that are "strings", which are basically ranges of bytes. This does some /// funky memory allocation and hashing things to make it extremely efficient, /// storing the string data *after* the value in the map. template<typename ValueTy, typename AllocatorTy = MallocAllocator> class CStringMap : public CStringMapImpl { AllocatorTy Allocator; + typedef StringMapEntry<ValueTy> MapEntryTy; public: CStringMap(unsigned InitialSize = 0) - : CStringMapImpl(InitialSize, sizeof(ValueTy)) {} + : CStringMapImpl(InitialSize, sizeof(MapEntryTy)) {} AllocatorTy &getAllocator() { return Allocator; } const AllocatorTy &getAllocator() const { return Allocator; } /// FindValue - Look up the specified key in the map. If it exists, return a /// pointer to the element, otherwise return null. - ValueTy *FindValue(const char *KeyStart, const char *KeyEnd) { + MapEntryTy *FindValue(const char *KeyStart, const char *KeyEnd) { unsigned BucketNo = LookupBucketFor(KeyStart, KeyEnd); - return static_cast<ValueTy*>(TheTable[BucketNo].Item); - } - - /// GetKeyForValueInMap - Given a value that is inserted into this map, return - /// the string that corresponds to it. This is an efficient operation that - /// is provided by CStringMap. The string is live as long as the value is in - /// the map. - static const char *GetKeyForValueInMap(const ValueTy &Val) { - return reinterpret_cast<const char*>(&Val+1); + return static_cast<MapEntryTy*>(TheTable[BucketNo].Item); } /// GetOrCreateValue - Look up the specified key in the table. If a value /// exists, return it. Otherwise, default construct a value, insert it, and /// return. - ValueTy &GetOrCreateValue(const char *KeyStart, const char *KeyEnd) { + StringMapEntry<ValueTy> &GetOrCreateValue(const char *KeyStart, + const char *KeyEnd) { unsigned BucketNo = LookupBucketFor(KeyStart, KeyEnd); ItemBucket &Bucket = TheTable[BucketNo]; if (Bucket.Item) - return *static_cast<ValueTy*>(Bucket.Item); + return *static_cast<MapEntryTy*>(Bucket.Item); unsigned KeyLength = KeyEnd-KeyStart; - // Okay, the item doesn't already exist, and Bucket is the bucket to fill - // in. Allocate a new item with space for the null-terminated string at the - // end. - unsigned AllocSize = sizeof(ValueTy)+KeyLength+1; + // Okay, the item doesn't already exist, and 'Bucket' is the bucket to fill + // in. Allocate a new item with space for the string at the end and a null + // terminator. + unsigned AllocSize = sizeof(MapEntryTy)+KeyLength+1; #ifdef __GNUC__ - unsigned Alignment = __alignof__(ValueTy); + unsigned Alignment = __alignof__(MapEntryTy); #else // FIXME: ugly. unsigned Alignment = 8; #endif - ValueTy *NewItem = (ValueTy*)Allocator.Allocate(AllocSize, Alignment); - new (NewItem) ValueTy(); + MapEntryTy *NewItem = + static_cast<MapEntryTy*>(Allocator.Allocate(AllocSize, Alignment)); + + // Default construct the value. + new (NewItem) MapEntryTy(KeyLength); ++NumItems; // Copy the string information. - char *StrBuffer = (char*)(NewItem+1); + char *StrBuffer = const_cast<char*>(NewItem->getKeyData()); memcpy(StrBuffer, KeyStart, KeyLength); - StrBuffer[KeyLength] = 0; // Null terminate string. + StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients. // Fill in the bucket for the hash table. The FullHashValue was already // filled in by LookupBucketFor. @@ -137,9 +166,9 @@ ~CStringMap() { for (ItemBucket *I = TheTable, *E = TheTable+NumBuckets; I != E; ++I) { - if (ValueTy *Id = static_cast<ValueTy*>(I->Item)) { + if (MapEntryTy *Id = static_cast<MapEntryTy*>(I->Item)) { // Free memory referenced by the item. - Id->~ValueTy(); + Id->~MapEntryTy(); Allocator.Deallocate(Id); } } _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits