HeaderSearch.h revision 1c2e9332fa69727425a3a2b912e36e2ab62083f8
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"
18a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Lex/ModuleMap.h"
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h"
2065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor#include "llvm/ADT/StringSet.h"
21d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek#include "llvm/Support/Allocator.h"
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <vector>
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
258e23806863721495f9e1f84aed614f7afba774a3Douglas Gregor
268e23806863721495f9e1f84aed614f7afba774a3Douglas Gregorclass DiagnosticsEngine;
278c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorclass ExternalIdentifierLookup;
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileEntry;
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileManager;
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo;
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff/// HeaderFileInfo - The preprocessor keeps track of this information for each
3383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff/// file that is #included.
3483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroffstruct HeaderFileInfo {
3583d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// isImport - True if this is a #import'd or #pragma once file.
36cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned isImport : 1;
371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// isPragmaOnce - True if this is  #pragma once file.
39dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  unsigned isPragmaOnce : 1;
40dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor
4183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// DirInfo - Keep track of whether this is a system header, and if so,
4283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// whether it is C++ clean or not.  This can be set by the include paths or
4383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// by #pragma gcc system_header.  This is an instance of
4483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// SrcMgr::CharacteristicKind.
4583d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  unsigned DirInfo : 2;
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
47cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Whether this header file info was supplied by an external source.
48cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned External : 1;
49cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
50cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Whether this structure is considered to already have been
51cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// "resolved", meaning that it was loaded from the external source.
52cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned Resolved : 1;
53cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
5465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Whether this is a header inside a framework that is currently
5565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// being built.
5665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  ///
5765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// When a framework is being built, the headers have not yet been placed
5865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// into the appropriate framework subdirectories, and therefore are
5965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// provided via a header map. This bit indicates when this is one of
6065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// those framework headers.
6165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  unsigned IndexHeaderMapHeader : 1;
6265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
6383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// NumIncludes - This is the number of times the file has been included
6483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// already.
6583d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  unsigned short NumIncludes;
661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
67cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief The ID number of the controlling macro.
68cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ///
69cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// This ID number will be non-zero when there is a controlling
70cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// macro whose IdentifierInfo may not yet have been loaded from
71cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// external storage.
72cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned ControllingMacroID;
73cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
7483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard
7583d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// that protects the entire contents of the file, this is the identifier
7683d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// for the macro that controls whether or not it has any effect.
778c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  ///
788c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// Note: Most clients should use getControllingMacro() to access
798c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// the controlling macro of this header, since
808c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// getControllingMacro() is able to load a controlling macro from
818c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// external storage.
8283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  const IdentifierInfo *ControllingMacro;
838c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
8465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief If this header came from a framework include, this is the name
8565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// of the framework.
8665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  StringRef Framework;
8765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  HeaderFileInfo()
89dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
9065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor      External(false), Resolved(false), IndexHeaderMapHeader(false),
9165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor      NumIncludes(0), ControllingMacroID(0), ControllingMacro(0)  {}
928c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
938c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// \brief Retrieve the controlling macro for this header file, if
948c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// any.
958c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
96cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
97cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Determine whether this is a non-default header file info, e.g.,
98cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// it corresponds to an actual header we've included or tried to include.
99cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  bool isNonDefault() const {
100dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    return isImport || isPragmaOnce || NumIncludes || ControllingMacro ||
101dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor      ControllingMacroID;
102cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
10383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff};
10483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
105cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor/// \brief An external source of header file information, which may supply
106cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor/// information about header files already included.
107cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregorclass ExternalHeaderFileInfoSource {
108cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregorpublic:
109cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  virtual ~ExternalHeaderFileInfoSource();
110cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
111cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Retrieve the header file information for the given file entry.
112cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ///
113cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \returns Header file information for the given file entry, with the
114cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \c External bit set. If the file entry is not known, return a
115cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// default-constructed \c HeaderFileInfo.
116cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
117cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor};
118cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// HeaderSearch - This class encapsulates the information needed to find the
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass HeaderSearch {
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FileManager &FileMgr;
1238e23806863721495f9e1f84aed614f7afba774a3Douglas Gregor  DiagnosticsEngine &Diags;
1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// #include search path information.  Requests for #include "x" search the
1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// directory of the #including file first, then each directory in SearchDirs
12674a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  /// consecutively. Requests for <x> search the current dir first, then each
12774a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  /// directory in SearchDirs, starting at AngledDirIdx, consecutively.  If
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// NoCurDirSearch is true, then the check for the file in the current
129fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner  /// directory is suppressed.
1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  std::vector<DirectoryLookup> SearchDirs;
13174a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  unsigned AngledDirIdx;
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned SystemDirIdx;
1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool NoCurDirSearch;
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1359a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// \brief The path to the module cache.
1369a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  std::string ModuleCachePath;
1379a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
138fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  /// \brief The name of the module we're building.
139fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  std::string BuildingModule;
140fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor
1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// FileInfo - This contains all of the preprocessor-specific data about files
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// that are included.  The vector is indexed by the FileEntry's UID.
1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
14483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  std::vector<HeaderFileInfo> FileInfo;
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1469960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// LookupFileCache - This is keeps track of each lookup performed by
1479960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// LookupFile.  The first part of the value is the starting index in
1489960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// SearchDirs that the cached search was performed from.  If there is a hit
1499960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// and this value doesn't match the current query, the cache has to be
1509960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// ignored.  The second value is the entry in SearchDirs that satisfied the
1519960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner  /// query.
152d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek  llvm::StringMap<std::pair<unsigned, unsigned>, llvm::BumpPtrAllocator>
153d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek    LookupFileCache;
1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// FrameworkMap - This is a collection mapping a framework or subframework
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// name like "Carbon" to the Carbon.framework directory.
157d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek  llvm::StringMap<const DirectoryEntry *, llvm::BumpPtrAllocator>
158d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek    FrameworkMap;
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
161822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// headermaps.  This vector owns the headermap.
162822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
1638c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
164a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief The mapping between modules and headers.
165a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  ModuleMap ModMap;
166a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor
167a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief Describes whether a given directory has a module map in it.
168a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
169a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor
17065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Uniqued set of framework names, which is used to track which
17165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// headers were included as framework headers.
17265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
17365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
1748c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// \brief Entity used to resolve the identifier IDs of controlling
1758c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// macros into IdentifierInfo pointers, as needed.
1768c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  ExternalIdentifierLookup *ExternalLookup;
1778c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
178cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Entity used to look up stored header file information.
179cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ExternalHeaderFileInfoSource *ExternalSource;
180cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Various statistics we track for performance analysis.
1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumIncluded;
1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumMultiIncludeFileOptzn;
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumFrameworkLookups, NumSubFrameworkLookups;
18549c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff
18649c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff  // HeaderSearch doesn't support default or copy construction.
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  explicit HeaderSearch();
18849c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff  explicit HeaderSearch(const HeaderSearch&);
18949c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff  void operator=(const HeaderSearch&);
1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
1918e23806863721495f9e1f84aed614f7afba774a3Douglas Gregor  HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags);
192822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  ~HeaderSearch();
1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FileManager &getFileMgr() const { return FileMgr; }
1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// SetSearchPaths - Interface for setting the file search paths.
1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
19974a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber                      unsigned angledDirIdx, unsigned systemDirIdx,
20074a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber                      bool noCurDirSearch) {
20174a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
20274a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber        "Directory indicies are unordered");
2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SearchDirs = dirs;
20474a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    AngledDirIdx = angledDirIdx;
2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SystemDirIdx = systemDirIdx;
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NoCurDirSearch = noCurDirSearch;
2079960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner    //LookupFileCache.clear();
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2101c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor  /// AddSearchPath - Add an additional search path.
2111c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor  void AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
2121c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
2131c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    SearchDirs.insert(SearchDirs.begin() + idx, dir);
2141c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    if (!isAngled)
2151c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor      AngledDirIdx++;
2161c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    SystemDirIdx++;
2171c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor  }
2181c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor
219fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  /// \brief Set the path to the module cache and the name of the module
220fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  /// we're building
221fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  void configureModules(StringRef CachePath, StringRef BuildingModule) {
222fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor    ModuleCachePath = CachePath;
223fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor    this->BuildingModule = BuildingModule;
2249a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  }
2259a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
226db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \brief Retrieve the path to the module cache.
227db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  StringRef getModuleCachePath() const { return ModuleCachePath; }
228db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor
2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ClearFileInfo - Forget everything we know about headers so far.
2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ClearFileInfo() {
2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    FileInfo.clear();
2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2348c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  void SetExternalLookup(ExternalIdentifierLookup *EIL) {
2358c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor    ExternalLookup = EIL;
2368c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  }
2378c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
238cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ExternalIdentifierLookup *getExternalLookup() const {
239cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor    return ExternalLookup;
240cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
241cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
242cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Set the external source of header information.
243cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
244cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor    ExternalSource = ES;
245cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
246cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
2475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
2487412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// return null on failure.
2497412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2507412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
2517412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// the file was found in, or null if not applicable.
2527412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2537412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param isAngled indicates whether the file reference is a <> reference.
2547412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2557412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param CurDir If non-null, the file was found in the specified directory
2567412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// search location.  This is used to implement #include_next.
2577412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2587412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param CurFileEnt If non-null, indicates where the #including file is, in
2597412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// case a relative search is needed.
2607412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2617412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param SearchPath If non-null, will be set to the search path relative
2627412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// to which the file was found. If the include path is absolute, SearchPath
2637412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// will be set to an empty string.
2647412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
2657412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param RelativePath If non-null, will be set to the path relative to
2667412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// SearchPath at which the file was found. This only differs from the
2677412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// Filename for framework includes.
268fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  ///
269fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  /// \param SuggestedModule If non-null, and the file found is semantically
270c69c42e939e6bdaa56d162cc36da4f6b6c53e8dbDouglas Gregor  /// part of a known module, this will be set to the module that should
271c69c42e939e6bdaa56d162cc36da4f6b6c53e8dbDouglas Gregor  /// be imported instead of preprocessing/parsing the file found.
272686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  const FileEntry *LookupFile(StringRef Filename, bool isAngled,
2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              const DirectoryLookup *FromDir,
2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              const DirectoryLookup *&CurDir,
275b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth                              const FileEntry *CurFileEnt,
276686775deca8b8685eb90801495880e3abdd844c2Chris Lattner                              SmallVectorImpl<char> *SearchPath,
277fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor                              SmallVectorImpl<char> *RelativePath,
2781c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor                              ModuleMap::Module **SuggestedModule,
2791c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor                              bool SkipCache = false);
2801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// LookupSubframeworkHeader - Look up a subframework for the specified
2825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// #include file.  For example, if #include'ing <HIToolbox/HIToolbox.h> from
2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// is a subframework within Carbon.framework.  If so, return the FileEntry
2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// for the designated file, otherwise return null.
286b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth  const FileEntry *LookupSubframeworkHeader(
287686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      StringRef Filename,
288b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth      const FileEntry *RelativeFileEnt,
289686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      SmallVectorImpl<char> *SearchPath,
290686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      SmallVectorImpl<char> *RelativePath);
2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
292afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  /// LookupFrameworkCache - Look up the specified framework name in our
293afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  /// framework cache, returning the DirectoryEntry it is in if we know,
294afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  /// otherwise, return null.
295686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  const DirectoryEntry *&LookupFrameworkCache(StringRef FWName) {
296a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner    return FrameworkMap.GetOrCreateValue(FWName).getValue();
297afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  }
2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ShouldEnterIncludeFile - Mark the specified file as a target of of a
3005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// #include, #include_next, or #import directive.  Return false if #including
3015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// the file will have no effect or true if we should include it.
3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
3031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getFileDirFlavor - Return whether the specified file is a normal header,
3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// a system header, or a C++ friendly system header.
3079d72851fec9e9c62570a027d42701562bbf29751Chris Lattner  SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
3089d72851fec9e9c62570a027d42701562bbf29751Chris Lattner    return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
3095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.
3125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// due to #pragma once.
3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void MarkFileIncludeOnce(const FileEntry *File) {
314dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    HeaderFileInfo &FI = getFileInfo(File);
315dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    FI.isImport = true;
316dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    FI.isPragmaOnce = true;
3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
319e9eb3f88b82176d8a43f7856250efded80cb2504Daniel Dunbar  /// MarkFileSystemHeader - Mark the specified file as a system header, e.g.
3205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// due to #pragma GCC system_header.
3215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void MarkFileSystemHeader(const FileEntry *File) {
3220b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner    getFileInfo(File).DirInfo = SrcMgr::C_System;
3235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
32525bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  /// IncrementIncludeCount - Increment the count for the number of times the
32625bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  /// specified FileEntry has been entered.
32725bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  void IncrementIncludeCount(const FileEntry *File) {
32825bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner    ++getFileInfo(File).NumIncludes;
32925bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  }
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// SetFileControllingMacro - Mark the specified file as having a controlling
3325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// macro.  This is used by the multiple-include optimization to eliminate
3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// no-op #includes.
3345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void SetFileControllingMacro(const FileEntry *File,
3355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               const IdentifierInfo *ControllingMacro) {
3365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    getFileInfo(File).ControllingMacro = ControllingMacro;
3375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
339dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// \brief Determine whether this file is intended to be safe from
340dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// multiple inclusions, e.g., it has #pragma once or a controlling
341dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// macro.
342dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  ///
343dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// This routine does not consider the effect of #import
344dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  bool isFileMultipleIncludeGuarded(const FileEntry *File);
345dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor
346822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// CreateHeaderMap - This method returns a HeaderMap for the specified
347822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
3481bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner  const HeaderMap *CreateHeaderMap(const FileEntry *FE);
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3509a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// \brief Search in the module cache path for a module with the given
3519a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// name.
3529a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  ///
3536e975c4517958bcc11c834336d340797356058dbDouglas Gregor  /// \param If non-NULL, will be set to the module file name we expected to
3546e975c4517958bcc11c834336d340797356058dbDouglas Gregor  /// find (regardless of whether it was actually found or not).
3556e975c4517958bcc11c834336d340797356058dbDouglas Gregor  ///
35621cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  /// \param UmbrellaHeader If non-NULL, and no module was found in the module
35721cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  /// cache, this routine will search in the framework paths to determine
35821cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  /// whether a module can be built from an umbrella header. If so, the pointee
35921cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  /// will be set to the path of the umbrella header.
36021cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  ///
3619a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// \returns A file describing the named module, if available, or NULL to
3629a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// indicate that the module could not be found.
36321cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor  const FileEntry *lookupModule(StringRef ModuleName,
3646e975c4517958bcc11c834336d340797356058dbDouglas Gregor                                std::string *ModuleFileName = 0,
36521cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor                                std::string *UmbrellaHeader = 0);
3669a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
367afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
36883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
369a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief Determine whether there is a module map that may map the header
370a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// with the given file name to a (sub)module.
371a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  ///
372a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \param Filename The name of the file.
373a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  ///
374a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \param Root The "root" directory, at which we should stop looking for
375a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// module maps.
376a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root);
377a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor
378a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief Retrieve the module that corresponds to the given file, if any.
379c69c42e939e6bdaa56d162cc36da4f6b6c53e8dbDouglas Gregor  ModuleMap::Module *findModuleForHeader(const FileEntry *File);
380a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor
381db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor
382db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \brief Read the contents of the given module map file.
383db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  ///
384db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \param File The module map file.
385db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  ///
386db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \param OnlyModule If non-NULL, this will receive the
387db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  ///
388db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \returns true if an error occurred, false otherwise.
389db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  bool loadModuleMapFile(const FileEntry *File);
390db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor
391db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \brief Retrieve a module with the given name.
392db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  ///
393db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \param Name The name of the module to retrieve.
394db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  ///
395db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \param AllowSearch If true, we're allowed to look for module maps within
396db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// the header search path. Otherwise, the module must already be known.
397db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  ///
398db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \returns The module, if found; otherwise, null.
399db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  ModuleMap::Module *getModule(StringRef Name, bool AllowSearch = true);
4002821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor
4012821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \brief Retrieve a module with the given name, which may be part of the
4022821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// given framework.
4032821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ///
4042821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \param Name The name of the module to retrieve.
4052821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ///
4062821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \param Dir The framework directory (e.g., ModuleName.framework).
4072821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ///
4082821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \returns The module, if found; otherwise, null.
4092821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ModuleMap::Module *getFrameworkModule(StringRef Name,
4102821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor                                        const DirectoryEntry *Dir);
4112821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor
4122821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \brief Retrieve the module map.
4132821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ModuleMap &getModuleMap() { return ModMap; }
414db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor
41512fab31aa5868b1a6b52246b5a87daa48a338fe2Douglas Gregor  unsigned header_file_size() const { return FileInfo.size(); }
41683d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
417c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl  // Used by ASTReader.
41883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
4191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
420590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis  /// getFileInfo - Return the HeaderFileInfo structure for the specified
421590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis  /// FileEntry.
422590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis  const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
423590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis    return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
424590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis  }
425590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis
426ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  // Used by external tools
427ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
428ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
429ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
430ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  unsigned search_dir_size() const { return SearchDirs.size(); }
431ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor
43274a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator quoted_dir_begin() const {
43374a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin();
43474a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
43574a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator quoted_dir_end() const {
43674a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + AngledDirIdx;
43774a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
43874a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber
43974a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator angled_dir_begin() const {
44074a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + AngledDirIdx;
44174a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
44274a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator angled_dir_end() const {
44374a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + SystemDirIdx;
44474a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
44574a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber
446ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator system_dir_begin() const {
447ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor    return SearchDirs.begin() + SystemDirIdx;
448ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  }
449ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
450ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor
45165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Retrieve a uniqued framework name.
45265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  StringRef getUniqueFrameworkName(StringRef Framework);
45365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
4545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void PrintStats();
455d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek
456d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek  size_t getTotalMemory() const;
457d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek
4585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
45926697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \brief Describes what happened when we tried to load a module map file.
46026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  enum LoadModuleMapResult {
46126697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief The module map file had already been loaded.
46226697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_AlreadyLoaded,
46326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief The module map file was loaded by this invocation.
46426697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_NewlyLoaded,
46526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief There is was directory with the given name.
46626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_NoDirectory,
46726697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief There was either no module map file or the module map file was
46826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// invalid.
46926697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_InvalidModuleMap
47026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  };
47126697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor
472cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  /// \brief Try to load the module map file in the given directory.
473cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  ///
47426697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \param DirName The name of the directory where we will look for a module
47526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// map file.
47626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  ///
47726697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \returns The result of attempting to load the module map file from the
47826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// named directory.
47926697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  LoadModuleMapResult loadModuleMapFile(StringRef DirName);
480cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor
481cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  /// \brief Try to load the module map file in the given directory.
482cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  ///
48326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \param Dir The directory where we will look for a module map file.
48426697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  ///
48526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \returns The result of attempting to load the module map file from the
48626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// named directory.
48726697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir);
4881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48983d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// getFileInfo - Return the HeaderFileInfo structure for the specified
4905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// FileEntry.
49183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  HeaderFileInfo &getFileInfo(const FileEntry *FE);
4925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
4935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end namespace clang
4955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
497