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"
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h"
2165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor#include "llvm/ADT/StringSet.h"
22d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek#include "llvm/Support/Allocator.h"
234c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman#include "llvm/ADT/OwningPtr.h"
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <vector>
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
278e23806863721495f9e1f84aed614f7afba774a3Douglas Gregor
288e23806863721495f9e1f84aed614f7afba774a3Douglas Gregorclass DiagnosticsEngine;
298c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorclass ExternalIdentifierLookup;
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileEntry;
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileManager;
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo;
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
34a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett/// \brief The preprocessor keeps track of this information for each
35809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett/// file that is \#included.
3683d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroffstruct HeaderFileInfo {
37a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief True if this is a \#import'd or \#pragma once file.
38cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned isImport : 1;
391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief True if this is a \#pragma once file.
41dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  unsigned isPragmaOnce : 1;
42dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor
4383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// DirInfo - Keep track of whether this is a system header, and if so,
4483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// whether it is C++ clean or not.  This can be set by the include paths or
45a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// by \#pragma gcc system_header.  This is an instance of
4683d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// SrcMgr::CharacteristicKind.
4783d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  unsigned DirInfo : 2;
481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Whether this header file info was supplied by an external source.
50cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned External : 1;
51cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
52cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Whether this structure is considered to already have been
53cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// "resolved", meaning that it was loaded from the external source.
54cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned Resolved : 1;
55cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
5665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Whether this is a header inside a framework that is currently
5765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// being built.
5865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  ///
5965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// When a framework is being built, the headers have not yet been placed
6065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// into the appropriate framework subdirectories, and therefore are
6165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// provided via a header map. This bit indicates when this is one of
6265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// those framework headers.
6365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  unsigned IndexHeaderMapHeader : 1;
6465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
65a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief The number of times the file has been included already.
6683d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  unsigned short NumIncludes;
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief The ID number of the controlling macro.
69cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ///
70cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// This ID number will be non-zero when there is a controlling
71cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// macro whose IdentifierInfo may not yet have been loaded from
72cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// external storage.
73cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  unsigned ControllingMacroID;
74cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
75a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// If this file has a \#ifndef XXX (or equivalent) guard that
76a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// protects the entire contents of the file, this is the identifier
7783d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  /// for the macro that controls whether or not it has any effect.
788c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  ///
798c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// Note: Most clients should use getControllingMacro() to access
808c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// the controlling macro of this header, since
818c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// getControllingMacro() is able to load a controlling macro from
828c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// external storage.
8383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  const IdentifierInfo *ControllingMacro;
848c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
8565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief If this header came from a framework include, this is the name
8665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// of the framework.
8765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  StringRef Framework;
8865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  HeaderFileInfo()
90dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
9165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor      External(false), Resolved(false), IndexHeaderMapHeader(false),
9265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor      NumIncludes(0), ControllingMacroID(0), ControllingMacro(0)  {}
938c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
948c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// \brief Retrieve the controlling macro for this header file, if
958c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// any.
968c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
97cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
98cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Determine whether this is a non-default header file info, e.g.,
99cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// it corresponds to an actual header we've included or tried to include.
100cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  bool isNonDefault() const {
101dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    return isImport || isPragmaOnce || NumIncludes || ControllingMacro ||
102dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor      ControllingMacroID;
103cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
10483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff};
10583d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
106cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor/// \brief An external source of header file information, which may supply
107cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor/// information about header files already included.
108cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregorclass ExternalHeaderFileInfoSource {
109cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregorpublic:
110cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  virtual ~ExternalHeaderFileInfoSource();
111cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
112cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Retrieve the header file information for the given file entry.
113cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ///
114cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \returns Header file information for the given file entry, with the
115cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \c External bit set. If the file entry is not known, return a
116cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// default-constructed \c HeaderFileInfo.
117cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
118cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor};
119cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
120a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett/// \brief Encapsulates the information needed to find the file referenced
121a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett/// by a \#include or \#include_next, (sub-)framework lookup, etc.
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass HeaderSearch {
1239ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar  /// This structure is used to record entries in our framework cache.
1249ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar  struct FrameworkCacheEntry {
1259ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar    /// The directory entry which should be used for the cached framework.
1269ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar    const DirectoryEntry *Directory;
12785ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar
12885ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar    /// Whether this framework has been "user-specified" to be treated as if it
12985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar    /// were a system framework (even if it was found outside a system framework
13085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar    /// directory).
13185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar    bool IsUserSpecifiedSystemFramework;
1329ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar  };
1339ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar
1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FileManager &FileMgr;
1358e23806863721495f9e1f84aed614f7afba774a3Douglas Gregor  DiagnosticsEngine &Diags;
136a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \#include search path information.  Requests for \#include "x" search the
137a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// directory of the \#including file first, then each directory in SearchDirs
13874a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  /// consecutively. Requests for <x> search the current dir first, then each
13974a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  /// directory in SearchDirs, starting at AngledDirIdx, consecutively.  If
1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// NoCurDirSearch is true, then the check for the file in the current
141fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner  /// directory is suppressed.
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  std::vector<DirectoryLookup> SearchDirs;
14374a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  unsigned AngledDirIdx;
1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned SystemDirIdx;
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool NoCurDirSearch;
1461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
147a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief \#include prefixes for which the 'system header' property is
148a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// overridden.
149a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  ///
150a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// For a \#include "x" or \#include \<x> directive, the last string in this
151f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith  /// list which is a prefix of 'x' determines whether the file is treated as
152f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith  /// a system header.
153f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith  std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
154f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith
1559a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  /// \brief The path to the module cache.
1569a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  std::string ModuleCachePath;
1579a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
158a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief All of the preprocessor-specific data about files that are
159a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// included, indexed by the FileEntry's UID.
16083d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  std::vector<HeaderFileInfo> FileInfo;
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
162a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Keeps track of each lookup performed by LookupFile.
163a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  ///
164a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// The first part of the value is the starting index in SearchDirs
165a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// that the cached search was performed from.  If there is a hit and
166a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// this value doesn't match the current query, the cache has to be
167a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// ignored.  The second value is the entry in SearchDirs that satisfied
168a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// the query.
169d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek  llvm::StringMap<std::pair<unsigned, unsigned>, llvm::BumpPtrAllocator>
170d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek    LookupFileCache;
1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
172a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Collection mapping a framework or subframework
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// name like "Carbon" to the Carbon.framework directory.
1749ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar  llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap;
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1764c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// IncludeAliases - maps include file names (including the quotes or
1774c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// angle brackets) to other include file names.  This is used to support the
1784c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// include_alias pragma for Microsoft compatibility.
1794c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator>
1804c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    IncludeAliasMap;
1814c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  OwningPtr<IncludeAliasMap> IncludeAliases;
1824c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
184822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// headermaps.  This vector owns the headermap.
185822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
1868c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
187a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief The mapping between modules and headers.
188a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  ModuleMap ModMap;
189a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor
190a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief Describes whether a given directory has a module map in it.
191a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
192a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor
19365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Uniqued set of framework names, which is used to track which
19465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// headers were included as framework headers.
19565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
19665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
1978c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// \brief Entity used to resolve the identifier IDs of controlling
1988c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  /// macros into IdentifierInfo pointers, as needed.
1998c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  ExternalIdentifierLookup *ExternalLookup;
2008c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
201cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Entity used to look up stored header file information.
202cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ExternalHeaderFileInfoSource *ExternalSource;
203cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Various statistics we track for performance analysis.
2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumIncluded;
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumMultiIncludeFileOptzn;
2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumFrameworkLookups, NumSubFrameworkLookups;
20849c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff
20949c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff  // HeaderSearch doesn't support default or copy construction.
2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  explicit HeaderSearch();
21149c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff  explicit HeaderSearch(const HeaderSearch&);
21249c1f4aa2a6c360d25d605004ec3c4affd62db77Steve Naroff  void operator=(const HeaderSearch&);
213e434ec71fccfe078906403affd641f709702d598Douglas Gregor
214e434ec71fccfe078906403affd641f709702d598Douglas Gregor  friend class DirectoryLookup;
215e434ec71fccfe078906403affd641f709702d598Douglas Gregor
2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
21751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor  HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags,
218dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor               const LangOptions &LangOpts, const TargetInfo *Target);
219822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  ~HeaderSearch();
2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  FileManager &getFileMgr() const { return FileMgr; }
2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
223a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Interface for setting the file search paths.
2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
22574a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber                      unsigned angledDirIdx, unsigned systemDirIdx,
22674a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber                      bool noCurDirSearch) {
22774a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
22874a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber        "Directory indicies are unordered");
2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SearchDirs = dirs;
23074a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    AngledDirIdx = angledDirIdx;
2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SystemDirIdx = systemDirIdx;
2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NoCurDirSearch = noCurDirSearch;
2339960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner    //LookupFileCache.clear();
2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
236a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Add an additional search path.
2371c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor  void AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
2381c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
2391c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    SearchDirs.insert(SearchDirs.begin() + idx, dir);
2401c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    if (!isAngled)
2411c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor      AngledDirIdx++;
2421c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor    SystemDirIdx++;
2431c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor  }
2441c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor
245a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Set the list of system header prefixes.
246f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith  void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool> > P) {
247f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith    SystemHeaderPrefixes.assign(P.begin(), P.end());
248f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith  }
249f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith
250a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Checks whether the map exists or not.
2514c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  bool HasIncludeAliasMap() const {
2524c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return IncludeAliases;
2534c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
2544c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
255a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Map the source include name to the dest include name.
256a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  ///
2574c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// The Source should include the angle brackets or quotes, the dest
2584c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// should not.  This allows for distinction between <> and "" headers.
2594c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  void AddIncludeAlias(StringRef Source, StringRef Dest) {
2604c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (!IncludeAliases)
2614c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      IncludeAliases.reset(new IncludeAliasMap);
2624c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    (*IncludeAliases)[Source] = Dest;
2634c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
2644c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
2654c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// MapHeaderToIncludeAlias - Maps one header file name to a different header
2664c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// file name, for use with the include_alias pragma.  Note that the source
2674c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// file name should include the angle brackets or quotes.  Returns StringRef
2684c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  /// as null if the header cannot be mapped.
2694c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  StringRef MapHeaderToIncludeAlias(StringRef Source) {
2704c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    assert(IncludeAliases && "Trying to map headers when there's no map");
2714c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
2724c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    // Do any filename replacements before anything else
2734c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source);
2744c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    if (Iter != IncludeAliases->end())
2754c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman      return Iter->second;
2764c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman    return StringRef();
2774c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman  }
2784c55c54db8e676aa3e042188773d9d82d59fff91Aaron Ballman
2795e3f9223db88227d6d21679c613b139d8160186dDouglas Gregor  /// \brief Set the path to the module cache.
2805e3f9223db88227d6d21679c613b139d8160186dDouglas Gregor  void setModuleCachePath(StringRef CachePath) {
281fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor    ModuleCachePath = CachePath;
2829a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  }
2839a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
284db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \brief Retrieve the path to the module cache.
285db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  StringRef getModuleCachePath() const { return ModuleCachePath; }
286db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor
287a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Forget everything we know about headers so far.
2885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ClearFileInfo() {
2895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    FileInfo.clear();
2905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2928c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  void SetExternalLookup(ExternalIdentifierLookup *EIL) {
2938c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor    ExternalLookup = EIL;
2948c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor  }
2958c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor
296cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  ExternalIdentifierLookup *getExternalLookup() const {
297cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor    return ExternalLookup;
298cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
299cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
300cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  /// \brief Set the external source of header information.
301cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
302cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor    ExternalSource = ES;
303cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor  }
304cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor
305dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor  /// \brief Set the target information for the header search, if not
306dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor  /// already known.
307dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor  void setTarget(const TargetInfo &Target);
308dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor
309198129e24b56ffcc85f66e798d52a8614e3a07a4James Dennett  /// \brief Given a "foo" or \<foo> reference, look up the indicated file,
3107412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// return null on failure.
3117412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
3127412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
3137412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// the file was found in, or null if not applicable.
3147412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
3157412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param isAngled indicates whether the file reference is a <> reference.
3167412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
3177412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param CurDir If non-null, the file was found in the specified directory
318a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// search location.  This is used to implement \#include_next.
3197412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
320a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \param CurFileEnt If non-null, indicates where the \#including file is, in
3217412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// case a relative search is needed.
3227412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
3237412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param SearchPath If non-null, will be set to the search path relative
3247412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// to which the file was found. If the include path is absolute, SearchPath
3257412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// will be set to an empty string.
3267412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
3277412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param RelativePath If non-null, will be set to the path relative to
3287412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// SearchPath at which the file was found. This only differs from the
3297412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// Filename for framework includes.
330fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  ///
331fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  /// \param SuggestedModule If non-null, and the file found is semantically
332c69c42e939e6bdaa56d162cc36da4f6b6c53e8dbDouglas Gregor  /// part of a known module, this will be set to the module that should
333c69c42e939e6bdaa56d162cc36da4f6b6c53e8dbDouglas Gregor  /// be imported instead of preprocessing/parsing the file found.
334686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  const FileEntry *LookupFile(StringRef Filename, bool isAngled,
3355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              const DirectoryLookup *FromDir,
3365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              const DirectoryLookup *&CurDir,
337b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth                              const FileEntry *CurFileEnt,
338686775deca8b8685eb90801495880e3abdd844c2Chris Lattner                              SmallVectorImpl<char> *SearchPath,
339fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor                              SmallVectorImpl<char> *RelativePath,
3401a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor                              Module **SuggestedModule,
3411c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor                              bool SkipCache = false);
3421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
343a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Look up a subframework for the specified \#include file.
344a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  ///
345a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// For example, if \#include'ing <HIToolbox/HIToolbox.h> from
346a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// within ".../Carbon.framework/Headers/Carbon.h", check to see if
347a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// HIToolbox is a subframework within Carbon.framework.  If so, return
348a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// the FileEntry for the designated file, otherwise return null.
349b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth  const FileEntry *LookupSubframeworkHeader(
350686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      StringRef Filename,
351b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth      const FileEntry *RelativeFileEnt,
352686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      SmallVectorImpl<char> *SearchPath,
353686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      SmallVectorImpl<char> *RelativePath);
3541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
355a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Look up the specified framework name in our framework cache.
356a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \returns The DirectoryEntry it is in if we know, null otherwise.
3579ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar  FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) {
358a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner    return FrameworkMap.GetOrCreateValue(FWName).getValue();
359afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  }
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
361a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Mark the specified file as a target of of a \#include,
362a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \#include_next, or \#import directive.
363a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  ///
364a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \return false if \#including the file will have no effect or true
365a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// if we should include it.
3665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
3671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
369a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Return whether the specified file is a normal header,
3705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// a system header, or a C++ friendly system header.
3719d72851fec9e9c62570a027d42701562bbf29751Chris Lattner  SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
3729d72851fec9e9c62570a027d42701562bbf29751Chris Lattner    return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
375a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Mark the specified file as a "once only" file, e.g. due to
376a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \#pragma once.
3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void MarkFileIncludeOnce(const FileEntry *File) {
378dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    HeaderFileInfo &FI = getFileInfo(File);
379dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    FI.isImport = true;
380dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    FI.isPragmaOnce = true;
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
383a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Mark the specified file as a system header, e.g. due to
384a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \#pragma GCC system_header.
3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void MarkFileSystemHeader(const FileEntry *File) {
3860b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner    getFileInfo(File).DirInfo = SrcMgr::C_System;
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
389a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Increment the count for the number of times the specified
390a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// FileEntry has been entered.
39125bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  void IncrementIncludeCount(const FileEntry *File) {
39225bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner    ++getFileInfo(File).NumIncludes;
39325bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner  }
3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
395a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Mark the specified file as having a controlling macro.
396a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  ///
397a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// This is used by the multiple-include optimization to eliminate
398809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett  /// no-op \#includes.
3995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void SetFileControllingMacro(const FileEntry *File,
4005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               const IdentifierInfo *ControllingMacro) {
4015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    getFileInfo(File).ControllingMacro = ControllingMacro;
4025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
404dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// \brief Determine whether this file is intended to be safe from
405809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett  /// multiple inclusions, e.g., it has \#pragma once or a controlling
406dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  /// macro.
407dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  ///
408809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett  /// This routine does not consider the effect of \#import
409dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  bool isFileMultipleIncludeGuarded(const FileEntry *File);
410dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor
411822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// CreateHeaderMap - This method returns a HeaderMap for the specified
412bed28ac1d1463adca3ecf24fca5c30646fa9dbb2Sylvestre Ledru  /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
4131bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner  const HeaderMap *CreateHeaderMap(const FileEntry *FE);
4141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
415e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \brief Retrieve the name of the module file that should be used to
416e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// load the given module.
4179a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor  ///
418e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \param Module The module whose module file name will be returned.
419a4d36a6dd00c1495cfe3b64f949d70ba9f778391Douglas Gregor  ///
420e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \returns The name of the module file that corresponds to this module,
421e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// or an empty string if this module does not correspond to any module file.
422e434ec71fccfe078906403affd641f709702d598Douglas Gregor  std::string getModuleFileName(Module *Module);
423e434ec71fccfe078906403affd641f709702d598Douglas Gregor
424e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \brief Retrieve the name of the module file that should be used to
425e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// load a module with the given name.
4266e975c4517958bcc11c834336d340797356058dbDouglas Gregor  ///
427efce31f51d6e7e31e125f96c20f6cdab3ead0a47James Dennett  /// \param ModuleName The module whose module file name will be returned.
428e434ec71fccfe078906403affd641f709702d598Douglas Gregor  ///
429e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \returns The name of the module file that corresponds to this module,
430e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// or an empty string if this module does not correspond to any module file.
431e434ec71fccfe078906403affd641f709702d598Douglas Gregor  std::string getModuleFileName(StringRef ModuleName);
432e434ec71fccfe078906403affd641f709702d598Douglas Gregor
433e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \brief Lookup a module Search for a module with the given name.
434e434ec71fccfe078906403affd641f709702d598Douglas Gregor  ///
435e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \param ModuleName The name of the module we're looking for.
436e434ec71fccfe078906403affd641f709702d598Douglas Gregor  ///
437e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \param AllowSearch Whether we are allowed to search in the various
438e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// search directories to produce a module definition. If not, this lookup
439e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// will only return an already-known module.
440e434ec71fccfe078906403affd641f709702d598Douglas Gregor  ///
441e434ec71fccfe078906403affd641f709702d598Douglas Gregor  /// \returns The module with the given name.
442e434ec71fccfe078906403affd641f709702d598Douglas Gregor  Module *lookupModule(StringRef ModuleName, bool AllowSearch = true);
4439a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor
444afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner  void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
44583d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
446a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief Determine whether there is a module map that may map the header
447a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// with the given file name to a (sub)module.
448a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  ///
449a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \param Filename The name of the file.
450a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  ///
451a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \param Root The "root" directory, at which we should stop looking for
452a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// module maps.
453a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root);
454a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor
455a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor  /// \brief Retrieve the module that corresponds to the given file, if any.
45651f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor  ///
45751f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor  /// \param File The header that we wish to map to a module.
4581a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor  Module *findModuleForHeader(const FileEntry *File);
459a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor
460db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \brief Read the contents of the given module map file.
461db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  ///
462db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \param File The module map file.
463db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  ///
464db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  /// \returns true if an error occurred, false otherwise.
465db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor  bool loadModuleMapFile(const FileEntry *File);
4662821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor
467c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor  /// \brief Collect the set of all known, top-level modules.
468c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor  ///
469c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor  /// \param Modules Will be filled with the set of known, top-level modules.
470c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor  void collectAllModules(llvm::SmallVectorImpl<Module *> &Modules);
471c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor
472e434ec71fccfe078906403affd641f709702d598Douglas Gregorprivate:
4732821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \brief Retrieve a module with the given name, which may be part of the
4742821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// given framework.
4752821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ///
4762821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \param Name The name of the module to retrieve.
4772821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ///
4782821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \param Dir The framework directory (e.g., ModuleName.framework).
4792821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ///
480a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor  /// \param IsSystem Whether the framework directory is part of the system
481a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor  /// frameworks.
482a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor  ///
4832821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \returns The module, if found; otherwise, null.
484e434ec71fccfe078906403affd641f709702d598Douglas Gregor  Module *loadFrameworkModule(StringRef Name,
485e434ec71fccfe078906403affd641f709702d598Douglas Gregor                              const DirectoryEntry *Dir,
486e434ec71fccfe078906403affd641f709702d598Douglas Gregor                              bool IsSystem);
487e434ec71fccfe078906403affd641f709702d598Douglas Gregor
488e434ec71fccfe078906403affd641f709702d598Douglas Gregorpublic:
4892821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  /// \brief Retrieve the module map.
4902821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor  ModuleMap &getModuleMap() { return ModMap; }
491db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor
49212fab31aa5868b1a6b52246b5a87daa48a338fe2Douglas Gregor  unsigned header_file_size() const { return FileInfo.size(); }
49383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff
494c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl  // Used by ASTReader.
49583d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
4961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
497a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
498590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis  const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
499590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis    return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
500590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis  }
501590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis
502ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  // Used by external tools
503ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
504ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
505ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
506ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  unsigned search_dir_size() const { return SearchDirs.size(); }
507ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor
50874a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator quoted_dir_begin() const {
50974a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin();
51074a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
51174a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator quoted_dir_end() const {
51274a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + AngledDirIdx;
51374a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
51474a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber
51574a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator angled_dir_begin() const {
51674a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + AngledDirIdx;
51774a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
51874a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  search_dir_iterator angled_dir_end() const {
51974a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber    return SearchDirs.begin() + SystemDirIdx;
52074a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber  }
52174a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber
522ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator system_dir_begin() const {
523ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor    return SearchDirs.begin() + SystemDirIdx;
524ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  }
525ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor  search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
526ec356c320a81062b1843f0dbe7fedf29ed947eceDouglas Gregor
52765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Retrieve a uniqued framework name.
52865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  StringRef getUniqueFrameworkName(StringRef Framework);
52965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
5305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void PrintStats();
531d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek
532d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek  size_t getTotalMemory() const;
533d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek
534cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth  static std::string NormalizeDashIncludePath(StringRef File,
535cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth                                              FileManager &FileMgr);
536cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth
5375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
53826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \brief Describes what happened when we tried to load a module map file.
53926697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  enum LoadModuleMapResult {
54026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief The module map file had already been loaded.
54126697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_AlreadyLoaded,
54226697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief The module map file was loaded by this invocation.
54326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_NewlyLoaded,
54426697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief There is was directory with the given name.
54526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_NoDirectory,
54626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// \brief There was either no module map file or the module map file was
54726697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    /// invalid.
54826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor    LMM_InvalidModuleMap
54926697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  };
55026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor
551cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  /// \brief Try to load the module map file in the given directory.
552cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  ///
55326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \param DirName The name of the directory where we will look for a module
55426697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// map file.
55526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  ///
55626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \returns The result of attempting to load the module map file from the
55726697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// named directory.
55826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  LoadModuleMapResult loadModuleMapFile(StringRef DirName);
559cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor
560cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  /// \brief Try to load the module map file in the given directory.
561cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor  ///
56226697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \param Dir The directory where we will look for a module map file.
56326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  ///
56426697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// \returns The result of attempting to load the module map file from the
56526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  /// named directory.
56626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor  LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir);
5671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
568a24bd5d9ad79be50cec0e25364d8267e7623c33fJames Dennett  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
56983d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff  HeaderFileInfo &getFileInfo(const FileEntry *FE);
5705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
5715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end namespace clang
5735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
575