aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Basic
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Basic')
-rw-r--r--include/clang/Basic/IdentifierTable.h38
-rw-r--r--include/clang/Basic/OnDiskHashTable.h29
2 files changed, 53 insertions, 14 deletions
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index d4f680494e..3156bbc4e9 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -229,7 +229,7 @@ private:
};
/// IdentifierInfoLookup - An abstract class used by IdentifierTable that
-/// provides an interface for for performing lookups from strings
+/// provides an interface for performing lookups from strings
/// (const char *) to IdentiferInfo objects.
class IdentifierInfoLookup {
public:
@@ -260,6 +260,11 @@ public:
IdentifierTable(const LangOptions &LangOpts,
IdentifierInfoLookup* externalLookup = 0);
+ /// \brief Set the external identifier lookup mechanism.
+ void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
+ ExternalLookup = IILookup;
+ }
+
llvm::BumpPtrAllocator& getAllocator() {
return HashTable.getAllocator();
}
@@ -295,6 +300,34 @@ public:
return *II;
}
+ /// \brief Creates a new IdentifierInfo from the given string.
+ ///
+ /// This is a lower-level version of get() that requires that this
+ /// identifier not be known previously and that does not consult an
+ /// external source for identifiers. In particular, external
+ /// identifier sources can use this routine to build IdentifierInfo
+ /// nodes and then introduce additional information about those
+ /// identifiers.
+ IdentifierInfo &CreateIdentifierInfo(const char *NameStart,
+ const char *NameEnd) {
+ llvm::StringMapEntry<IdentifierInfo*> &Entry =
+ HashTable.GetOrCreateValue(NameStart, NameEnd);
+
+ IdentifierInfo *II = Entry.getValue();
+ assert(!II && "IdentifierInfo already exists");
+
+ // Lookups failed, make a new IdentifierInfo.
+ void *Mem = getAllocator().Allocate<IdentifierInfo>();
+ II = new (Mem) IdentifierInfo();
+ Entry.setValue(II);
+
+ // Make sure getName() knows how to find the IdentifierInfo
+ // contents.
+ II->Entry = &Entry;
+
+ return *II;
+ }
+
IdentifierInfo &get(const char *Name) {
return get(Name, Name+strlen(Name));
}
@@ -304,14 +337,11 @@ public:
return get(NameBytes, NameBytes+Name.size());
}
-private:
typedef HashTableTy::const_iterator iterator;
typedef HashTableTy::const_iterator const_iterator;
iterator begin() const { return HashTable.begin(); }
iterator end() const { return HashTable.end(); }
-public:
-
unsigned size() const { return HashTable.size(); }
/// PrintStats - Print some statistics to stderr that indicate how well the
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
index 631d497f1a..3caeb9ffd8 100644
--- a/include/clang/Basic/OnDiskHashTable.h
+++ b/include/clang/Basic/OnDiskHashTable.h
@@ -242,6 +242,8 @@ class OnDiskChainedHashTable {
const unsigned NumEntries;
const unsigned char* const Buckets;
const unsigned char* const Base;
+ Info InfoObj;
+
public:
typedef typename Info::internal_key_type internal_key_type;
typedef typename Info::external_key_type external_key_type;
@@ -249,9 +251,10 @@ public:
OnDiskChainedHashTable(unsigned numBuckets, unsigned numEntries,
const unsigned char* buckets,
- const unsigned char* base)
+ const unsigned char* base,
+ const Info &InfoObj = Info())
: NumBuckets(numBuckets), NumEntries(numEntries),
- Buckets(buckets), Base(base) {
+ Buckets(buckets), Base(base), InfoObj(InfoObj) {
assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
"'buckets' must have a 4-byte alignment");
}
@@ -267,22 +270,27 @@ public:
internal_key_type key;
const unsigned char* const data;
const unsigned len;
+ Info *InfoObj;
public:
iterator() : data(0), len(0) {}
- iterator(const internal_key_type k, const unsigned char* d, unsigned l)
- : key(k), data(d), len(l) {}
+ iterator(const internal_key_type k, const unsigned char* d, unsigned l,
+ Info *InfoObj)
+ : key(k), data(d), len(l), InfoObj(InfoObj) {}
- data_type operator*() const { return Info::ReadData(key, data, len); }
+ data_type operator*() const { return InfoObj->ReadData(key, data, len); }
bool operator==(const iterator& X) const { return X.data == data; }
bool operator!=(const iterator& X) const { return X.data != data; }
};
- iterator find(const external_key_type& eKey) {
+ iterator find(const external_key_type& eKey, Info *InfoPtr = 0) {
+ if (!InfoPtr)
+ InfoPtr = &InfoObj;
+
using namespace io;
const internal_key_type& iKey = Info::GetInternalKey(eKey);
unsigned key_hash = Info::ComputeHash(iKey);
- // Each bucket is just a 32-bit offset into the PTH file.
+ // Each bucket is just a 32-bit offset into the hash table file.
unsigned idx = key_hash & (NumBuckets - 1);
const unsigned char* Bucket = Buckets + sizeof(uint32_t)*idx;
@@ -319,7 +327,7 @@ public:
}
// The key matches!
- return iterator(X, Items + L.first, L.second);
+ return iterator(X, Items + L.first, L.second, InfoPtr);
}
return iterator();
@@ -329,7 +337,8 @@ public:
static OnDiskChainedHashTable* Create(const unsigned char* buckets,
- const unsigned char* const base) {
+ const unsigned char* const base,
+ const Info &InfoObj = Info()) {
using namespace io;
assert(buckets > base);
assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
@@ -338,7 +347,7 @@ public:
unsigned numBuckets = ReadLE32(buckets);
unsigned numEntries = ReadLE32(buckets);
return new OnDiskChainedHashTable<Info>(numBuckets, numEntries, buckets,
- base);
+ base, InfoObj);
}
};