aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex/PTHLexer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lex/PTHLexer.cpp')
-rw-r--r--lib/Lex/PTHLexer.cpp85
1 files changed, 74 insertions, 11 deletions
diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp
index 86c65771fd..a2d66fe075 100644
--- a/lib/Lex/PTHLexer.cpp
+++ b/lib/Lex/PTHLexer.cpp
@@ -506,9 +506,10 @@ public:
PTHManager::PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup,
const char* idDataTable, IdentifierInfo** perIDCache,
- Preprocessor& pp)
+ const char* sortedIdTable, unsigned numIds)
: Buf(buf), PerIDCache(perIDCache), FileLookup(fileLookup),
- IdDataTable(idDataTable), ITable(pp.getIdentifierTable()), PP(pp) {}
+ IdDataTable(idDataTable), SortedIdTable(sortedIdTable),
+ NumIds(numIds), PP(0) {}
PTHManager::~PTHManager() {
delete Buf;
@@ -516,7 +517,7 @@ PTHManager::~PTHManager() {
free(PerIDCache);
}
-PTHManager* PTHManager::Create(const std::string& file, Preprocessor& PP) {
+PTHManager* PTHManager::Create(const std::string& file) {
// Memory map the PTH file.
llvm::OwningPtr<llvm::MemoryBuffer>
@@ -563,6 +564,14 @@ PTHManager* PTHManager::Create(const std::string& file, Preprocessor& PP) {
return 0; // FIXME: Proper error diagnostic?
}
+ // Get the location of the lexigraphically-sorted table of persistent IDs.
+ const char* SortedIdTableOffset = EndTable + sizeof(uint32_t)*2;
+ const char* SortedIdTable = BufBeg + Read32(SortedIdTableOffset);
+ if (!(SortedIdTable > BufBeg && SortedIdTable < BufEnd)) {
+ assert(false && "Invalid PTH file.");
+ return 0; // FIXME: Proper error diagnostic?
+ }
+
// Get the number of IdentifierInfos and pre-allocate the identifier cache.
uint32_t NumIds = Read32(IData);
@@ -577,14 +586,15 @@ PTHManager* PTHManager::Create(const std::string& file, Preprocessor& PP) {
return 0;
}
- // Create the new lexer.
- return new PTHManager(File.take(), FL.take(), IData, PerIDCache, PP);
+ // Create the new PTHManager.
+ return new PTHManager(File.take(), FL.take(), IData, PerIDCache,
+ SortedIdTable, NumIds);
}
IdentifierInfo* PTHManager::GetIdentifierInfo(unsigned persistentID) {
// Check if the IdentifierInfo has already been resolved.
- IdentifierInfo*& II = PerIDCache[persistentID];
+ IdentifierInfo* II = PerIDCache[persistentID];
if (II) return II;
// Look in the PTH file for the string data for the IdentifierInfo object.
@@ -592,14 +602,66 @@ IdentifierInfo* PTHManager::GetIdentifierInfo(unsigned persistentID) {
const char* IDData = Buf->getBufferStart() + Read32(TableEntry);
assert(IDData < Buf->getBufferEnd());
- // Read the length of the string.
- uint32_t len = Read32(IDData);
+ // Allocate the object.
+ std::pair<IdentifierInfo,const char*> *Mem =
+ Alloc.Allocate<std::pair<IdentifierInfo,const char*> >();
+
+ Mem->second = IDData;
+ II = new ((void*) Mem) IdentifierInfo(true);
- // Get the IdentifierInfo* with the specified string.
- II = &ITable.get(IDData, IDData+len);
+ // Store the new IdentifierInfo in the cache.
+ PerIDCache[persistentID] = II;
return II;
}
+IdentifierInfo* PTHManager::get(const char *NameStart, const char *NameEnd) {
+ unsigned min = 0;
+ unsigned max = NumIds;
+ unsigned len = NameEnd - NameStart;
+
+ do {
+ unsigned i = (max - min) / 2 + min;
+ const char* p = SortedIdTable + (i * 4);
+
+ // Read the persistentID.
+ unsigned perID =
+ ((unsigned) ((uint8_t) p[0]))
+ | (((unsigned) ((uint8_t) p[1])) << 8)
+ | (((unsigned) ((uint8_t) p[2])) << 16)
+ | (((unsigned) ((uint8_t) p[3])) << 24);
+
+ // Get the IdentifierInfo.
+ IdentifierInfo* II = GetIdentifierInfo(perID);
+
+ // First compare the lengths.
+ unsigned IILen = II->getLength();
+ if (len < IILen) goto IsLess;
+ if (len > IILen) goto IsGreater;
+
+ // Now compare the strings!
+ {
+ signed comp = strncmp(NameStart, II->getName(), len);
+ if (comp < 0) goto IsLess;
+ if (comp > 0) goto IsGreater;
+ }
+ // We found a match!
+ return II;
+
+ IsGreater:
+ if (i == min) break;
+ min = i;
+ continue;
+
+ IsLess:
+ max = i;
+ assert(!(max == min) || (min == i));
+ }
+ while (1);
+
+ return 0;
+}
+
+
PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) {
if (!FE)
@@ -634,6 +696,7 @@ PTHLexer* PTHManager::CreateLexer(unsigned FileID, const FileEntry* FE) {
PTHSpellingSearch* ss = new PTHSpellingSearch(*this, len, spellingTable);
SpellingMap[FileID] = ss;
- return new PTHLexer(PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond,
+ assert(PP && "No preprocessor set yet!");
+ return new PTHLexer(*PP, SourceLocation::getFileLoc(FileID, 0), data, ppcond,
*ss, *this);
}