[cfe-commits] r64477 - in /cfe/trunk: Driver/CacheTokens.cpp include/clang/Lex/PTHManager.h lib/Lex/PTHLexer.cpp
Ted Kremenek
kremenek at apple.com
Fri Feb 13 11:13:46 PST 2009
Author: kremenek
Date: Fri Feb 13 13:13:46 2009
New Revision: 64477
URL: http://llvm.org/viewvc/llvm-project?rev=64477&view=rev
Log:
Add some boilerplate to the PTH file to prepare for the caching of stats for directories (and negative stats too).
Modified:
cfe/trunk/Driver/CacheTokens.cpp
cfe/trunk/include/clang/Lex/PTHManager.h
cfe/trunk/lib/Lex/PTHLexer.cpp
Modified: cfe/trunk/Driver/CacheTokens.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/CacheTokens.cpp?rev=64477&r1=64476&r2=64477&view=diff
==============================================================================
--- cfe/trunk/Driver/CacheTokens.cpp (original)
+++ cfe/trunk/Driver/CacheTokens.cpp Fri Feb 13 13:13:46 2009
@@ -1,4 +1,4 @@
-//===--- CacheTokens.cpp - Caching of lexer tokens for PCH support --------===//
+//===--- CacheTokens.cpp - Caching of lexer tokens for PTH support --------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This provides a possible implementation of PCH support for Clang that is
+// This provides a possible implementation of PTH support for Clang that is
// based on caching lexed tokens and identifiers.
//
//===----------------------------------------------------------------------===//
@@ -192,54 +192,115 @@
//===----------------------------------------------------------------------===//
namespace {
-class VISIBILITY_HIDDEN PCHEntry {
+class VISIBILITY_HIDDEN PTHEntry {
Offset TokenData, PPCondData;
public:
- PCHEntry() {}
+ PTHEntry() {}
- PCHEntry(Offset td, Offset ppcd)
+ PTHEntry(Offset td, Offset ppcd)
: TokenData(td), PPCondData(ppcd) {}
Offset getTokenOffset() const { return TokenData; }
Offset getPPCondTableOffset() const { return PPCondData; }
};
-class VISIBILITY_HIDDEN FileEntryPCHEntryInfo {
+
+class VISIBILITY_HIDDEN PTHEntryKeyVariant {
+ union { const FileEntry* FE; const DirectoryEntry* DE; const char* Path; };
+ enum { IsFE = 0x1, IsDE = 0x2, IsNoExist = 0x0 } Kind;
+public:
+ PTHEntryKeyVariant(const FileEntry *fe) : FE(fe), Kind(IsFE) {}
+ PTHEntryKeyVariant(const DirectoryEntry *de) : DE(de), Kind(IsDE) {}
+ PTHEntryKeyVariant(const char* path) : Path(path), Kind(IsNoExist) {}
+
+ const FileEntry *getFile() const { return Kind == IsFE ? FE : 0; }
+ const DirectoryEntry *getDir() const { return Kind == IsDE ? DE : 0; }
+ const char* getNameOfNonExistantFile() const {
+ return Kind == IsNoExist ? Path : 0;
+ }
+
+ const char* getCString() const {
+ switch (Kind) {
+ case IsFE: return FE->getName();
+ case IsDE: return DE->getName();
+ default: return Path;
+ }
+ }
+
+ unsigned getKind() const { return (unsigned) Kind; }
+
+ void EmitData(llvm::raw_ostream& Out) {
+ switch (Kind) {
+ case IsFE:
+ // Emit stat information.
+ ::Emit32(Out, FE->getInode());
+ ::Emit32(Out, FE->getDevice());
+ ::Emit16(Out, FE->getFileMode());
+ ::Emit64(Out, FE->getModificationTime());
+ ::Emit64(Out, FE->getSize());
+ break;
+ case IsDE:
+ // FIXME
+ default: break;
+ // Emit nothing.
+ }
+ }
+
+ unsigned getRepresentationLength() const {
+ switch (Kind) {
+ case IsFE: return 4 + 4 + 2 + 8 + 8;
+ case IsDE: // FIXME
+ default: return 0;
+ }
+ }
+};
+
+class VISIBILITY_HIDDEN FileEntryPTHEntryInfo {
public:
- typedef const FileEntry* key_type;
+ typedef PTHEntryKeyVariant key_type;
typedef key_type key_type_ref;
- typedef PCHEntry data_type;
- typedef const PCHEntry& data_type_ref;
+ typedef PTHEntry data_type;
+ typedef const PTHEntry& data_type_ref;
- static unsigned ComputeHash(const FileEntry* FE) {
- return BernsteinHash(FE->getName());
+ static unsigned ComputeHash(PTHEntryKeyVariant V) {
+ return BernsteinHash(V.getCString());
}
static std::pair<unsigned,unsigned>
- EmitKeyDataLength(llvm::raw_ostream& Out, const FileEntry* FE,
- const PCHEntry& E) {
+ EmitKeyDataLength(llvm::raw_ostream& Out, PTHEntryKeyVariant V,
+ const PTHEntry& E) {
- unsigned n = strlen(FE->getName()) + 1;
+ unsigned n = strlen(V.getCString()) + 1 + 1;
::Emit16(Out, n);
- return std::make_pair(n,(4*2)+(4+4+2+8+8));
+
+ unsigned m = V.getRepresentationLength() + (V.getFile() ? 4 + 4 : 0);
+ ::Emit8(Out, m);
+
+ return std::make_pair(n, m);
}
- static void EmitKey(llvm::raw_ostream& Out, const FileEntry* FE, unsigned n) {
- Out.write(FE->getName(), n);
+ static void EmitKey(llvm::raw_ostream& Out, PTHEntryKeyVariant V, unsigned n){
+ // Emit the entry kind.
+ ::Emit8(Out, (unsigned) V.getKind());
+ // Emit the string.
+ Out.write(V.getCString(), n - 1);
}
- static void EmitData(llvm::raw_ostream& Out, const FileEntry* FE,
- const PCHEntry& E, unsigned) {
- ::Emit32(Out, E.getTokenOffset());
- ::Emit32(Out, E.getPPCondTableOffset());
- // Emit stat information.
- ::Emit32(Out, FE->getInode());
- ::Emit32(Out, FE->getDevice());
- ::Emit16(Out, FE->getFileMode());
- ::Emit64(Out, FE->getModificationTime());
- ::Emit64(Out, FE->getSize());
+ static void EmitData(llvm::raw_ostream& Out, PTHEntryKeyVariant V,
+ const PTHEntry& E, unsigned) {
+
+
+ // For file entries emit the offsets into the PTH file for token data
+ // and the preprocessor blocks table.
+ if (V.getFile()) {
+ ::Emit32(Out, E.getTokenOffset());
+ ::Emit32(Out, E.getPPCondTableOffset());
+ }
+
+ // Emit any other data associated with the key (i.e., stat information).
+ V.EmitData(Out);
}
};
@@ -254,7 +315,7 @@
};
} // end anonymous namespace
-typedef OnDiskChainedHashTableGenerator<FileEntryPCHEntryInfo> PCHMap;
+typedef OnDiskChainedHashTableGenerator<FileEntryPTHEntryInfo> PTHMap;
typedef llvm::DenseMap<const IdentifierInfo*,uint32_t> IDMap;
typedef llvm::StringMap<OffsetOpt, llvm::BumpPtrAllocator> CachedStrsTy;
@@ -264,7 +325,7 @@
llvm::raw_fd_ostream& Out;
Preprocessor& PP;
uint32_t idcount;
- PCHMap PM;
+ PTHMap PM;
CachedStrsTy CachedStrs;
Offset CurStrOffset;
std::vector<llvm::StringMapEntry<OffsetOpt>*> StrEntries;
@@ -304,7 +365,7 @@
/// token data.
Offset EmitFileTable() { return PM.Emit(Out); }
- PCHEntry LexTokens(Lexer& L);
+ PTHEntry LexTokens(Lexer& L);
Offset EmitCachedSpellings();
public:
@@ -360,7 +421,7 @@
Emit32(PP.getSourceManager().getFileOffset(T.getLocation()));
}
-PCHEntry PTHWriter::LexTokens(Lexer& L) {
+PTHEntry PTHWriter::LexTokens(Lexer& L) {
// Pad 0's so that we emit tokens to a 4-byte alignment.
// This speed up reading them back in.
Pad(Out, 4);
@@ -513,7 +574,7 @@
Emit32(x == i ? 0 : x);
}
- return PCHEntry(off, PPCondOff);
+ return PTHEntry(off, PPCondOff);
}
Offset PTHWriter::EmitCachedSpellings() {
@@ -604,39 +665,39 @@
//===----------------------------------------------------------------------===//
namespace {
-class VISIBILITY_HIDDEN PCHIdKey {
+class VISIBILITY_HIDDEN PTHIdKey {
public:
const IdentifierInfo* II;
uint32_t FileOffset;
};
-class VISIBILITY_HIDDEN PCHIdentifierTableTrait {
+class VISIBILITY_HIDDEN PTHIdentifierTableTrait {
public:
- typedef PCHIdKey* key_type;
+ typedef PTHIdKey* key_type;
typedef key_type key_type_ref;
typedef uint32_t data_type;
typedef data_type data_type_ref;
- static unsigned ComputeHash(PCHIdKey* key) {
+ static unsigned ComputeHash(PTHIdKey* key) {
return BernsteinHash(key->II->getName());
}
static std::pair<unsigned,unsigned>
- EmitKeyDataLength(llvm::raw_ostream& Out, const PCHIdKey* key, uint32_t) {
+ EmitKeyDataLength(llvm::raw_ostream& Out, const PTHIdKey* key, uint32_t) {
unsigned n = strlen(key->II->getName()) + 1;
::Emit16(Out, n);
return std::make_pair(n, sizeof(uint32_t));
}
- static void EmitKey(llvm::raw_fd_ostream& Out, PCHIdKey* key, unsigned n) {
+ static void EmitKey(llvm::raw_fd_ostream& Out, PTHIdKey* key, unsigned n) {
// Record the location of the key data. This is used when generating
// the mapping from persistent IDs to strings.
key->FileOffset = Out.tell();
Out.write(key->II->getName(), n);
}
- static void EmitData(llvm::raw_ostream& Out, PCHIdKey*, uint32_t pID,
+ static void EmitData(llvm::raw_ostream& Out, PTHIdKey*, uint32_t pID,
unsigned) {
::Emit32(Out, pID);
}
@@ -654,10 +715,10 @@
// (2) a map from (IdentifierInfo*, Offset)* -> persistent IDs
// Note that we use 'calloc', so all the bytes are 0.
- PCHIdKey* IIDMap = (PCHIdKey*) calloc(idcount, sizeof(PCHIdKey));
+ PTHIdKey* IIDMap = (PTHIdKey*) calloc(idcount, sizeof(PTHIdKey));
// Create the hashtable.
- OnDiskChainedHashTableGenerator<PCHIdentifierTableTrait> IIOffMap;
+ OnDiskChainedHashTableGenerator<PTHIdentifierTableTrait> IIOffMap;
// Generate mapping from persistent IDs -> IdentifierInfo*.
for (IDMap::iterator I=IM.begin(), E=IM.end(); I!=E; ++I) {
Modified: cfe/trunk/include/clang/Lex/PTHManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PTHManager.h?rev=64477&r1=64476&r2=64477&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/PTHManager.h (original)
+++ cfe/trunk/include/clang/Lex/PTHManager.h Fri Feb 13 13:13:46 2009
@@ -96,7 +96,7 @@
public:
// The current PTH version.
- enum { Version = 7 };
+ enum { Version = 8 };
~PTHManager();
Modified: cfe/trunk/lib/Lex/PTHLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PTHLexer.cpp?rev=64477&r1=64476&r2=64477&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PTHLexer.cpp (original)
+++ cfe/trunk/lib/Lex/PTHLexer.cpp Fri Feb 13 13:13:46 2009
@@ -375,13 +375,15 @@
bool isEmpty() const { return NumEntries == 0; }
class iterator {
+ internal_key_type key;
const unsigned char* const data;
const unsigned len;
public:
iterator() : data(0), len(0) {}
- iterator(const unsigned char* d, unsigned l) : data(d), len(l) {}
+ iterator(const internal_key_type k, const unsigned char* d, unsigned l)
+ : key(k), data(d), len(l) {}
- data_type operator*() const { return Info::ReadData(data, len); }
+ data_type operator*() const { return Info::ReadData(key, data, len); }
bool operator==(const iterator& X) const { return X.data == data; }
bool operator!=(const iterator& X) const { return X.data != data; }
};
@@ -427,7 +429,7 @@
}
// The key matches!
- return iterator(Items + L.first, L.second);
+ return iterator(X, Items + L.first, L.second);
}
return iterator();
@@ -472,23 +474,22 @@
class VISIBILITY_HIDDEN PTHFileLookupCommonTrait {
public:
- typedef const char* internal_key_type;
-
- static bool EqualKey(const char* a, const char* b) {
- return strcmp(a, b) == 0;
- }
-
- static unsigned ComputeHash(const char* x) {
- return BernsteinHash(x);
+ typedef std::pair<unsigned char, const char*> internal_key_type;
+
+ static unsigned ComputeHash(internal_key_type x) {
+ return BernsteinHash(x.second);
}
static std::pair<unsigned, unsigned>
ReadKeyDataLength(const unsigned char*& d) {
- return std::make_pair((unsigned) ReadUnalignedLE16(d), 8U + (4+4+2+8+8));
+ unsigned keyLen = (unsigned) ReadUnalignedLE16(d);
+ unsigned dataLen = (unsigned) *(d++);
+ return std::make_pair(keyLen, dataLen);
}
- static const char* ReadKey(const unsigned char* d, unsigned) {
- return (const char*) d;
+ static internal_key_type ReadKey(const unsigned char* d, unsigned) {
+ unsigned char k = *(d++); // Read the entry kind.
+ return std::make_pair(k, (const char*) d);
}
};
@@ -497,11 +498,17 @@
typedef const FileEntry* external_key_type;
typedef PTHFileData data_type;
- static const char* GetInternalKey(const FileEntry* FE) {
- return FE->getName();
+ static internal_key_type GetInternalKey(const FileEntry* FE) {
+ return std::make_pair((unsigned char) 0x1, FE->getName());
}
+
+ static bool EqualKey(internal_key_type a, internal_key_type b) {
+ return a.first == b.first && strcmp(a.second, b.second) == 0;
+ }
- static PTHFileData ReadData(const unsigned char* d, unsigned) {
+ static PTHFileData ReadData(const internal_key_type& k,
+ const unsigned char* d, unsigned) {
+ assert(k.first == 0x1 && "Only file lookups can match!");
uint32_t x = ::ReadUnalignedLE32(d);
uint32_t y = ::ReadUnalignedLE32(d);
return PTHFileData(x, y);
@@ -543,7 +550,8 @@
return std::make_pair((const char*) d, n-1);
}
- static uint32_t ReadData(const unsigned char* d, unsigned) {
+ static uint32_t ReadData(const internal_key_type& k, const unsigned char* d,
+ unsigned) {
return ::ReadUnalignedLE32(d);
}
};
@@ -768,6 +776,7 @@
namespace {
class VISIBILITY_HIDDEN PTHStatData {
public:
+ const bool hasStat;
const ino_t ino;
const dev_t dev;
const mode_t mode;
@@ -775,23 +784,40 @@
const off_t size;
PTHStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
- : ino(i), dev(d), mode(mo), mtime(m), size(s) {}
+ : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
+
+ PTHStatData()
+ : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
};
class VISIBILITY_HIDDEN PTHStatLookupTrait : public PTHFileLookupCommonTrait {
public:
- typedef internal_key_type external_key_type; // const char*
+ typedef const char* external_key_type; // const char*
typedef PTHStatData data_type;
- static const char* GetInternalKey(external_key_type x) { return x; }
+ static internal_key_type GetInternalKey(const char *path) {
+ // The key 'kind' doesn't matter here because it is ignored in EqualKey.
+ return std::make_pair((unsigned char) 0x0, path);
+ }
+
+ static bool EqualKey(internal_key_type a, internal_key_type b) {
+ // When doing 'stat' lookups we don't care about the kind of 'a' and 'b',
+ // just the paths.
+ return strcmp(a.second, b.second) == 0;
+ }
- static data_type ReadData(const unsigned char* d, unsigned) {
- d += 4 * 2; // Skip the first 2 words.
- ino_t ino = (ino_t) ReadUnalignedLE32(d);
- dev_t dev = (dev_t) ReadUnalignedLE32(d);
- mode_t mode = (mode_t) ReadUnalignedLE16(d);
- time_t mtime = (time_t) ReadUnalignedLE64(d);
- return data_type(ino, dev, mode, mtime, (off_t) ReadUnalignedLE64(d));
+ static data_type ReadData(const internal_key_type& k, const unsigned char* d,
+ unsigned) {
+ if (k.first == 0x1 /* File */) {
+ d += 4 * 2; // Skip the first 2 words.
+ ino_t ino = (ino_t) ReadUnalignedLE32(d);
+ dev_t dev = (dev_t) ReadUnalignedLE32(d);
+ mode_t mode = (mode_t) ReadUnalignedLE16(d);
+ time_t mtime = (time_t) ReadUnalignedLE64(d);
+ return data_type(ino, dev, mode, mtime, (off_t) ReadUnalignedLE64(d));
+ }
+
+ return data_type();
}
};
}
More information about the cfe-commits
mailing list