15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- DirectoryLookup.h - Info for searching for headers -----*- 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 DirectoryLookup interface.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
17d47d3b0cfeb7e8564ff77f48130fe63282b6d127Chris Lattner#include "clang/Basic/LLVM.h"
180b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner#include "clang/Basic/SourceManager.h"
19bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl#include "clang/Lex/ModuleMap.h"
200b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
22822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattnerclass HeaderMap;
23df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattnerclass DirectoryEntry;
24df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattnerclass FileEntry;
25afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattnerclass HeaderSearch;
261a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregorclass Module;
271a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor
28822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner/// DirectoryLookup - This class represents one entry in the search list that
29dc3d8c9c7094f89438407b97795b3c993bb3d6feJames Dennett/// specifies the search order for directories in \#include directives.  It
30df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner/// represents either a directory, a framework, or a headermap.
31df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner///
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass DirectoryLookup {
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
34df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  enum LookupType_t {
35df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner    LT_NormalDir,
36df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner    LT_Framework,
37df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner    LT_HeaderMap
38df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  };
39822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattnerprivate:
40822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  union {  // This union is discriminated by isHeaderMap.
41df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner    /// Dir - This is the actual directory that we're referring to for a normal
42df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner    /// directory or a framework.
43822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    const DirectoryEntry *Dir;
441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
45df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner    /// Map - This is the HeaderMap if this is a headermap lookup.
46df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner    ///
47822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner    const HeaderMap *Map;
48822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  } u;
491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
500b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner  /// DirCharacteristic - The type of directory this is: this is an instance of
519d72851fec9e9c62570a027d42701562bbf29751Chris Lattner  /// SrcMgr::CharacteristicKind.
52ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned DirCharacteristic : 2;
531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
54df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  /// LookupType - This indicates whether this DirectoryLookup object is a
55df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  /// normal directory, a framework, or a headermap.
56df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  unsigned LookupType : 2;
5765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
5865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Whether this is a header map used when building a framework.
5965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  unsigned IsIndexHeaderMap : 1;
60cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor
61cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  /// \brief Whether we've performed an exhaustive search for module maps
62cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  /// within the subdirectories of this directory.
63cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  unsigned SearchedAllModuleMaps : 1;
6465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
66822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
67822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// 'dir'.
689d72851fec9e9c62570a027d42701562bbf29751Chris Lattner  DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT,
691ea6bc0fd9c1ff9fa03e8a829a79c4167445d503Daniel Dunbar                  bool isFramework)
701ea6bc0fd9c1ff9fa03e8a829a79c4167445d503Daniel Dunbar    : DirCharacteristic(DT),
7165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor      LookupType(isFramework ? LT_Framework : LT_NormalDir),
72cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor      IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {
731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    u.Dir = dir;
74822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  }
751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
76822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
77822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// 'map'.
789d72851fec9e9c62570a027d42701562bbf29751Chris Lattner  DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT,
791ea6bc0fd9c1ff9fa03e8a829a79c4167445d503Daniel Dunbar                  bool isIndexHeaderMap)
801ea6bc0fd9c1ff9fa03e8a829a79c4167445d503Daniel Dunbar    : DirCharacteristic(DT), LookupType(LT_HeaderMap),
81cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor      IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {
821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    u.Map = map;
83822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  }
841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
853af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner  /// getLookupType - Return the kind of directory lookup that this is: either a
863af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner  /// normal directory, a framework path, or a HeaderMap.
873af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner  LookupType_t getLookupType() const { return (LookupType_t)LookupType; }
881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
893af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner  /// getName - Return the directory or filename corresponding to this lookup
903af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner  /// object.
913af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner  const char *getName() const;
921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// getDir - Return the directory that this entry refers to.
945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
95df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  const DirectoryEntry *getDir() const { return isNormalDir() ? u.Dir : 0; }
96df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner
97df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  /// getFrameworkDir - Return the directory that this framework refers to.
98df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  ///
99df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  const DirectoryEntry *getFrameworkDir() const {
100df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner    return isFramework() ? u.Dir : 0;
101df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  }
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
103822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  /// getHeaderMap - Return the directory that this entry refers to.
104822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner  ///
105df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  const HeaderMap *getHeaderMap() const { return isHeaderMap() ? u.Map : 0; }
106b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner
107b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner  /// isNormalDir - Return true if this is a normal directory, not a header map.
108df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  bool isNormalDir() const { return getLookupType() == LT_NormalDir; }
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
110df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  /// isFramework - True if this is a framework directory.
111df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  ///
112df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  bool isFramework() const { return getLookupType() == LT_Framework; }
1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
114b94c707350ee2099996a80c8d97f28b61ff98c7bChris Lattner  /// isHeaderMap - Return true if this is a header map, not a normal directory.
115df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner  bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; }
1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
117cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  /// \brief Determine whether we have already searched this entire
118cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  /// directory for module maps.
119cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; }
120cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor
121cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  /// \brief Specify whether we have already searched all of the subdirectories
122cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  /// for module maps.
123cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  void setSearchedAllModuleMaps(bool SAMM) {
124cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor    SearchedAllModuleMaps = SAMM;
125cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor  }
126cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// DirCharacteristic - The type of directory this is, one of the DirType enum
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// values.
1299d72851fec9e9c62570a027d42701562bbf29751Chris Lattner  SrcMgr::CharacteristicKind getDirCharacteristic() const {
1309d72851fec9e9c62570a027d42701562bbf29751Chris Lattner    return (SrcMgr::CharacteristicKind)DirCharacteristic;
1310b9e736308af5397f558ffc8e780c438c2fdb563Chris Lattner  }
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1338f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  /// \brief Whether this describes a system header directory.
1348f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  bool isSystemHeaderDirectory() const {
1358f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor    return getDirCharacteristic() != SrcMgr::C_User;
1368f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor  }
1378f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor
13865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  /// \brief Whether this header map is building a framework or not.
13965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  bool isIndexHeaderMap() const {
14065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor    return isHeaderMap() && IsIndexHeaderMap;
14165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor  }
14265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor
1433af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner  /// LookupFile - Lookup the specified file in this search path, returning it
1443af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner  /// if it exists or returning null if not.
1457412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
1467412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param Filename The file to look up relative to the search paths.
1477412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
1487412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param HS The header search instance to search with.
1497412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
1507412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param SearchPath If not NULL, will be set to the search path relative
1517412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// to which the file was found.
1527412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  ///
1537412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// \param RelativePath If not NULL, will be set to the path relative to
1547412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// SearchPath at which the file was found. This only differs from the
1557412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek  /// Filename for framework includes.
156fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  ///
157fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor  /// \param SuggestedModule If non-null, and the file found is semantically
158c69c42e939e6bdaa56d162cc36da4f6b6c53e8dbDouglas Gregor  /// part of a known module, this will be set to the module that should
159c69c42e939e6bdaa56d162cc36da4f6b6c53e8dbDouglas Gregor  /// be imported instead of preprocessing/parsing the file found.
16085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar  ///
161efce31f51d6e7e31e125f96c20f6cdab3ead0a47James Dennett  /// \param [out] InUserSpecifiedSystemFramework If the file is found,
162efce31f51d6e7e31e125f96c20f6cdab3ead0a47James Dennett  /// set to true if the file is located in a framework that has been
163efce31f51d6e7e31e125f96c20f6cdab3ead0a47James Dennett  /// user-specified to be treated as a system framework.
164686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS,
165686775deca8b8685eb90801495880e3abdd844c2Chris Lattner                              SmallVectorImpl<char> *SearchPath,
166fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor                              SmallVectorImpl<char> *RelativePath,
167bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl                              ModuleMap::KnownHeader *SuggestedModule,
168efce31f51d6e7e31e125f96c20f6cdab3ead0a47James Dennett                              bool &InUserSpecifiedSystemFramework) const;
1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
170afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattnerprivate:
171b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth  const FileEntry *DoFrameworkLookup(
172686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      StringRef Filename, HeaderSearch &HS,
173686775deca8b8685eb90801495880e3abdd844c2Chris Lattner      SmallVectorImpl<char> *SearchPath,
174fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor      SmallVectorImpl<char> *RelativePath,
175bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl      ModuleMap::KnownHeader *SuggestedModule,
17685ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar      bool &InUserSpecifiedSystemHeader) const;
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end namespace clang
1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
183