summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp198
1 files changed, 115 insertions, 83 deletions
diff --git a/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp b/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp
index e2629a3..fce31c4 100644
--- a/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp
+++ b/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp
@@ -15,21 +15,21 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemStatCache.h"
#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/OnDiskHashTable.h"
#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/PTHManager.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/Token.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/EndianStream.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/system_error.h"
+#include "llvm/Support/OnDiskHashTable.h"
+#include <memory>
+#include <system_error>
using namespace clang;
-using namespace clang::io;
-#define DISK_TOKEN_SIZE (1+1+2+4+4)
+static const unsigned StoredTokenSize = 1 + 1 + 2 + 4 + 4;
//===----------------------------------------------------------------------===//
// PTHLexer methods.
@@ -37,7 +37,7 @@ using namespace clang::io;
PTHLexer::PTHLexer(Preprocessor &PP, FileID FID, const unsigned char *D,
const unsigned char *ppcond, PTHManager &PM)
- : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
+ : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), LastHashTokPtr(nullptr),
PPCond(ppcond), CurPPCondPtr(ppcond), PTHMgr(PM) {
FileStartLoc = PP.getSourceManager().getLocForStartOfFile(FID);
@@ -47,14 +47,17 @@ bool PTHLexer::Lex(Token& Tok) {
//===--------------------------------------==//
// Read the raw token data.
//===--------------------------------------==//
+ using namespace llvm::support;
// Shadow CurPtr into an automatic variable.
const unsigned char *CurPtrShadow = CurPtr;
// Read in the data for the token.
- unsigned Word0 = ReadLE32(CurPtrShadow);
- uint32_t IdentifierID = ReadLE32(CurPtrShadow);
- uint32_t FileOffset = ReadLE32(CurPtrShadow);
+ unsigned Word0 = endian::readNext<uint32_t, little, aligned>(CurPtrShadow);
+ uint32_t IdentifierID =
+ endian::readNext<uint32_t, little, aligned>(CurPtrShadow);
+ uint32_t FileOffset =
+ endian::readNext<uint32_t, little, aligned>(CurPtrShadow);
tok::TokenKind TKind = (tok::TokenKind) (Word0 & 0xFF);
Token::TokenFlags TFlags = (Token::TokenFlags) ((Word0 >> 8) & 0xFF);
@@ -107,7 +110,7 @@ bool PTHLexer::Lex(Token& Tok) {
}
if (TKind == tok::hash && Tok.isAtStartOfLine()) {
- LastHashTokPtr = CurPtr - DISK_TOKEN_SIZE;
+ LastHashTokPtr = CurPtr - StoredTokenSize;
assert(!LexingRawMode);
PP->HandleDirective(Tok);
@@ -176,7 +179,7 @@ void PTHLexer::DiscardToEndOfLine() {
if (y & Token::StartOfLine) break;
// Skip to the next token.
- p += DISK_TOKEN_SIZE;
+ p += StoredTokenSize;
}
CurPtr = p;
@@ -184,18 +187,19 @@ void PTHLexer::DiscardToEndOfLine() {
/// SkipBlock - Used by Preprocessor to skip the current conditional block.
bool PTHLexer::SkipBlock() {
+ using namespace llvm::support;
assert(CurPPCondPtr && "No cached PP conditional information.");
assert(LastHashTokPtr && "No known '#' token.");
- const unsigned char* HashEntryI = 0;
+ const unsigned char *HashEntryI = nullptr;
uint32_t TableIdx;
do {
// Read the token offset from the side-table.
- uint32_t Offset = ReadLE32(CurPPCondPtr);
+ uint32_t Offset = endian::readNext<uint32_t, little, aligned>(CurPPCondPtr);
// Read the target table index from the side-table.
- TableIdx = ReadLE32(CurPPCondPtr);
+ TableIdx = endian::readNext<uint32_t, little, aligned>(CurPPCondPtr);
// Compute the actual memory address of the '#' token data for this entry.
HashEntryI = TokBuf + Offset;
@@ -212,12 +216,13 @@ bool PTHLexer::SkipBlock() {
PPCond + TableIdx*(sizeof(uint32_t)*2);
assert(NextPPCondPtr >= CurPPCondPtr);
// Read where we should jump to.
- const unsigned char* HashEntryJ = TokBuf + ReadLE32(NextPPCondPtr);
+ const unsigned char *HashEntryJ =
+ TokBuf + endian::readNext<uint32_t, little, aligned>(NextPPCondPtr);
if (HashEntryJ <= LastHashTokPtr) {
// Jump directly to the next entry in the side table.
HashEntryI = HashEntryJ;
- TableIdx = ReadLE32(NextPPCondPtr);
+ TableIdx = endian::readNext<uint32_t, little, aligned>(NextPPCondPtr);
CurPPCondPtr = NextPPCondPtr;
}
}
@@ -232,8 +237,9 @@ bool PTHLexer::SkipBlock() {
CurPPCondPtr = NextPPCondPtr;
// Read where we should jump to.
- HashEntryI = TokBuf + ReadLE32(NextPPCondPtr);
- uint32_t NextIdx = ReadLE32(NextPPCondPtr);
+ HashEntryI =
+ TokBuf + endian::readNext<uint32_t, little, aligned>(NextPPCondPtr);
+ uint32_t NextIdx = endian::readNext<uint32_t, little, aligned>(NextPPCondPtr);
// By construction NextIdx will be zero if this is a #endif. This is useful
// to know to obviate lexing another token.
@@ -249,10 +255,10 @@ bool PTHLexer::SkipBlock() {
// already points 'elif'. Just return.
if (CurPtr > HashEntryI) {
- assert(CurPtr == HashEntryI + DISK_TOKEN_SIZE);
+ assert(CurPtr == HashEntryI + StoredTokenSize);
// Did we reach a #endif? If so, go ahead and consume that token as well.
if (isEndif)
- CurPtr += DISK_TOKEN_SIZE*2;
+ CurPtr += StoredTokenSize * 2;
else
LastHashTokPtr = HashEntryI;
@@ -268,10 +274,12 @@ bool PTHLexer::SkipBlock() {
// Skip the '#' token.
assert(((tok::TokenKind)*CurPtr) == tok::hash);
- CurPtr += DISK_TOKEN_SIZE;
+ CurPtr += StoredTokenSize;
// Did we reach a #endif? If so, go ahead and consume that token as well.
- if (isEndif) { CurPtr += DISK_TOKEN_SIZE*2; }
+ if (isEndif) {
+ CurPtr += StoredTokenSize * 2;
+ }
return isEndif;
}
@@ -282,8 +290,10 @@ SourceLocation PTHLexer::getSourceLocation() {
// handling a #included file. Just read the necessary data from the token
// data buffer to construct the SourceLocation object.
// NOTE: This is a virtual function; hence it is defined out-of-line.
- const unsigned char *OffsetPtr = CurPtr + (DISK_TOKEN_SIZE - 4);
- uint32_t Offset = ReadLE32(OffsetPtr);
+ using namespace llvm::support;
+
+ const unsigned char *OffsetPtr = CurPtr + (StoredTokenSize - 4);
+ uint32_t Offset = endian::readNext<uint32_t, little, aligned>(OffsetPtr);
return FileStartLoc.getLocWithOffset(Offset);
}
@@ -310,14 +320,18 @@ public:
class PTHFileLookupCommonTrait {
public:
typedef std::pair<unsigned char, const char*> internal_key_type;
+ typedef unsigned hash_value_type;
+ typedef unsigned offset_type;
- static unsigned ComputeHash(internal_key_type x) {
+ static hash_value_type ComputeHash(internal_key_type x) {
return llvm::HashString(x.second);
}
static std::pair<unsigned, unsigned>
ReadKeyDataLength(const unsigned char*& d) {
- unsigned keyLen = (unsigned) ReadUnalignedLE16(d);
+ using namespace llvm::support;
+ unsigned keyLen =
+ (unsigned)endian::readNext<uint16_t, little, unaligned>(d);
unsigned dataLen = (unsigned) *(d++);
return std::make_pair(keyLen, dataLen);
}
@@ -344,21 +358,20 @@ public:
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);
+ using namespace llvm::support;
+ uint32_t x = endian::readNext<uint32_t, little, unaligned>(d);
+ uint32_t y = endian::readNext<uint32_t, little, unaligned>(d);
return PTHFileData(x, y);
}
};
class PTHStringLookupTrait {
public:
- typedef uint32_t
- data_type;
-
- typedef const std::pair<const char*, unsigned>
- external_key_type;
-
+ typedef uint32_t data_type;
+ typedef const std::pair<const char*, unsigned> external_key_type;
typedef external_key_type internal_key_type;
+ typedef uint32_t hash_value_type;
+ typedef unsigned offset_type;
static bool EqualKey(const internal_key_type& a,
const internal_key_type& b) {
@@ -366,7 +379,7 @@ public:
: false;
}
- static unsigned ComputeHash(const internal_key_type& a) {
+ static hash_value_type ComputeHash(const internal_key_type& a) {
return llvm::HashString(StringRef(a.first, a.second));
}
@@ -376,7 +389,10 @@ public:
static std::pair<unsigned, unsigned>
ReadKeyDataLength(const unsigned char*& d) {
- return std::make_pair((unsigned) ReadUnalignedLE16(d), sizeof(uint32_t));
+ using namespace llvm::support;
+ return std::make_pair(
+ (unsigned)endian::readNext<uint16_t, little, unaligned>(d),
+ sizeof(uint32_t));
}
static std::pair<const char*, unsigned>
@@ -387,14 +403,15 @@ public:
static uint32_t ReadData(const internal_key_type& k, const unsigned char* d,
unsigned) {
- return ::ReadUnalignedLE32(d);
+ using namespace llvm::support;
+ return endian::readNext<uint32_t, little, unaligned>(d);
}
};
} // end anonymous namespace
-typedef OnDiskChainedHashTable<PTHFileLookupTrait> PTHFileLookup;
-typedef OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup;
+typedef llvm::OnDiskChainedHashTable<PTHFileLookupTrait> PTHFileLookup;
+typedef llvm::OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup;
//===----------------------------------------------------------------------===//
// PTHManager methods.
@@ -408,7 +425,7 @@ PTHManager::PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup,
const char* originalSourceFile)
: Buf(buf), PerIDCache(perIDCache), FileLookup(fileLookup),
IdDataTable(idDataTable), StringIdLookup(stringIdLookup),
- NumIds(numIds), PP(0), SpellingBase(spellingBase),
+ NumIds(numIds), PP(nullptr), SpellingBase(spellingBase),
OriginalSourceFile(originalSourceFile) {}
PTHManager::~PTHManager() {
@@ -419,19 +436,23 @@ PTHManager::~PTHManager() {
}
static void InvalidPTH(DiagnosticsEngine &Diags, const char *Msg) {
- Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, Msg));
+ Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0")) << Msg;
}
PTHManager *PTHManager::Create(const std::string &file,
DiagnosticsEngine &Diags) {
// Memory map the PTH file.
- OwningPtr<llvm::MemoryBuffer> File;
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileOrErr =
+ llvm::MemoryBuffer::getFile(file);
- if (llvm::MemoryBuffer::getFile(file, File)) {
+ if (!FileOrErr) {
// FIXME: Add ec.message() to this diag.
Diags.Report(diag::err_invalid_pth_file) << file;
- return 0;
+ return nullptr;
}
+ std::unique_ptr<llvm::MemoryBuffer> File = std::move(FileOrErr.get());
+
+ using namespace llvm::support;
// Get the buffer ranges and check if there are at least three 32-bit
// words at the end of the file.
@@ -442,19 +463,19 @@ PTHManager *PTHManager::Create(const std::string &file,
if ((BufEnd - BufBeg) < (signed)(sizeof("cfe-pth") + 4 + 4) ||
memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth")) != 0) {
Diags.Report(diag::err_invalid_pth_file) << file;
- return 0;
+ return nullptr;
}
// Read the PTH version.
const unsigned char *p = BufBeg + (sizeof("cfe-pth"));
- unsigned Version = ReadLE32(p);
+ unsigned Version = endian::readNext<uint32_t, little, aligned>(p);
if (Version < PTHManager::Version) {
InvalidPTH(Diags,
Version < PTHManager::Version
? "PTH file uses an older PTH format that is no longer supported"
: "PTH file uses a newer PTH format that cannot be read");
- return 0;
+ return nullptr;
}
// Compute the address of the index table at the end of the PTH file.
@@ -462,20 +483,21 @@ PTHManager *PTHManager::Create(const std::string &file,
if (PrologueOffset >= BufEnd) {
Diags.Report(diag::err_invalid_pth_file) << file;
- return 0;
+ return nullptr;
}
// Construct the file lookup table. This will be used for mapping from
// FileEntry*'s to cached tokens.
const unsigned char* FileTableOffset = PrologueOffset + sizeof(uint32_t)*2;
- const unsigned char* FileTable = BufBeg + ReadLE32(FileTableOffset);
+ const unsigned char *FileTable =
+ BufBeg + endian::readNext<uint32_t, little, aligned>(FileTableOffset);
if (!(FileTable > BufBeg && FileTable < BufEnd)) {
Diags.Report(diag::err_invalid_pth_file) << file;
- return 0; // FIXME: Proper error diagnostic?
+ return nullptr; // FIXME: Proper error diagnostic?
}
- OwningPtr<PTHFileLookup> FL(PTHFileLookup::Create(FileTable, BufBeg));
+ std::unique_ptr<PTHFileLookup> FL(PTHFileLookup::Create(FileTable, BufBeg));
// Warn if the PTH file is empty. We still want to create a PTHManager
// as the PTH could be used with -include-pth.
@@ -485,65 +507,71 @@ PTHManager *PTHManager::Create(const std::string &file,
// Get the location of the table mapping from persistent ids to the
// data needed to reconstruct identifiers.
const unsigned char* IDTableOffset = PrologueOffset + sizeof(uint32_t)*0;
- const unsigned char* IData = BufBeg + ReadLE32(IDTableOffset);
+ const unsigned char *IData =
+ BufBeg + endian::readNext<uint32_t, little, aligned>(IDTableOffset);
if (!(IData >= BufBeg && IData < BufEnd)) {
Diags.Report(diag::err_invalid_pth_file) << file;
- return 0;
+ return nullptr;
}
// Get the location of the hashtable mapping between strings and
// persistent IDs.
const unsigned char* StringIdTableOffset = PrologueOffset + sizeof(uint32_t)*1;
- const unsigned char* StringIdTable = BufBeg + ReadLE32(StringIdTableOffset);
+ const unsigned char *StringIdTable =
+ BufBeg + endian::readNext<uint32_t, little, aligned>(StringIdTableOffset);
if (!(StringIdTable >= BufBeg && StringIdTable < BufEnd)) {
Diags.Report(diag::err_invalid_pth_file) << file;
- return 0;
+ return nullptr;
}
- OwningPtr<PTHStringIdLookup> SL(PTHStringIdLookup::Create(StringIdTable,
- BufBeg));
+ std::unique_ptr<PTHStringIdLookup> SL(
+ PTHStringIdLookup::Create(StringIdTable, BufBeg));
// Get the location of the spelling cache.
const unsigned char* spellingBaseOffset = PrologueOffset + sizeof(uint32_t)*3;
- const unsigned char* spellingBase = BufBeg + ReadLE32(spellingBaseOffset);
+ const unsigned char *spellingBase =
+ BufBeg + endian::readNext<uint32_t, little, aligned>(spellingBaseOffset);
if (!(spellingBase >= BufBeg && spellingBase < BufEnd)) {
Diags.Report(diag::err_invalid_pth_file) << file;
- return 0;
+ return nullptr;
}
// Get the number of IdentifierInfos and pre-allocate the identifier cache.
- uint32_t NumIds = ReadLE32(IData);
+ uint32_t NumIds = endian::readNext<uint32_t, little, aligned>(IData);
// Pre-allocate the persistent ID -> IdentifierInfo* cache. We use calloc()
// so that we in the best case only zero out memory once when the OS returns
// us new pages.
- IdentifierInfo** PerIDCache = 0;
+ IdentifierInfo **PerIDCache = nullptr;
if (NumIds) {
PerIDCache = (IdentifierInfo**)calloc(NumIds, sizeof(*PerIDCache));
if (!PerIDCache) {
InvalidPTH(Diags, "Could not allocate memory for processing PTH file");
- return 0;
+ return nullptr;
}
}
// Compute the address of the original source file.
const unsigned char* originalSourceBase = PrologueOffset + sizeof(uint32_t)*4;
- unsigned len = ReadUnalignedLE16(originalSourceBase);
- if (!len) originalSourceBase = 0;
+ unsigned len =
+ endian::readNext<uint16_t, little, unaligned>(originalSourceBase);
+ if (!len) originalSourceBase = nullptr;
// Create the new PTHManager.
- return new PTHManager(File.take(), FL.take(), IData, PerIDCache,
- SL.take(), NumIds, spellingBase,
- (const char*) originalSourceBase);
+ return new PTHManager(File.release(), FL.release(), IData, PerIDCache,
+ SL.release(), NumIds, spellingBase,
+ (const char *)originalSourceBase);
}
IdentifierInfo* PTHManager::LazilyCreateIdentifierInfo(unsigned PersistentID) {
+ using namespace llvm::support;
// Look in the PTH file for the string data for the IdentifierInfo object.
const unsigned char* TableEntry = IdDataTable + sizeof(uint32_t)*PersistentID;
- const unsigned char* IDData =
- (const unsigned char*)Buf->getBufferStart() + ReadLE32(TableEntry);
+ const unsigned char *IDData =
+ (const unsigned char *)Buf->getBufferStart() +
+ endian::readNext<uint32_t, little, aligned>(TableEntry);
assert(IDData < (const unsigned char*)Buf->getBufferEnd());
// Allocate the object.
@@ -567,7 +595,7 @@ IdentifierInfo* PTHManager::get(StringRef Name) {
PTHStringIdLookup::iterator I = SL.find(std::make_pair(Name.data(),
Name.size()));
if (I == SL.end()) // No identifier found?
- return 0;
+ return nullptr;
// Match found. Return the identifier!
assert(*I > 0);
@@ -577,7 +605,9 @@ IdentifierInfo* PTHManager::get(StringRef Name) {
PTHLexer *PTHManager::CreateLexer(FileID FID) {
const FileEntry *FE = PP->getSourceManager().getFileEntryForID(FID);
if (!FE)
- return 0;
+ return nullptr;
+
+ using namespace llvm::support;
// Lookup the FileEntry object in our file lookup data structure. It will
// return a variant that indicates whether or not there is an offset within
@@ -586,7 +616,7 @@ PTHLexer *PTHManager::CreateLexer(FileID FID) {
PTHFileLookup::iterator I = PFL.find(FE);
if (I == PFL.end()) // No tokens available?
- return 0;
+ return nullptr;
const PTHFileData& FileData = *I;
@@ -596,8 +626,8 @@ PTHLexer *PTHManager::CreateLexer(FileID FID) {
// Get the location of pp-conditional table.
const unsigned char* ppcond = BufStart + FileData.getPPCondOffset();
- uint32_t Len = ReadLE32(ppcond);
- if (Len == 0) ppcond = 0;
+ uint32_t Len = endian::readNext<uint32_t, little, aligned>(ppcond);
+ if (Len == 0) ppcond = nullptr;
assert(PP && "No preprocessor set yet!");
return new PTHLexer(*PP, FID, data, ppcond, *this);
@@ -650,11 +680,13 @@ public:
d += 4 * 2; // Skip the first 2 words.
}
- uint64_t File = ReadUnalignedLE64(d);
- uint64_t Device = ReadUnalignedLE64(d);
+ using namespace llvm::support;
+
+ uint64_t File = endian::readNext<uint64_t, little, unaligned>(d);
+ uint64_t Device = endian::readNext<uint64_t, little, unaligned>(d);
llvm::sys::fs::UniqueID UniqueID(File, Device);
- time_t ModTime = ReadUnalignedLE64(d);
- uint64_t Size = ReadUnalignedLE64(d);
+ time_t ModTime = endian::readNext<uint64_t, little, unaligned>(d);
+ uint64_t Size = endian::readNext<uint64_t, little, unaligned>(d);
return data_type(Size, ModTime, UniqueID, IsDirectory);
}
@@ -664,7 +696,7 @@ public:
};
class PTHStatCache : public FileSystemStatCache {
- typedef OnDiskChainedHashTable<PTHStatLookupTrait> CacheTy;
+ typedef llvm::OnDiskChainedHashTable<PTHStatLookupTrait> CacheTy;
CacheTy Cache;
public:
@@ -672,22 +704,22 @@ public:
Cache(FL.getNumBuckets(), FL.getNumEntries(), FL.getBuckets(),
FL.getBase()) {}
- ~PTHStatCache() {}
-
LookupResult getStat(const char *Path, FileData &Data, bool isFile,
- int *FileDescriptor) {
+ std::unique_ptr<vfs::File> *F,
+ vfs::FileSystem &FS) override {
// Do the lookup for the file's data in the PTH file.
CacheTy::iterator I = Cache.find(Path);
// If we don't get a hit in the PTH file just forward to 'stat'.
if (I == Cache.end())
- return statChained(Path, Data, isFile, FileDescriptor);
+ return statChained(Path, Data, isFile, F, FS);
const PTHStatData &D = *I;
if (!D.HasData)
return CacheMissing;
+ Data.Name = Path;
Data.Size = D.Size;
Data.ModTime = D.ModTime;
Data.UniqueID = D.UniqueID;
OpenPOWER on IntegriCloud