1 | //===--- DirectoryLookup.h - Info for searching for headers -----*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the DirectoryLookup interface. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H |
14 | #define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H |
15 | |
16 | #include "clang/Basic/LLVM.h" |
17 | #include "clang/Basic/FileManager.h" |
18 | #include "clang/Basic/SourceManager.h" |
19 | #include "clang/Lex/ModuleMap.h" |
20 | |
21 | namespace clang { |
22 | class ; |
23 | class ; |
24 | class Module; |
25 | |
26 | /// DirectoryLookup - This class represents one entry in the search list that |
27 | /// specifies the search order for directories in \#include directives. It |
28 | /// represents either a directory, a framework, or a headermap. |
29 | /// |
30 | class DirectoryLookup { |
31 | public: |
32 | enum LookupType_t { |
33 | LT_NormalDir, |
34 | LT_Framework, |
35 | |
36 | }; |
37 | private: |
38 | union DLU { // This union is discriminated by isHeaderMap. |
39 | /// Dir - This is the actual directory that we're referring to for a normal |
40 | /// directory or a framework. |
41 | DirectoryEntryRef Dir; |
42 | |
43 | /// Map - This is the HeaderMap if this is a headermap lookup. |
44 | /// |
45 | const HeaderMap *Map; |
46 | |
47 | DLU(DirectoryEntryRef Dir) : Dir(Dir) {} |
48 | (const HeaderMap *Map) : Map(Map) {} |
49 | } u; |
50 | |
51 | /// DirCharacteristic - The type of directory this is: this is an instance of |
52 | /// SrcMgr::CharacteristicKind. |
53 | LLVM_PREFERRED_TYPE(SrcMgr::CharacteristicKind) |
54 | unsigned DirCharacteristic : 3; |
55 | |
56 | /// LookupType - This indicates whether this DirectoryLookup object is a |
57 | /// normal directory, a framework, or a headermap. |
58 | LLVM_PREFERRED_TYPE(LookupType_t) |
59 | unsigned LookupType : 2; |
60 | |
61 | /// Whether this is a header map used when building a framework. |
62 | LLVM_PREFERRED_TYPE(bool) |
63 | unsigned : 1; |
64 | |
65 | /// Whether we've performed an exhaustive search for module maps |
66 | /// within the subdirectories of this directory. |
67 | LLVM_PREFERRED_TYPE(bool) |
68 | unsigned SearchedAllModuleMaps : 1; |
69 | |
70 | public: |
71 | /// This ctor *does not take ownership* of 'Dir'. |
72 | DirectoryLookup(DirectoryEntryRef Dir, SrcMgr::CharacteristicKind DT, |
73 | bool isFramework) |
74 | : u(Dir), DirCharacteristic(DT), |
75 | LookupType(isFramework ? LT_Framework : LT_NormalDir), |
76 | IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {} |
77 | |
78 | /// This ctor *does not take ownership* of 'Map'. |
79 | (const HeaderMap *Map, SrcMgr::CharacteristicKind DT, |
80 | bool ) |
81 | : u(Map), DirCharacteristic(DT), LookupType(LT_HeaderMap), |
82 | IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {} |
83 | |
84 | /// getLookupType - Return the kind of directory lookup that this is: either a |
85 | /// normal directory, a framework path, or a HeaderMap. |
86 | LookupType_t getLookupType() const { return (LookupType_t)LookupType; } |
87 | |
88 | /// getName - Return the directory or filename corresponding to this lookup |
89 | /// object. |
90 | StringRef getName() const; |
91 | |
92 | /// getDir - Return the directory that this entry refers to. |
93 | /// |
94 | const DirectoryEntry *getDir() const { |
95 | return isNormalDir() ? &u.Dir.getDirEntry() : nullptr; |
96 | } |
97 | |
98 | OptionalDirectoryEntryRef getDirRef() const { |
99 | return isNormalDir() ? OptionalDirectoryEntryRef(u.Dir) : std::nullopt; |
100 | } |
101 | |
102 | /// getFrameworkDir - Return the directory that this framework refers to. |
103 | /// |
104 | const DirectoryEntry *getFrameworkDir() const { |
105 | return isFramework() ? &u.Dir.getDirEntry() : nullptr; |
106 | } |
107 | |
108 | OptionalDirectoryEntryRef getFrameworkDirRef() const { |
109 | return isFramework() ? OptionalDirectoryEntryRef(u.Dir) : std::nullopt; |
110 | } |
111 | |
112 | /// getHeaderMap - Return the directory that this entry refers to. |
113 | /// |
114 | const HeaderMap *() const { |
115 | return isHeaderMap() ? u.Map : nullptr; |
116 | } |
117 | |
118 | /// isNormalDir - Return true if this is a normal directory, not a header map. |
119 | bool isNormalDir() const { return getLookupType() == LT_NormalDir; } |
120 | |
121 | /// isFramework - True if this is a framework directory. |
122 | /// |
123 | bool isFramework() const { return getLookupType() == LT_Framework; } |
124 | |
125 | /// isHeaderMap - Return true if this is a header map, not a normal directory. |
126 | bool () const { return getLookupType() == LT_HeaderMap; } |
127 | |
128 | /// Determine whether we have already searched this entire |
129 | /// directory for module maps. |
130 | bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; } |
131 | |
132 | /// Specify whether we have already searched all of the subdirectories |
133 | /// for module maps. |
134 | void setSearchedAllModuleMaps(bool SAMM) { |
135 | SearchedAllModuleMaps = SAMM; |
136 | } |
137 | |
138 | /// DirCharacteristic - The type of directory this is, one of the DirType enum |
139 | /// values. |
140 | SrcMgr::CharacteristicKind getDirCharacteristic() const { |
141 | return (SrcMgr::CharacteristicKind)DirCharacteristic; |
142 | } |
143 | |
144 | /// Whether this describes a system header directory. |
145 | bool () const { |
146 | return getDirCharacteristic() != SrcMgr::C_User; |
147 | } |
148 | |
149 | /// Whether this header map is building a framework or not. |
150 | bool () const { |
151 | return isHeaderMap() && IsIndexHeaderMap; |
152 | } |
153 | |
154 | /// LookupFile - Lookup the specified file in this search path, returning it |
155 | /// if it exists or returning null if not. |
156 | /// |
157 | /// \param Filename The file to look up relative to the search paths. |
158 | /// |
159 | /// \param HS The header search instance to search with. |
160 | /// |
161 | /// \param IncludeLoc the source location of the #include or #import |
162 | /// directive. |
163 | /// |
164 | /// \param SearchPath If not NULL, will be set to the search path relative |
165 | /// to which the file was found. |
166 | /// |
167 | /// \param RelativePath If not NULL, will be set to the path relative to |
168 | /// SearchPath at which the file was found. This only differs from the |
169 | /// Filename for framework includes. |
170 | /// |
171 | /// \param RequestingModule The module in which the lookup was performed. |
172 | /// |
173 | /// \param SuggestedModule If non-null, and the file found is semantically |
174 | /// part of a known module, this will be set to the module that should |
175 | /// be imported instead of preprocessing/parsing the file found. |
176 | /// |
177 | /// \param [out] InUserSpecifiedSystemFramework If the file is found, |
178 | /// set to true if the file is located in a framework that has been |
179 | /// user-specified to be treated as a system framework. |
180 | /// |
181 | /// \param [out] IsFrameworkFound For a framework directory set to true if |
182 | /// specified '.framework' directory is found. |
183 | /// |
184 | /// \param [out] MappedName if this is a headermap which maps the filename to |
185 | /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this |
186 | /// vector and point Filename to it. |
187 | OptionalFileEntryRef |
188 | (StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, |
189 | SmallVectorImpl<char> *SearchPath, |
190 | SmallVectorImpl<char> *RelativePath, Module *RequestingModule, |
191 | ModuleMap::KnownHeader *SuggestedModule, |
192 | bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, |
193 | bool &, SmallVectorImpl<char> &MappedName, |
194 | bool OpenFile = true) const; |
195 | |
196 | private: |
197 | OptionalFileEntryRef ( |
198 | StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, |
199 | SmallVectorImpl<char> *RelativePath, Module *RequestingModule, |
200 | ModuleMap::KnownHeader *SuggestedModule, |
201 | bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const; |
202 | }; |
203 | |
204 | } // end namespace clang |
205 | |
206 | #endif |
207 | |