Home | History | Annotate | Download | only in Lex
      1 //===--- HeaderMap.h - A file that acts like dir of symlinks ----*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the HeaderMap interface.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_LEX_HEADERMAP_H
     15 #define LLVM_CLANG_LEX_HEADERMAP_H
     16 
     17 #include "clang/Basic/LLVM.h"
     18 #include "llvm/ADT/Optional.h"
     19 #include "llvm/Support/Compiler.h"
     20 #include "llvm/Support/MemoryBuffer.h"
     21 #include <memory>
     22 
     23 namespace clang {
     24 
     25 class FileEntry;
     26 class FileManager;
     27 struct HMapBucket;
     28 struct HMapHeader;
     29 
     30 /// Implementation for \a HeaderMap that doesn't depend on \a FileManager.
     31 class HeaderMapImpl {
     32   std::unique_ptr<const llvm::MemoryBuffer> FileBuffer;
     33   bool NeedsBSwap;
     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   const char *getFileName() const;
     49 
     50   /// Print the contents of this headermap to stderr.
     51   void dump() const;
     52 
     53 private:
     54   unsigned getEndianAdjustedWord(unsigned X) const;
     55   const HMapHeader &getHeader() const;
     56   HMapBucket getBucket(unsigned BucketNo) const;
     57 
     58   /// Look up the specified string in the string table.  If the string index is
     59   /// not valid, return None.
     60   Optional<StringRef> getString(unsigned StrTabIdx) const;
     61 };
     62 
     63 /// This class represents an Apple concept known as a 'header map'.  To the
     64 /// \#include file resolution process, it basically acts like a directory of
     65 /// symlinks to files.  Its advantages are that it is dense and more efficient
     66 /// to create and process than a directory of symlinks.
     67 class HeaderMap : private HeaderMapImpl {
     68   HeaderMap(std::unique_ptr<const llvm::MemoryBuffer> File, bool BSwap)
     69       : HeaderMapImpl(std::move(File), BSwap) {}
     70 
     71 public:
     72   /// This attempts to load the specified file as a header map.  If it doesn't
     73   /// look like a HeaderMap, it gives up and returns null.
     74   static const HeaderMap *Create(const FileEntry *FE, FileManager &FM);
     75 
     76   /// Check to see if the specified relative filename is located in this
     77   /// HeaderMap.  If so, open it and return its FileEntry.  If RawPath is not
     78   /// NULL and the file is found, RawPath will be set to the raw path at which
     79   /// the file was found in the file system. For example, for a search path
     80   /// ".." and a filename "../file.h" this would be "../../file.h".
     81   const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const;
     82 
     83   using HeaderMapImpl::lookupFilename;
     84   using HeaderMapImpl::getFileName;
     85   using HeaderMapImpl::dump;
     86 };
     87 
     88 } // end namespace clang.
     89 
     90 #endif
     91