diff options
-rw-r--r-- | Driver/clang.cpp | 12 | ||||
-rw-r--r-- | Lex/HeaderMap.cpp | 54 | ||||
-rw-r--r-- | Lex/HeaderSearch.cpp | 5 | ||||
-rw-r--r-- | include/clang/Lex/HeaderMap.h | 4 | ||||
-rw-r--r-- | include/clang/Lex/HeaderSearch.h | 2 |
5 files changed, 58 insertions, 19 deletions
diff --git a/Driver/clang.cpp b/Driver/clang.cpp index 05b6a0f1fe..58c384d65e 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -666,19 +666,11 @@ static void AddPath(const std::string &Path, IncludeDirGroup Group, if (!isFramework) { if (const FileEntry *FE = FM.getFile(&MappedPath[0], &MappedPath[0]+MappedPath.size())) { - std::string ErrorInfo; - const HeaderMap *HM = HS.CreateHeaderMap(FE, ErrorInfo); - if (HM) { + if (const HeaderMap *HM = HS.CreateHeaderMap(FE)) { + // It is a headermap, add it to the search path. IncludeGroup[Group].push_back(DirectoryLookup(HM, Type,isUserSupplied)); return; } - - // If this looked like a headermap but was corrupted, emit that error, - // otherwise treat it as a missing directory. - if (!ErrorInfo.empty()) { - fprintf(stderr, "%s\n", ErrorInfo.c_str()); - return; - } } } diff --git a/Lex/HeaderMap.cpp b/Lex/HeaderMap.cpp index 5b9c4b0d23..ebcbc17f80 100644 --- a/Lex/HeaderMap.cpp +++ b/Lex/HeaderMap.cpp @@ -12,10 +12,60 @@ //===----------------------------------------------------------------------===// #include "clang/Lex/HeaderMap.h" +#include "clang/Basic/FileManager.h" +#include "llvm/ADT/scoped_ptr.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/MemoryBuffer.h" using namespace clang; -const HeaderMap *HeaderMap::Create(const FileEntry *FE, std::string &ErrorInfo){ - // FIXME: woot! +enum { + HeaderMagicNumber = ('h' << 24) | ('m' << 16) | ('a' << 8) | 'p' +}; + +struct HMapHeader { + uint32_t Magic; // Magic word, also indicates byte order. + uint16_t Version; // Version number -- currently 1. + uint16_t Reserved; // Reserved for future use - zero for now. + uint32_t StringsOffset; // Offset to start of string pool. + uint32_t Count; // Number of entries in the string table. + uint32_t Capacity; // Number of buckets (always a power of 2). + uint32_t MaxValueLength; // Length of longest result path (excluding nul). + // Strings follow the buckets, at StringsOffset. +}; + + +/// HeaderMap::Create - This attempts to load the specified file as a header +/// map. If it doesn't look like a HeaderMap, it gives up and returns null. +/// If it looks like a HeaderMap but is obviously corrupted, it puts a reason +/// into the string error argument and returns null. +const HeaderMap *HeaderMap::Create(const FileEntry *FE) { + // If the file is too small to be a header map, ignore it. + unsigned FileSize = FE->getSize(); + if (FileSize <= sizeof(HMapHeader)) return 0; + + llvm::scoped_ptr<const llvm::MemoryBuffer> File( + llvm::MemoryBuffer::getFile(FE->getName(), strlen(FE->getName()), 0, + FE->getSize())); + if (File == 0) return 0; // Unreadable file? + const char *FileStart = File->getBufferStart(); + + // We know the file is at least as big as the header, check it now. + const HMapHeader *Header = reinterpret_cast<const HMapHeader*>(FileStart); + + // Sniff it to see if it's a headermap. + if (Header->Version != 1 || Header->Reserved != 0) + return 0; + + // Check the magic number. + bool NeedsByteSwap; + if (Header->Magic == HeaderMagicNumber) + NeedsByteSwap = false; + else if (Header->Magic == llvm::ByteSwap_32(HeaderMagicNumber)) + NeedsByteSwap = true; // Mixed endianness headermap. + else + return 0; // Not a header map. + return 0; } diff --git a/Lex/HeaderSearch.cpp b/Lex/HeaderSearch.cpp index 99d0d52f11..beda5893ac 100644 --- a/Lex/HeaderSearch.cpp +++ b/Lex/HeaderSearch.cpp @@ -58,8 +58,7 @@ void HeaderSearch::PrintStats() { /// CreateHeaderMap - This method returns a HeaderMap for the specified /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure. -const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE, - std::string &ErrorInfo) { +const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { // We expect the number of headermaps to be small, and almost always empty. // If it ever grows, use of a linear search should be re-evaluated. if (!HeaderMaps.empty()) { @@ -70,7 +69,7 @@ const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE, return HeaderMaps[i].second; } - if (const HeaderMap *HM = HeaderMap::Create(FE, ErrorInfo)) { + if (const HeaderMap *HM = HeaderMap::Create(FE)) { HeaderMaps.push_back(std::make_pair(FE, HM)); return HM; } diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h index 8b1669f86b..dc70d848e0 100644 --- a/include/clang/Lex/HeaderMap.h +++ b/include/clang/Lex/HeaderMap.h @@ -30,9 +30,7 @@ class HeaderMap { public: /// HeaderMap::Create - This attempts to load the specified file as a header /// map. If it doesn't look like a HeaderMap, it gives up and returns null. - /// If it looks like a HeaderMap but is obviously corrupted, it puts a reason - /// into the string error argument and returns null. - static const HeaderMap *Create(const FileEntry *FE, std::string &ErrorInfo); + static const HeaderMap *Create(const FileEntry *FE); /// LookupFile - Check to see if the specified relative filename is located in /// this HeaderMap. If so, open it and return its FileEntry. diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 6e1965bedb..fe22381eec 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -181,7 +181,7 @@ public: /// CreateHeaderMap - This method returns a HeaderMap for the specified /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure. - const HeaderMap *CreateHeaderMap(const FileEntry *FE, std::string &ErrorInfo); + const HeaderMap *CreateHeaderMap(const FileEntry *FE); void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; } |