Add some boilerplate to the PTH file to prepare for the caching of stats for directories (and negative stats too).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64477 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/CacheTokens.cpp b/Driver/CacheTokens.cpp
index 52ce082..0089e0c 100644
--- a/Driver/CacheTokens.cpp
+++ b/Driver/CacheTokens.cpp
@@ -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:
- typedef const FileEntry* key_type;
+ 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 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) {