1 //===--- HeaderMap.h - A file that acts like dir of symlinks ----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the HeaderMap interface. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_LEX_HEADERMAP_H 14 #define LLVM_CLANG_LEX_HEADERMAP_H 15 16 #include "clang/Basic/FileManager.h" 17 #include "clang/Basic/LLVM.h" 18 #include "llvm/ADT/Optional.h" 19 #include "llvm/ADT/StringMap.h" 20 #include "llvm/Support/Compiler.h" 21 #include "llvm/Support/MemoryBuffer.h" 22 #include <memory> 23 24 namespace clang { 25 26 struct HMapBucket; 27 struct HMapHeader; 28 29 /// Implementation for \a HeaderMap that doesn't depend on \a FileManager. 30 class HeaderMapImpl { 31 std::unique_ptr<const llvm::MemoryBuffer> FileBuffer; 32 bool NeedsBSwap; 33 mutable llvm::StringMap<StringRef> ReverseMap; 34 35 public: 36 HeaderMapImpl(std::unique_ptr<const llvm::MemoryBuffer> File, bool NeedsBSwap) 37 : FileBuffer(std::move(File)), NeedsBSwap(NeedsBSwap) {} 38 39 // Check for a valid header and extract the byte swap. 40 static bool checkHeader(const llvm::MemoryBuffer &File, bool &NeedsByteSwap); 41 42 /// If the specified relative filename is located in this HeaderMap return 43 /// the filename it is mapped to, otherwise return an empty StringRef. 44 StringRef lookupFilename(StringRef Filename, 45 SmallVectorImpl<char> &DestPath) const; 46 47 /// Return the filename of the headermap. 48 StringRef getFileName() const; 49 50 /// Print the contents of this headermap to stderr. 51 void dump() const; 52 53 /// Return key for specifed path. 54 StringRef reverseLookupFilename(StringRef DestPath) const; 55 56 private: 57 unsigned getEndianAdjustedWord(unsigned X) const; 58 const HMapHeader &getHeader() const; 59 HMapBucket getBucket(unsigned BucketNo) const; 60 61 /// Look up the specified string in the string table. If the string index is 62 /// not valid, return None. 63 Optional<StringRef> getString(unsigned StrTabIdx) const; 64 }; 65 66 /// This class represents an Apple concept known as a 'header map'. To the 67 /// \#include file resolution process, it basically acts like a directory of 68 /// symlinks to files. Its advantages are that it is dense and more efficient 69 /// to create and process than a directory of symlinks. 70 class HeaderMap : private HeaderMapImpl { 71 HeaderMap(std::unique_ptr<const llvm::MemoryBuffer> File, bool BSwap) 72 : HeaderMapImpl(std::move(File), BSwap) {} 73 74 public: 75 /// This attempts to load the specified file as a header map. If it doesn't 76 /// look like a HeaderMap, it gives up and returns null. 77 static std::unique_ptr<HeaderMap> Create(const FileEntry *FE, 78 FileManager &FM); 79 80 using HeaderMapImpl::dump; 81 using HeaderMapImpl::getFileName; 82 using HeaderMapImpl::lookupFilename; 83 using HeaderMapImpl::reverseLookupFilename; 84 }; 85 86 } // end namespace clang. 87 88 #endif 89