HeaderSearch.h revision 6e975c4517958bcc11c834336d340797356058db
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- HeaderSearch.h - Resolve Header File Locations ---------*- C++ -*-===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file defines the HeaderSearch interface.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define LLVM_CLANG_LEX_HEADERSEARCH_H
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/DirectoryLookup.h"
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h"
1965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor#include "llvm/ADT/StringSet.h"
20d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek#include "llvm/Support/Allocator.h"
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <vector>
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
248c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
258c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorclass ExternalIdentifierLookup;
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileEntry;
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileManager;
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo;
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3083d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff/// HeaderFileInfo - The preprocessor keeps track of this information for each
3183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff/// file that is #included.
3283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroffstruct HeaderFileInfo {
3383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// isImport - True if this is a #import'd or #pragma once file.
34cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned isImport : 1;
351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
36dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// isPragmaOnce - True if this is  #pragma once file.
37dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  unsigned isPragmaOnce : 1;
38dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor
3983d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// DirInfo - Keep track of whether this is a system header, and if so,
4083d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// whether it is C++ clean or not.  This can be set by the include paths or
4183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// by #pragma gcc system_header.  This is an instance of
4283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// SrcMgr::CharacteristicKind.
4383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  unsigned DirInfo : 2;
441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
45cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Whether this header file info was supplied by an external source.
46cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned External : 1;
47cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
48cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Whether this structure is considered to already have been
49cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// "resolved", meaning that it was loaded from the external source.
50cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned Resolved : 1;
51cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
5265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Whether this is a header inside a framework that is currently
5365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// being built.
5465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  ///
5565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// When a framework is being built, the headers have not yet been placed
5665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// into the appropriate framework subdirectories, and therefore are
5765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// provided via a header map. This bit indicates when this is one of
5865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// those framework headers.
5965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  unsigned IndexHeaderMapHeader : 1;
6065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
6183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// NumIncludes - This is the number of times the file has been included
6283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// already.
6383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  unsigned short NumIncludes;
641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
65cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief The ID number of the controlling macro.
66cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ///
67cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// This ID number will be non-zero when there is a controlling
68cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// macro whose IdentifierInfo may not yet have been loaded from
69cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// external storage.
70cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned ControllingMacroID;
71cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
7283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard
7383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// that protects the entire contents of the file, this is the identifier
7483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// for the macro that controls whether or not it has any effect.
758c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  ///
768c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// Note: Most clients should use getControllingMacro() to access
778c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// the controlling macro of this header, since
788c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// getControllingMacro() is able to load a controlling macro from
798c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// external storage.
8083d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  const IdentifierInfo *ControllingMacro;
818c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
8265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief If this header came from a framework include, this is the name
8365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// of the framework.
8465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  StringRef Framework;
8565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  HeaderFileInfo()
87dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
8865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor      External(false), Resolved(false), IndexHeaderMapHeader(false),
8965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor      NumIncludes(0), ControllingMacroID(0), ControllingMacro(0)  {}
908c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
918c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// \brief Retrieve the controlling macro for this header file, if
928c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// any.
938c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
94cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
95cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Determine whether this is a non-default header file info, e.g.,
96cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// it corresponds to an actual header we've included or tried to include.
97cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  bool isNonDefault() const {
98dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    return isImport || isPragmaOnce || NumIncludes || ControllingMacro ||
99dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor      ControllingMacroID;
100cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
10183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff};
10283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
103cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor/// \brief An external source of header file information, which may supply
104cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor/// information about header files already included.
105cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregorclass ExternalHeaderFileInfoSource {
106cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregorpublic:
107cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  virtual ~ExternalHeaderFileInfoSource();
108cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
109cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Retrieve the header file information for the given file entry.
110cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ///
111cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \returns Header file information for the given file entry, with the
112cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \c External bit set. If the file entry is not known, return a
113cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// default-constructed \c HeaderFileInfo.
114cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
115cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor};
116cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// HeaderSearch - This class encapsulates the information needed to find the
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass HeaderSearch {
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FileManager &FileMgr;
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// #include search path information.  Requests for #include "x" search the
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// directory of the #including file first, then each directory in SearchDirs
12374a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  /// consecutively. Requests for <x> search the current dir first, then each
12474a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  /// directory in SearchDirs, starting at AngledDirIdx, consecutively.  If
1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// NoCurDirSearch is true, then the check for the file in the current
126fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner  /// directory is suppressed.
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  std::vector<DirectoryLookup> SearchDirs;
12874a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  unsigned AngledDirIdx;
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned SystemDirIdx;
1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool NoCurDirSearch;
1311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1329a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// \brief The path to the module cache.
1339a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  std::string ModuleCachePath;
1349a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// FileInfo - This contains all of the preprocessor-specific data about files
1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// that are included.  The vector is indexed by the FileEntry's UID.
1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
13883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  std::vector<HeaderFileInfo> FileInfo;
1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1409960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// LookupFileCache - This is keeps track of each lookup performed by
1419960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// LookupFile.  The first part of the value is the starting index in
1429960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// SearchDirs that the cached search was performed from.  If there is a hit
1439960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// and this value doesn't match the current query, the cache has to be
1449960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// ignored.  The second value is the entry in SearchDirs that satisfied the
1459960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// query.
146d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek  llvm::StringMap<std::pair<unsigned, unsigned>, llvm::BumpPtrAllocator>
147d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek    LookupFileCache;
1481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// FrameworkMap - This is a collection mapping a framework or subframework
1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// name like "Carbon" to the Carbon.framework directory.
152d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek  llvm::StringMap<const DirectoryEntry *, llvm::BumpPtrAllocator>
153d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek    FrameworkMap;
1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
156822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// headermaps.  This vector owns the headermap.
157822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
1588c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
15965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Uniqued set of framework names, which is used to track which
16065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// headers were included as framework headers.
16165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
16265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
1638c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// \brief Entity used to resolve the identifier IDs of controlling
1648c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// macros into IdentifierInfo pointers, as needed.
1658c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  ExternalIdentifierLookup *ExternalLookup;
1668c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
167cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Entity used to look up stored header file information.
168cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ExternalHeaderFileInfoSource *ExternalSource;
169cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Various statistics we track for performance analysis.
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumIncluded;
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumMultiIncludeFileOptzn;
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumFrameworkLookups, NumSubFrameworkLookups;
17449c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff
17549c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff  // HeaderSearch doesn't support default or copy construction.
1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  explicit HeaderSearch();
17749c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff  explicit HeaderSearch(const HeaderSearch&);
17849c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff  void operator=(const HeaderSearch&);
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
18039b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner  HeaderSearch(FileManager &FM);
181822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  ~HeaderSearch();
1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FileManager &getFileMgr() const { return FileMgr; }
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// SetSearchPaths - Interface for setting the file search paths.
1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
18874a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber                      unsigned angledDirIdx, unsigned systemDirIdx,
18974a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber                      bool noCurDirSearch) {
19074a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
19174a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber        "Directory indicies are unordered");
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SearchDirs = dirs;
19374a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    AngledDirIdx = angledDirIdx;
1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SystemDirIdx = systemDirIdx;
1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NoCurDirSearch = noCurDirSearch;
1969960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner    //LookupFileCache.clear();
1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1999a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// \brief Set the path to the module cache.
2009a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  void setModuleCachePath(StringRef Path) {
2019a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor    ModuleCachePath = Path;
2029a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  }
2039a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ClearFileInfo - Forget everything we know about headers so far.
2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ClearFileInfo() {
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    FileInfo.clear();
2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2098c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  void SetExternalLookup(ExternalIdentifierLookup *EIL) {
2108c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor    ExternalLookup = EIL;
2118c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  }
2128c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
213cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ExternalIdentifierLookup *getExternalLookup() const {
214cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor    return ExternalLookup;
215cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
216cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
217cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Set the external source of header information.
218cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
219cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor    ExternalSource = ES;
220cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
221cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
2237412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// return null on failure.
2247412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2257412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
2267412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// the file was found in, or null if not applicable.
2277412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2287412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param isAngled indicates whether the file reference is a <> reference.
2297412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2307412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param CurDir If non-null, the file was found in the specified directory
2317412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// search location.  This is used to implement #include_next.
2327412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2337412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param CurFileEnt If non-null, indicates where the #including file is, in
2347412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// case a relative search is needed.
2357412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2367412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param SearchPath If non-null, will be set to the search path relative
2377412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// to which the file was found. If the include path is absolute, SearchPath
2387412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// will be set to an empty string.
2397412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2407412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param RelativePath If non-null, will be set to the path relative to
2417412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// SearchPath at which the file was found. This only differs from the
2427412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// Filename for framework includes.
243686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  const FileEntry *LookupFile(StringRef Filename, bool isAngled,
2445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              const DirectoryLookup *FromDir,
2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              const DirectoryLookup *&CurDir,
246b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth                              const FileEntry *CurFileEnt,
247686775deca8b8685eb90801495880e3abdd844c2Chris Lattner                              SmallVectorImpl<char> *SearchPath,
248686775deca8b8685eb90801495880e3abdd844c2Chris Lattner                              SmallVectorImpl<char> *RelativePath);
2491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// LookupSubframeworkHeader - Look up a subframework for the specified
2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// #include file.  For example, if #include'ing <HIToolbox/HIToolbox.h> from
2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// is a subframework within Carbon.framework.  If so, return the FileEntry
2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// for the designated file, otherwise return null.
255b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth  const FileEntry *LookupSubframeworkHeader(
256686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      StringRef Filename,
257b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth      const FileEntry *RelativeFileEnt,
258686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      SmallVectorImpl<char> *SearchPath,
259686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      SmallVectorImpl<char> *RelativePath);
2601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
261afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  /// LookupFrameworkCache - Look up the specified framework name in our
262afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  /// framework cache, returning the DirectoryEntry it is in if we know,
263afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  /// otherwise, return null.
264686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  const DirectoryEntry *&LookupFrameworkCache(StringRef FWName) {
265a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner    return FrameworkMap.GetOrCreateValue(FWName).getValue();
266afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  }
2671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ShouldEnterIncludeFile - Mark the specified file as a target of of a
2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// #include, #include_next, or #import directive.  Return false if #including
2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// the file will have no effect or true if we should include it.
2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
2721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getFileDirFlavor - Return whether the specified file is a normal header,
2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// a system header, or a C++ friendly system header.
2769d72851fec9e9c62570a027d42701562bbf29751Chris Lattner  SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
2779d72851fec9e9c62570a027d42701562bbf29751Chris Lattner    return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
2785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.
2815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// due to #pragma once.
2825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void MarkFileIncludeOnce(const FileEntry *File) {
283dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    HeaderFileInfo &FI = getFileInfo(File);
284dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    FI.isImport = true;
285dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    FI.isPragmaOnce = true;
2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
288e9eb3f88b82176d8a43f7856250efded80cb2504Daniel Dunbar  /// MarkFileSystemHeader - Mark the specified file as a system header, e.g.
2895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// due to #pragma GCC system_header.
2905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void MarkFileSystemHeader(const FileEntry *File) {
2910b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner    getFileInfo(File).DirInfo = SrcMgr::C_System;
2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
29425bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  /// IncrementIncludeCount - Increment the count for the number of times the
29525bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  /// specified FileEntry has been entered.
29625bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  void IncrementIncludeCount(const FileEntry *File) {
29725bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner    ++getFileInfo(File).NumIncludes;
29825bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  }
2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// SetFileControllingMacro - Mark the specified file as having a controlling
3015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// macro.  This is used by the multiple-include optimization to eliminate
3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// no-op #includes.
3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void SetFileControllingMacro(const FileEntry *File,
3045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               const IdentifierInfo *ControllingMacro) {
3055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    getFileInfo(File).ControllingMacro = ControllingMacro;
3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
308dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// \brief Determine whether this file is intended to be safe from
309dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// multiple inclusions, e.g., it has #pragma once or a controlling
310dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// macro.
311dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  ///
312dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// This routine does not consider the effect of #import
313dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  bool isFileMultipleIncludeGuarded(const FileEntry *File);
314dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor
315822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// CreateHeaderMap - This method returns a HeaderMap for the specified
316822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
3171bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner  const HeaderMap *CreateHeaderMap(const FileEntry *FE);
3181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3199a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// \brief Search in the module cache path for a module with the given
3209a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// name.
3219a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  ///
3226e975c4517958bcc11c834336d340797356058dbDouglas Gregor  /// \param If non-NULL, will be set to the module file name we expected to
3236e975c4517958bcc11c834336d340797356058dbDouglas Gregor  /// find (regardless of whether it was actually found or not).
3246e975c4517958bcc11c834336d340797356058dbDouglas Gregor  ///
32521cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  /// \param UmbrellaHeader If non-NULL, and no module was found in the module
32621cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  /// cache, this routine will search in the framework paths to determine
32721cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  /// whether a module can be built from an umbrella header. If so, the pointee
32821cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  /// will be set to the path of the umbrella header.
32921cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  ///
3309a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// \returns A file describing the named module, if available, or NULL to
3319a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// indicate that the module could not be found.
33221cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  const FileEntry *lookupModule(StringRef ModuleName,
3336e975c4517958bcc11c834336d340797356058dbDouglas Gregor                                std::string *ModuleFileName = 0,
33421cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor                                std::string *UmbrellaHeader = 0);
3359a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
336afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
33783d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
33812fab31aa5868b1a6b52246b5a87daa48a338fe2Douglas Gregor  typedef std::vector<HeaderFileInfo>::const_iterator header_file_iterator;
33912fab31aa5868b1a6b52246b5a87daa48a338fe2Douglas Gregor  header_file_iterator header_file_begin() const { return FileInfo.begin(); }
34012fab31aa5868b1a6b52246b5a87daa48a338fe2Douglas Gregor  header_file_iterator header_file_end() const { return FileInfo.end(); }
34112fab31aa5868b1a6b52246b5a87daa48a338fe2Douglas Gregor  unsigned header_file_size() const { return FileInfo.size(); }
34283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
343c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl  // Used by ASTReader.
34483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
3451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
346ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  // Used by external tools
347ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
348ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
349ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
350ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  unsigned search_dir_size() const { return SearchDirs.size(); }
351ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor
35274a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator quoted_dir_begin() const {
35374a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin();
35474a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
35574a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator quoted_dir_end() const {
35674a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + AngledDirIdx;
35774a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
35874a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber
35974a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator angled_dir_begin() const {
36074a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + AngledDirIdx;
36174a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
36274a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator angled_dir_end() const {
36374a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + SystemDirIdx;
36474a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
36574a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber
366ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator system_dir_begin() const {
367ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor    return SearchDirs.begin() + SystemDirIdx;
368ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  }
369ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
370ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor
37165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Retrieve a uniqued framework name.
37265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  StringRef getUniqueFrameworkName(StringRef Framework);
37365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void PrintStats();
375d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek
376d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek  size_t getTotalMemory() const;
377d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek
3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
3791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38083d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// getFileInfo - Return the HeaderFileInfo structure for the specified
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// FileEntry.
38283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  HeaderFileInfo &getFileInfo(const FileEntry *FE);
3835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
3845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end namespace clang
3865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
388