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"
19f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith#include "llvm/ADT/ArrayRef.h"
20c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor#include "llvm/ADT/IntrusiveRefCntPtr.h"
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h"
2265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor#include "llvm/ADT/StringSet.h"
23d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek#include "llvm/Support/Allocator.h"
24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <memory>
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <vector>
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
288e23806863721495f9e1f84aed614f7afba774a3Douglas Gregor
298e23806863721495f9e1f84aed614f7afba774a3Douglas Gregorclass DiagnosticsEngine;
308c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorclass ExternalIdentifierLookup;
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileEntry;
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileManager;
33c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregorclass HeaderSearchOptions;
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo;
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
36a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett/// \brief The preprocessor keeps track of this information for each
37809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett/// file that is \#included.
3883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroffstruct HeaderFileInfo {
39a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief True if this is a \#import'd or \#pragma once file.
40cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned isImport : 1;
411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief True if this is a \#pragma once file.
43dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  unsigned isPragmaOnce : 1;
44dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor
4583d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// DirInfo - Keep track of whether this is a system header, and if so,
4683d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// whether it is C++ clean or not.  This can be set by the include paths or
47a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// by \#pragma gcc system_header.  This is an instance of
4883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// SrcMgr::CharacteristicKind.
4983d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  unsigned DirInfo : 2;
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
51cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Whether this header file info was supplied by an external source.
52cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned External : 1;
5355ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis
5455ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis  /// \brief Whether this header is part of a module.
5555ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis  unsigned isModuleHeader : 1;
56d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis
57d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis  /// \brief Whether this header is part of the module that we are building.
58d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis  unsigned isCompilingModuleHeader : 1;
59bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl
60bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  /// \brief Whether this header is part of the module that we are building.
61bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  /// This is an instance of ModuleMap::ModuleHeaderRole.
62bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  unsigned HeaderRole : 2;
63cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
64cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Whether this structure is considered to already have been
65cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// "resolved", meaning that it was loaded from the external source.
66cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned Resolved : 1;
67cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
6865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Whether this is a header inside a framework that is currently
6965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// being built.
7065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  ///
7165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// When a framework is being built, the headers have not yet been placed
7265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// into the appropriate framework subdirectories, and therefore are
7365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// provided via a header map. This bit indicates when this is one of
7465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// those framework headers.
7565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  unsigned IndexHeaderMapHeader : 1;
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Whether this file had been looked up as a header.
78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned IsValid : 1;
7965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
80a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief The number of times the file has been included already.
8183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  unsigned short NumIncludes;
821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
83cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief The ID number of the controlling macro.
84cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ///
85cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// This ID number will be non-zero when there is a controlling
86cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// macro whose IdentifierInfo may not yet have been loaded from
87cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// external storage.
88cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned ControllingMacroID;
89cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
90a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// If this file has a \#ifndef XXX (or equivalent) guard that
91a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// protects the entire contents of the file, this is the identifier
9283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// for the macro that controls whether or not it has any effect.
938c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  ///
948c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// Note: Most clients should use getControllingMacro() to access
958c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// the controlling macro of this header, since
968c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// getControllingMacro() is able to load a controlling macro from
978c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// external storage.
9883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  const IdentifierInfo *ControllingMacro;
998c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
10065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief If this header came from a framework include, this is the name
10165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// of the framework.
10265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  StringRef Framework;
10365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  HeaderFileInfo()
105dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
106d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis      External(false), isModuleHeader(false), isCompilingModuleHeader(false),
107bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl      HeaderRole(ModuleMap::NormalHeader),
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Resolved(false), IndexHeaderMapHeader(false), IsValid(0),
1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      NumIncludes(0), ControllingMacroID(0), ControllingMacro(nullptr)  {}
1108c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
1118c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// \brief Retrieve the controlling macro for this header file, if
1128c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// any.
1138c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
114cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
115cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Determine whether this is a non-default header file info, e.g.,
116cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// it corresponds to an actual header we've included or tried to include.
117cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  bool isNonDefault() const {
118dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    return isImport || isPragmaOnce || NumIncludes || ControllingMacro ||
119dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor      ControllingMacroID;
120cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
121bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl
122bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  /// \brief Get the HeaderRole properly typed.
123bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  ModuleMap::ModuleHeaderRole getHeaderRole() const {
124bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl    return static_cast<ModuleMap::ModuleHeaderRole>(HeaderRole);
125bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  }
126bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl
127bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  /// \brief Set the HeaderRole properly typed.
128bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  void setHeaderRole(ModuleMap::ModuleHeaderRole Role) {
129bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl    HeaderRole = Role;
130bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  }
13183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff};
13283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
133cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor/// \brief An external source of header file information, which may supply
134cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor/// information about header files already included.
135cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregorclass ExternalHeaderFileInfoSource {
136cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregorpublic:
137cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  virtual ~ExternalHeaderFileInfoSource();
138cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
139cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Retrieve the header file information for the given file entry.
140cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ///
141cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \returns Header file information for the given file entry, with the
142cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \c External bit set. If the file entry is not known, return a
143cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// default-constructed \c HeaderFileInfo.
144cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
145cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor};
146cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
147a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett/// \brief Encapsulates the information needed to find the file referenced
148a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett/// by a \#include or \#include_next, (sub-)framework lookup, etc.
1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass HeaderSearch {
1509ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar  /// This structure is used to record entries in our framework cache.
1519ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar  struct FrameworkCacheEntry {
1529ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar    /// The directory entry which should be used for the cached framework.
1539ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar    const DirectoryEntry *Directory;
15485ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar
15585ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar    /// Whether this framework has been "user-specified" to be treated as if it
15685ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar    /// were a system framework (even if it was found outside a system framework
15785ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar    /// directory).
15885ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar    bool IsUserSpecifiedSystemFramework;
1599ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar  };
1609ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar
161c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor  /// \brief Header-search options used to initialize this header search.
162cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
163c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  DiagnosticsEngine &Diags;
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FileManager &FileMgr;
166a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \#include search path information.  Requests for \#include "x" search the
167a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// directory of the \#including file first, then each directory in SearchDirs
16874a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  /// consecutively. Requests for <x> search the current dir first, then each
16974a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  /// directory in SearchDirs, starting at AngledDirIdx, consecutively.  If
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// NoCurDirSearch is true, then the check for the file in the current
171fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner  /// directory is suppressed.
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  std::vector<DirectoryLookup> SearchDirs;
17374a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  unsigned AngledDirIdx;
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned SystemDirIdx;
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool NoCurDirSearch;
1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
177a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief \#include prefixes for which the 'system header' property is
178a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// overridden.
179a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  ///
180a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// For a \#include "x" or \#include \<x> directive, the last string in this
181f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith  /// list which is a prefix of 'x' determines whether the file is treated as
182f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith  /// a system header.
183f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith  std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
184f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith
1859a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// \brief The path to the module cache.
1869a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  std::string ModuleCachePath;
1879a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
188a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief All of the preprocessor-specific data about files that are
189a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// included, indexed by the FileEntry's UID.
19083d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  std::vector<HeaderFileInfo> FileInfo;
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Keeps track of each lookup performed by LookupFile.
193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct LookupFileCacheInfo {
194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// Starting index in SearchDirs that the cached search was performed from.
195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// If there is a hit and this value doesn't match the current query, the
196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// cache has to be ignored.
197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    unsigned StartIdx;
198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// The entry in SearchDirs that satisfied the query.
199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    unsigned HitIdx;
200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// This is non-null if the original filename was mapped to a framework
201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// include via a headermap.
202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    const char *MappedName;
203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// Default constructor -- Initialize all members with zero.
205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    LookupFileCacheInfo(): StartIdx(0), HitIdx(0), MappedName(nullptr) {}
206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void reset(unsigned StartIdx) {
208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      this->StartIdx = StartIdx;
209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      this->MappedName = nullptr;
210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache;
2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
214a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Collection mapping a framework or subframework
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// name like "Carbon" to the Carbon.framework directory.
2169ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar  llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap;
2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2184c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// IncludeAliases - maps include file names (including the quotes or
2194c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// angle brackets) to other include file names.  This is used to support the
2204c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// include_alias pragma for Microsoft compatibility.
2214c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator>
2224c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    IncludeAliasMap;
223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<IncludeAliasMap> IncludeAliases;
2244c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
2251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
226822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// headermaps.  This vector owns the headermap.
227822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
2288c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
229a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief The mapping between modules and headers.
23055ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis  mutable ModuleMap ModMap;
231a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor
232a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief Describes whether a given directory has a module map in it.
233a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
234176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
235176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \brief Set of module map files we've already loaded, and a flag indicating
236176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// whether they were valid or not.
237176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps;
238176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
23965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Uniqued set of framework names, which is used to track which
24065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// headers were included as framework headers.
24165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
24265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
2438c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// \brief Entity used to resolve the identifier IDs of controlling
2448c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// macros into IdentifierInfo pointers, as needed.
2458c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  ExternalIdentifierLookup *ExternalLookup;
2468c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
247cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Entity used to look up stored header file information.
248cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ExternalHeaderFileInfoSource *ExternalSource;
249cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Various statistics we track for performance analysis.
2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumIncluded;
2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumMultiIncludeFileOptzn;
2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumFrameworkLookups, NumSubFrameworkLookups;
25449c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff
2550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  const LangOptions &LangOpts;
256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
25749c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff  // HeaderSearch doesn't support default or copy construction.
2580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  HeaderSearch(const HeaderSearch&) = delete;
2590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void operator=(const HeaderSearch&) = delete;
260be2fa7ebf01259b63dc52fe46c8d101c18e72269Craig Topper
261e434ec71fccfe078906403affd641f709702d598Douglas Gregor  friend class DirectoryLookup;
262e434ec71fccfe078906403affd641f709702d598Douglas Gregor
2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
264cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
265ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek               SourceManager &SourceMgr, DiagnosticsEngine &Diags,
266dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor               const LangOptions &LangOpts, const TargetInfo *Target);
267822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  ~HeaderSearch();
2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
269c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor  /// \brief Retrieve the header-search options with which this header search
270c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor  /// was initialized.
271c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor  HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; }
272c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor
2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FileManager &getFileMgr() const { return FileMgr; }
2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
275a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Interface for setting the file search paths.
2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
27774a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber                      unsigned angledDirIdx, unsigned systemDirIdx,
27874a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber                      bool noCurDirSearch) {
27974a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
28074a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber        "Directory indicies are unordered");
2815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SearchDirs = dirs;
28274a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    AngledDirIdx = angledDirIdx;
2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SystemDirIdx = systemDirIdx;
2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NoCurDirSearch = noCurDirSearch;
2859960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner    //LookupFileCache.clear();
2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
288a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Add an additional search path.
2891c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor  void AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
2901c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
2911c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    SearchDirs.insert(SearchDirs.begin() + idx, dir);
2921c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    if (!isAngled)
2931c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor      AngledDirIdx++;
2941c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    SystemDirIdx++;
2951c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor  }
2961c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor
297a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Set the list of system header prefixes.
298f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith  void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool> > P) {
299f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith    SystemHeaderPrefixes.assign(P.begin(), P.end());
300f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith  }
301f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith
302a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Checks whether the map exists or not.
303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool HasIncludeAliasMap() const { return (bool)IncludeAliases; }
3044c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
305a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Map the source include name to the dest include name.
306a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  ///
3074c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// The Source should include the angle brackets or quotes, the dest
3084c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// should not.  This allows for distinction between <> and "" headers.
3094c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  void AddIncludeAlias(StringRef Source, StringRef Dest) {
3104c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (!IncludeAliases)
3114c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      IncludeAliases.reset(new IncludeAliasMap);
3124c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    (*IncludeAliases)[Source] = Dest;
3134c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
3144c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
3154c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// MapHeaderToIncludeAlias - Maps one header file name to a different header
3164c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// file name, for use with the include_alias pragma.  Note that the source
3174c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// file name should include the angle brackets or quotes.  Returns StringRef
3184c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// as null if the header cannot be mapped.
3194c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef MapHeaderToIncludeAlias(StringRef Source) {
3204c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    assert(IncludeAliases && "Trying to map headers when there's no map");
3214c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
3224c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // Do any filename replacements before anything else
3234c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source);
3244c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (Iter != IncludeAliases->end())
3254c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      return Iter->second;
3264c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return StringRef();
3274c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
3284c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
3295e3f9223db88227d6d21679c613b139d8160186dDouglas Gregor  /// \brief Set the path to the module cache.
3305e3f9223db88227d6d21679c613b139d8160186dDouglas Gregor  void setModuleCachePath(StringRef CachePath) {
331fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor    ModuleCachePath = CachePath;
3329a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  }
3339a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
334db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \brief Retrieve the path to the module cache.
335db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  StringRef getModuleCachePath() const { return ModuleCachePath; }
3361ecf0e6e271f3046bc53264318c47eae0fb80afdAxel Naumann
3371ecf0e6e271f3046bc53264318c47eae0fb80afdAxel Naumann  /// \brief Consider modules when including files from this directory.
3381ecf0e6e271f3046bc53264318c47eae0fb80afdAxel Naumann  void setDirectoryHasModuleMap(const DirectoryEntry* Dir) {
3391ecf0e6e271f3046bc53264318c47eae0fb80afdAxel Naumann    DirectoryHasModuleMap[Dir] = true;
3401ecf0e6e271f3046bc53264318c47eae0fb80afdAxel Naumann  }
341db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor
342a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Forget everything we know about headers so far.
3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ClearFileInfo() {
3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    FileInfo.clear();
3455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3478c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  void SetExternalLookup(ExternalIdentifierLookup *EIL) {
3488c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor    ExternalLookup = EIL;
3498c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  }
3508c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
351cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ExternalIdentifierLookup *getExternalLookup() const {
352cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor    return ExternalLookup;
353cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
354cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
355cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Set the external source of header information.
356cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
357cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor    ExternalSource = ES;
358cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
359cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
360dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor  /// \brief Set the target information for the header search, if not
361dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor  /// already known.
362dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor  void setTarget(const TargetInfo &Target);
363dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor
364198129e24b56ffcc85f66e798d52a8614e3a07a4James Dennett  /// \brief Given a "foo" or \<foo> reference, look up the indicated file,
3657412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// return null on failure.
3667412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
3677412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
3687412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// the file was found in, or null if not applicable.
3697412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \param IncludeLoc Used for diagnostics if valid.
371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///
3727412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param isAngled indicates whether the file reference is a <> reference.
3737412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
3747412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param CurDir If non-null, the file was found in the specified directory
375a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// search location.  This is used to implement \#include_next.
3767412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \param Includers Indicates where the \#including file(s) are, in case
378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// relative searches are needed. In reverse order of inclusion.
3797412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
3807412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param SearchPath If non-null, will be set to the search path relative
3817412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// to which the file was found. If the include path is absolute, SearchPath
3827412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// will be set to an empty string.
3837412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
3847412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param RelativePath If non-null, will be set to the path relative to
3857412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// SearchPath at which the file was found. This only differs from the
3867412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// Filename for framework includes.
387fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  ///
388fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  /// \param SuggestedModule If non-null, and the file found is semantically
389c69c42e939e6bdaa56d162cc36da4f6b6c53e8dbDouglas Gregor  /// part of a known module, this will be set to the module that should
390c69c42e939e6bdaa56d162cc36da4f6b6c53e8dbDouglas Gregor  /// be imported instead of preprocessing/parsing the file found.
391176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const FileEntry *LookupFile(
392176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
393176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
394176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
395176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
396176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      ModuleMap::KnownHeader *SuggestedModule, bool SkipCache = false);
3971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
398a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Look up a subframework for the specified \#include file.
399a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  ///
400a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// For example, if \#include'ing <HIToolbox/HIToolbox.h> from
401a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// within ".../Carbon.framework/Headers/Carbon.h", check to see if
402a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// HIToolbox is a subframework within Carbon.framework.  If so, return
403a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// the FileEntry for the designated file, otherwise return null.
404b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth  const FileEntry *LookupSubframeworkHeader(
405686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      StringRef Filename,
406b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth      const FileEntry *RelativeFileEnt,
407686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      SmallVectorImpl<char> *SearchPath,
4081b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor      SmallVectorImpl<char> *RelativePath,
409bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl      ModuleMap::KnownHeader *SuggestedModule);
4101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
411a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Look up the specified framework name in our framework cache.
412a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \returns The DirectoryEntry it is in if we know, null otherwise.
4139ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar  FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) {
414176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return FrameworkMap[FWName];
415afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  }
4161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
417a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Mark the specified file as a target of of a \#include,
418a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \#include_next, or \#import directive.
419a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  ///
420a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \return false if \#including the file will have no effect or true
421a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// if we should include it.
4225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
4231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
425a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Return whether the specified file is a normal header,
4265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// a system header, or a C++ friendly system header.
4279d72851fec9e9c62570a027d42701562bbf29751Chris Lattner  SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
4289d72851fec9e9c62570a027d42701562bbf29751Chris Lattner    return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
4295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
431a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Mark the specified file as a "once only" file, e.g. due to
432a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \#pragma once.
4335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void MarkFileIncludeOnce(const FileEntry *File) {
434dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    HeaderFileInfo &FI = getFileInfo(File);
435dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    FI.isImport = true;
436dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    FI.isPragmaOnce = true;
4375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
439a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Mark the specified file as a system header, e.g. due to
440a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \#pragma GCC system_header.
4415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void MarkFileSystemHeader(const FileEntry *File) {
4420b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner    getFileInfo(File).DirInfo = SrcMgr::C_System;
4435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44555ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis  /// \brief Mark the specified file as part of a module.
446bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  void MarkFileModuleHeader(const FileEntry *File,
447bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl                            ModuleMap::ModuleHeaderRole Role,
448bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl                            bool IsCompiledModuleHeader);
44955ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis
450a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Increment the count for the number of times the specified
451a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// FileEntry has been entered.
45225bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  void IncrementIncludeCount(const FileEntry *File) {
45325bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner    ++getFileInfo(File).NumIncludes;
45425bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  }
4551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
456a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Mark the specified file as having a controlling macro.
457a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  ///
458a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// This is used by the multiple-include optimization to eliminate
459809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett  /// no-op \#includes.
4605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void SetFileControllingMacro(const FileEntry *File,
4615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               const IdentifierInfo *ControllingMacro) {
4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    getFileInfo(File).ControllingMacro = ControllingMacro;
4635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
465671538e8a51eab5bd65a1f9f327ba7f44f84e486Richard Trieu  /// \brief Return true if this is the first time encountering this header.
466671538e8a51eab5bd65a1f9f327ba7f44f84e486Richard Trieu  bool FirstTimeLexingFile(const FileEntry *File) {
467671538e8a51eab5bd65a1f9f327ba7f44f84e486Richard Trieu    return getFileInfo(File).NumIncludes == 1;
468671538e8a51eab5bd65a1f9f327ba7f44f84e486Richard Trieu  }
469671538e8a51eab5bd65a1f9f327ba7f44f84e486Richard Trieu
470dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// \brief Determine whether this file is intended to be safe from
471809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett  /// multiple inclusions, e.g., it has \#pragma once or a controlling
472dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// macro.
473dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  ///
474809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett  /// This routine does not consider the effect of \#import
475dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  bool isFileMultipleIncludeGuarded(const FileEntry *File);
476dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor
477822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// CreateHeaderMap - This method returns a HeaderMap for the specified
478bed28ac1d1463adca3ecf24fca5c30646fa9dbb2Sylvestre Ledru  /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
4791bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner  const HeaderMap *CreateHeaderMap(const FileEntry *FE);
4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
481651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Returns true if modules are enabled.
4820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  bool enabledModules() const { return LangOpts.Modules; }
483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
484e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \brief Retrieve the name of the module file that should be used to
485e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// load the given module.
4869a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  ///
487e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \param Module The module whose module file name will be returned.
488a4d36a6dd00c1495cfe3b64f949d70ba9f778391Douglas Gregor  ///
489e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \returns The name of the module file that corresponds to this module,
490e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// or an empty string if this module does not correspond to any module file.
491e434ec71fccfe078906403affd641f709702d598Douglas Gregor  std::string getModuleFileName(Module *Module);
492e434ec71fccfe078906403affd641f709702d598Douglas Gregor
493e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \brief Retrieve the name of the module file that should be used to
494e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// load a module with the given name.
4956e975c4517958bcc11c834336d340797356058dbDouglas Gregor  ///
496efce31f51d6e7e31e125f96c20f6cdab3ead0a47James Dennett  /// \param ModuleName The module whose module file name will be returned.
497e434ec71fccfe078906403affd641f709702d598Douglas Gregor  ///
4986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \param ModuleMapPath A path that when combined with \c ModuleName
4996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// uniquely identifies this module. See Module::ModuleMap.
5006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ///
501e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \returns The name of the module file that corresponds to this module,
502e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// or an empty string if this module does not correspond to any module file.
5036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath);
504e434ec71fccfe078906403affd641f709702d598Douglas Gregor
505e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \brief Lookup a module Search for a module with the given name.
506e434ec71fccfe078906403affd641f709702d598Douglas Gregor  ///
507e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \param ModuleName The name of the module we're looking for.
508e434ec71fccfe078906403affd641f709702d598Douglas Gregor  ///
509e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \param AllowSearch Whether we are allowed to search in the various
510e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// search directories to produce a module definition. If not, this lookup
511e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// will only return an already-known module.
512e434ec71fccfe078906403affd641f709702d598Douglas Gregor  ///
513e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \returns The module with the given name.
514e434ec71fccfe078906403affd641f709702d598Douglas Gregor  Module *lookupModule(StringRef ModuleName, bool AllowSearch = true);
515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
516651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Try to find a module map file in the given directory, returning
517651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \c nullptr if none is found.
518651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const FileEntry *lookupModuleMapFile(const DirectoryEntry *Dir,
519651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                       bool IsFramework);
5209a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
521afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
52283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
523a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief Determine whether there is a module map that may map the header
524a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// with the given file name to a (sub)module.
525651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Always returns false if modules are disabled.
526a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  ///
527a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \param Filename The name of the file.
528a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  ///
529a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \param Root The "root" directory, at which we should stop looking for
530a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// module maps.
5318f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  ///
5328f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  /// \param IsSystem Whether the directories we're looking at are system
5338f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  /// header directories.
5348f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root,
5358f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor                    bool IsSystem);
536a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor
537a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief Retrieve the module that corresponds to the given file, if any.
53851f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor  ///
53951f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor  /// \param File The header that we wish to map to a module.
540bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl  ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File) const;
541a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor
542db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \brief Read the contents of the given module map file.
543db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  ///
544db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \param File The module map file.
5458f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  /// \param IsSystem Whether this file is in a system header directory.
546db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  ///
547db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \returns true if an error occurred, false otherwise.
5488f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  bool loadModuleMapFile(const FileEntry *File, bool IsSystem);
5492821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor
550c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor  /// \brief Collect the set of all known, top-level modules.
551c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor  ///
552c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor  /// \param Modules Will be filled with the set of known, top-level modules.
553cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  void collectAllModules(SmallVectorImpl<Module *> &Modules);
55430a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor
55530a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor  /// \brief Load all known, top-level system modules.
55630a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor  void loadTopLevelSystemModules();
55730a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor
558e434ec71fccfe078906403affd641f709702d598Douglas Gregorprivate:
5592821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \brief Retrieve a module with the given name, which may be part of the
5602821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// given framework.
5612821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ///
5622821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \param Name The name of the module to retrieve.
5632821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ///
5642821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \param Dir The framework directory (e.g., ModuleName.framework).
5652821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ///
566a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor  /// \param IsSystem Whether the framework directory is part of the system
567a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor  /// frameworks.
568a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor  ///
5692821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \returns The module, if found; otherwise, null.
570e434ec71fccfe078906403affd641f709702d598Douglas Gregor  Module *loadFrameworkModule(StringRef Name,
571e434ec71fccfe078906403affd641f709702d598Douglas Gregor                              const DirectoryEntry *Dir,
572e434ec71fccfe078906403affd641f709702d598Douglas Gregor                              bool IsSystem);
573cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor
574cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  /// \brief Load all of the module maps within the immediate subdirectories
575cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  /// of the given search directory.
576cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
577cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor
578651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
579651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
580651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
583e434ec71fccfe078906403affd641f709702d598Douglas Gregorpublic:
5842821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \brief Retrieve the module map.
5852821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ModuleMap &getModuleMap() { return ModMap; }
586db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor
58712fab31aa5868b1a6b52246b5a87daa48a338fe2Douglas Gregor  unsigned header_file_size() const { return FileInfo.size(); }
58883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Get a \c HeaderFileInfo structure for the specified \c FileEntry,
590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// if one exists.
591651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const;
592590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis
593ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  // Used by external tools
594ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
595ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
596ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
597ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  unsigned search_dir_size() const { return SearchDirs.size(); }
598ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor
59974a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator quoted_dir_begin() const {
60074a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin();
60174a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
60274a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator quoted_dir_end() const {
60374a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + AngledDirIdx;
60474a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
60574a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber
60674a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator angled_dir_begin() const {
60774a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + AngledDirIdx;
60874a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
60974a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator angled_dir_end() const {
61074a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + SystemDirIdx;
61174a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
61274a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber
613ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator system_dir_begin() const {
614ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor    return SearchDirs.begin() + SystemDirIdx;
615ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  }
616ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
617ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor
61865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Retrieve a uniqued framework name.
61965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  StringRef getUniqueFrameworkName(StringRef Framework);
62065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
6215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void PrintStats();
622d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek
623d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek  size_t getTotalMemory() const;
624d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek
625cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth  static std::string NormalizeDashIncludePath(StringRef File,
626cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth                                              FileManager &FileMgr);
627cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth
6285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
62926697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \brief Describes what happened when we tried to load a module map file.
63026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  enum LoadModuleMapResult {
63126697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief The module map file had already been loaded.
63226697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_AlreadyLoaded,
63326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief The module map file was loaded by this invocation.
63426697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_NewlyLoaded,
63526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief There is was directory with the given name.
63626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_NoDirectory,
63726697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief There was either no module map file or the module map file was
63826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// invalid.
63926697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_InvalidModuleMap
64026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  };
641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
642651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File,
6430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                            bool IsSystem,
6440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                            const DirectoryEntry *Dir);
645651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
646cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  /// \brief Try to load the module map file in the given directory.
647cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  ///
64826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \param DirName The name of the directory where we will look for a module
64926697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// map file.
6508f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  /// \param IsSystem Whether this is a system header directory.
651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \param IsFramework Whether this is a framework directory.
65226697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  ///
65326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \returns The result of attempting to load the module map file from the
65426697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// named directory.
655651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem,
656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        bool IsFramework);
657cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor
658cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  /// \brief Try to load the module map file in the given directory.
659cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  ///
66026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \param Dir The directory where we will look for a module map file.
6618f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  /// \param IsSystem Whether this is a system header directory.
662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \param IsFramework Whether this is a framework directory.
66326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  ///
66426697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \returns The result of attempting to load the module map file from the
66526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// named directory.
6668f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir,
667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        bool IsSystem, bool IsFramework);
6681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
669a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
67083d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  HeaderFileInfo &getFileInfo(const FileEntry *FE);
6715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
6725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end namespace clang
6745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
676