blob: 4d2ed2eccc1bd4dd0175033672d4141ca6ad9138 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- HeaderSearch.h - Resolve Header File Locations ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the HeaderSearch interface.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
15#define LLVM_CLANG_LEX_HEADERSEARCH_H
16
17#include "clang/Lex/DirectoryLookup.h"
18#include "llvm/ADT/StringMap.h"
19#include <vector>
20
21namespace clang {
Douglas Gregor8c5a7602009-04-25 23:30:02 +000022
23class ExternalIdentifierLookup;
Reid Spencer5f016e22007-07-11 17:01:13 +000024class FileEntry;
25class FileManager;
26class IdentifierInfo;
27
Steve Naroff83d63c72009-04-24 20:03:17 +000028/// HeaderFileInfo - The preprocessor keeps track of this information for each
29/// file that is #included.
30struct HeaderFileInfo {
31 /// isImport - True if this is a #import'd or #pragma once file.
Douglas Gregorcfbf1c72011-02-10 17:09:37 +000032 unsigned isImport : 1;
Mike Stump1eb44332009-09-09 15:08:12 +000033
Douglas Gregordd3e5542011-05-04 00:14:37 +000034 /// isPragmaOnce - True if this is #pragma once file.
35 unsigned isPragmaOnce : 1;
36
Steve Naroff83d63c72009-04-24 20:03:17 +000037 /// DirInfo - Keep track of whether this is a system header, and if so,
38 /// whether it is C++ clean or not. This can be set by the include paths or
39 /// by #pragma gcc system_header. This is an instance of
40 /// SrcMgr::CharacteristicKind.
41 unsigned DirInfo : 2;
Mike Stump1eb44332009-09-09 15:08:12 +000042
Douglas Gregorcfbf1c72011-02-10 17:09:37 +000043 /// \brief Whether this header file info was supplied by an external source.
44 unsigned External : 1;
45
46 /// \brief Whether this structure is considered to already have been
47 /// "resolved", meaning that it was loaded from the external source.
48 unsigned Resolved : 1;
49
Steve Naroff83d63c72009-04-24 20:03:17 +000050 /// NumIncludes - This is the number of times the file has been included
51 /// already.
52 unsigned short NumIncludes;
Mike Stump1eb44332009-09-09 15:08:12 +000053
Douglas Gregorcfbf1c72011-02-10 17:09:37 +000054 /// \brief The ID number of the controlling macro.
55 ///
56 /// This ID number will be non-zero when there is a controlling
57 /// macro whose IdentifierInfo may not yet have been loaded from
58 /// external storage.
59 unsigned ControllingMacroID;
60
Steve Naroff83d63c72009-04-24 20:03:17 +000061 /// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard
62 /// that protects the entire contents of the file, this is the identifier
63 /// for the macro that controls whether or not it has any effect.
Douglas Gregor8c5a7602009-04-25 23:30:02 +000064 ///
65 /// Note: Most clients should use getControllingMacro() to access
66 /// the controlling macro of this header, since
67 /// getControllingMacro() is able to load a controlling macro from
68 /// external storage.
Steve Naroff83d63c72009-04-24 20:03:17 +000069 const IdentifierInfo *ControllingMacro;
Douglas Gregor8c5a7602009-04-25 23:30:02 +000070
Mike Stump1eb44332009-09-09 15:08:12 +000071 HeaderFileInfo()
Douglas Gregordd3e5542011-05-04 00:14:37 +000072 : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
73 External(false), Resolved(false), NumIncludes(0), ControllingMacroID(0),
Douglas Gregorcfbf1c72011-02-10 17:09:37 +000074 ControllingMacro(0) {}
Douglas Gregor8c5a7602009-04-25 23:30:02 +000075
76 /// \brief Retrieve the controlling macro for this header file, if
77 /// any.
78 const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
Douglas Gregorcfbf1c72011-02-10 17:09:37 +000079
80 /// \brief Determine whether this is a non-default header file info, e.g.,
81 /// it corresponds to an actual header we've included or tried to include.
82 bool isNonDefault() const {
Douglas Gregordd3e5542011-05-04 00:14:37 +000083 return isImport || isPragmaOnce || NumIncludes || ControllingMacro ||
84 ControllingMacroID;
Douglas Gregorcfbf1c72011-02-10 17:09:37 +000085 }
Steve Naroff83d63c72009-04-24 20:03:17 +000086};
87
Douglas Gregorcfbf1c72011-02-10 17:09:37 +000088/// \brief An external source of header file information, which may supply
89/// information about header files already included.
90class ExternalHeaderFileInfoSource {
91public:
92 virtual ~ExternalHeaderFileInfoSource();
93
94 /// \brief Retrieve the header file information for the given file entry.
95 ///
96 /// \returns Header file information for the given file entry, with the
97 /// \c External bit set. If the file entry is not known, return a
98 /// default-constructed \c HeaderFileInfo.
99 virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
100};
101
Reid Spencer5f016e22007-07-11 17:01:13 +0000102/// HeaderSearch - This class encapsulates the information needed to find the
103/// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
104class HeaderSearch {
105 FileManager &FileMgr;
Reid Spencer5f016e22007-07-11 17:01:13 +0000106 /// #include search path information. Requests for #include "x" search the
107 /// directory of the #including file first, then each directory in SearchDirs
Nico Weber74a5fd82011-05-24 04:31:14 +0000108 /// consecutively. Requests for <x> search the current dir first, then each
109 /// directory in SearchDirs, starting at AngledDirIdx, consecutively. If
Reid Spencer5f016e22007-07-11 17:01:13 +0000110 /// NoCurDirSearch is true, then the check for the file in the current
Chris Lattnerfc8f0e12011-04-15 05:22:18 +0000111 /// directory is suppressed.
Reid Spencer5f016e22007-07-11 17:01:13 +0000112 std::vector<DirectoryLookup> SearchDirs;
Nico Weber74a5fd82011-05-24 04:31:14 +0000113 unsigned AngledDirIdx;
Reid Spencer5f016e22007-07-11 17:01:13 +0000114 unsigned SystemDirIdx;
115 bool NoCurDirSearch;
Mike Stump1eb44332009-09-09 15:08:12 +0000116
Reid Spencer5f016e22007-07-11 17:01:13 +0000117 /// FileInfo - This contains all of the preprocessor-specific data about files
118 /// that are included. The vector is indexed by the FileEntry's UID.
119 ///
Steve Naroff83d63c72009-04-24 20:03:17 +0000120 std::vector<HeaderFileInfo> FileInfo;
Reid Spencer5f016e22007-07-11 17:01:13 +0000121
Chris Lattner9960ae82007-07-22 07:28:00 +0000122 /// LookupFileCache - This is keeps track of each lookup performed by
123 /// LookupFile. The first part of the value is the starting index in
124 /// SearchDirs that the cached search was performed from. If there is a hit
125 /// and this value doesn't match the current query, the cache has to be
126 /// ignored. The second value is the entry in SearchDirs that satisfied the
127 /// query.
128 llvm::StringMap<std::pair<unsigned, unsigned> > LookupFileCache;
Mike Stump1eb44332009-09-09 15:08:12 +0000129
130
Reid Spencer5f016e22007-07-11 17:01:13 +0000131 /// FrameworkMap - This is a collection mapping a framework or subframework
132 /// name like "Carbon" to the Carbon.framework directory.
133 llvm::StringMap<const DirectoryEntry *> FrameworkMap;
134
Mike Stump1eb44332009-09-09 15:08:12 +0000135 /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
Chris Lattner822da612007-12-17 06:36:45 +0000136 /// headermaps. This vector owns the headermap.
137 std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
Douglas Gregor8c5a7602009-04-25 23:30:02 +0000138
139 /// \brief Entity used to resolve the identifier IDs of controlling
140 /// macros into IdentifierInfo pointers, as needed.
141 ExternalIdentifierLookup *ExternalLookup;
142
Douglas Gregorcfbf1c72011-02-10 17:09:37 +0000143 /// \brief Entity used to look up stored header file information.
144 ExternalHeaderFileInfoSource *ExternalSource;
145
Reid Spencer5f016e22007-07-11 17:01:13 +0000146 // Various statistics we track for performance analysis.
147 unsigned NumIncluded;
148 unsigned NumMultiIncludeFileOptzn;
149 unsigned NumFrameworkLookups, NumSubFrameworkLookups;
Steve Naroff49c1f4a2008-02-02 00:10:46 +0000150
151 // HeaderSearch doesn't support default or copy construction.
Mike Stump1eb44332009-09-09 15:08:12 +0000152 explicit HeaderSearch();
Steve Naroff49c1f4a2008-02-02 00:10:46 +0000153 explicit HeaderSearch(const HeaderSearch&);
154 void operator=(const HeaderSearch&);
Reid Spencer5f016e22007-07-11 17:01:13 +0000155public:
Chris Lattner39b49bc2010-11-23 08:35:12 +0000156 HeaderSearch(FileManager &FM);
Chris Lattner822da612007-12-17 06:36:45 +0000157 ~HeaderSearch();
Reid Spencer5f016e22007-07-11 17:01:13 +0000158
159 FileManager &getFileMgr() const { return FileMgr; }
160
161 /// SetSearchPaths - Interface for setting the file search paths.
162 ///
163 void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
Nico Weber74a5fd82011-05-24 04:31:14 +0000164 unsigned angledDirIdx, unsigned systemDirIdx,
165 bool noCurDirSearch) {
166 assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
167 "Directory indicies are unordered");
Reid Spencer5f016e22007-07-11 17:01:13 +0000168 SearchDirs = dirs;
Nico Weber74a5fd82011-05-24 04:31:14 +0000169 AngledDirIdx = angledDirIdx;
Reid Spencer5f016e22007-07-11 17:01:13 +0000170 SystemDirIdx = systemDirIdx;
171 NoCurDirSearch = noCurDirSearch;
Chris Lattner9960ae82007-07-22 07:28:00 +0000172 //LookupFileCache.clear();
Reid Spencer5f016e22007-07-11 17:01:13 +0000173 }
Mike Stump1eb44332009-09-09 15:08:12 +0000174
Reid Spencer5f016e22007-07-11 17:01:13 +0000175 /// ClearFileInfo - Forget everything we know about headers so far.
176 void ClearFileInfo() {
177 FileInfo.clear();
178 }
Mike Stump1eb44332009-09-09 15:08:12 +0000179
Douglas Gregor8c5a7602009-04-25 23:30:02 +0000180 void SetExternalLookup(ExternalIdentifierLookup *EIL) {
181 ExternalLookup = EIL;
182 }
183
Douglas Gregorcfbf1c72011-02-10 17:09:37 +0000184 ExternalIdentifierLookup *getExternalLookup() const {
185 return ExternalLookup;
186 }
187
188 /// \brief Set the external source of header information.
189 void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
190 ExternalSource = ES;
191 }
192
Reid Spencer5f016e22007-07-11 17:01:13 +0000193 /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
Manuel Klimek74124942011-04-26 21:50:03 +0000194 /// return null on failure.
195 ///
196 /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
197 /// the file was found in, or null if not applicable.
198 ///
199 /// \param isAngled indicates whether the file reference is a <> reference.
200 ///
201 /// \param CurDir If non-null, the file was found in the specified directory
202 /// search location. This is used to implement #include_next.
203 ///
204 /// \param CurFileEnt If non-null, indicates where the #including file is, in
205 /// case a relative search is needed.
206 ///
207 /// \param SearchPath If non-null, will be set to the search path relative
208 /// to which the file was found. If the include path is absolute, SearchPath
209 /// will be set to an empty string.
210 ///
211 /// \param RelativePath If non-null, will be set to the path relative to
212 /// SearchPath at which the file was found. This only differs from the
213 /// Filename for framework includes.
Chris Lattner686775d2011-07-20 06:58:45 +0000214 const FileEntry *LookupFile(StringRef Filename, bool isAngled,
Reid Spencer5f016e22007-07-11 17:01:13 +0000215 const DirectoryLookup *FromDir,
216 const DirectoryLookup *&CurDir,
Chandler Carruthb5142bb2011-03-16 18:34:36 +0000217 const FileEntry *CurFileEnt,
Chris Lattner686775d2011-07-20 06:58:45 +0000218 SmallVectorImpl<char> *SearchPath,
219 SmallVectorImpl<char> *RelativePath);
Mike Stump1eb44332009-09-09 15:08:12 +0000220
Reid Spencer5f016e22007-07-11 17:01:13 +0000221 /// LookupSubframeworkHeader - Look up a subframework for the specified
222 /// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from
223 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
224 /// is a subframework within Carbon.framework. If so, return the FileEntry
225 /// for the designated file, otherwise return null.
Chandler Carruthb5142bb2011-03-16 18:34:36 +0000226 const FileEntry *LookupSubframeworkHeader(
Chris Lattner686775d2011-07-20 06:58:45 +0000227 StringRef Filename,
Chandler Carruthb5142bb2011-03-16 18:34:36 +0000228 const FileEntry *RelativeFileEnt,
Chris Lattner686775d2011-07-20 06:58:45 +0000229 SmallVectorImpl<char> *SearchPath,
230 SmallVectorImpl<char> *RelativePath);
Mike Stump1eb44332009-09-09 15:08:12 +0000231
Chris Lattnerafded5b2007-12-17 08:13:48 +0000232 /// LookupFrameworkCache - Look up the specified framework name in our
233 /// framework cache, returning the DirectoryEntry it is in if we know,
234 /// otherwise, return null.
Chris Lattner686775d2011-07-20 06:58:45 +0000235 const DirectoryEntry *&LookupFrameworkCache(StringRef FWName) {
Chris Lattnera1394812010-01-10 01:35:12 +0000236 return FrameworkMap.GetOrCreateValue(FWName).getValue();
Chris Lattnerafded5b2007-12-17 08:13:48 +0000237 }
Mike Stump1eb44332009-09-09 15:08:12 +0000238
Reid Spencer5f016e22007-07-11 17:01:13 +0000239 /// ShouldEnterIncludeFile - Mark the specified file as a target of of a
240 /// #include, #include_next, or #import directive. Return false if #including
241 /// the file will have no effect or true if we should include it.
242 bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
Mike Stump1eb44332009-09-09 15:08:12 +0000243
244
Reid Spencer5f016e22007-07-11 17:01:13 +0000245 /// getFileDirFlavor - Return whether the specified file is a normal header,
246 /// a system header, or a C++ friendly system header.
Chris Lattner9d728512008-10-27 01:19:25 +0000247 SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
248 return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
Reid Spencer5f016e22007-07-11 17:01:13 +0000249 }
Mike Stump1eb44332009-09-09 15:08:12 +0000250
Reid Spencer5f016e22007-07-11 17:01:13 +0000251 /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.
252 /// due to #pragma once.
253 void MarkFileIncludeOnce(const FileEntry *File) {
Douglas Gregordd3e5542011-05-04 00:14:37 +0000254 HeaderFileInfo &FI = getFileInfo(File);
255 FI.isImport = true;
256 FI.isPragmaOnce = true;
Reid Spencer5f016e22007-07-11 17:01:13 +0000257 }
258
Daniel Dunbare9eb3f82008-09-26 01:11:51 +0000259 /// MarkFileSystemHeader - Mark the specified file as a system header, e.g.
Reid Spencer5f016e22007-07-11 17:01:13 +0000260 /// due to #pragma GCC system_header.
261 void MarkFileSystemHeader(const FileEntry *File) {
Chris Lattner0b9e7362008-09-26 21:18:42 +0000262 getFileInfo(File).DirInfo = SrcMgr::C_System;
Reid Spencer5f016e22007-07-11 17:01:13 +0000263 }
Mike Stump1eb44332009-09-09 15:08:12 +0000264
Chris Lattner25bfcb92007-11-15 19:22:18 +0000265 /// IncrementIncludeCount - Increment the count for the number of times the
266 /// specified FileEntry has been entered.
267 void IncrementIncludeCount(const FileEntry *File) {
268 ++getFileInfo(File).NumIncludes;
269 }
Mike Stump1eb44332009-09-09 15:08:12 +0000270
Reid Spencer5f016e22007-07-11 17:01:13 +0000271 /// SetFileControllingMacro - Mark the specified file as having a controlling
272 /// macro. This is used by the multiple-include optimization to eliminate
273 /// no-op #includes.
274 void SetFileControllingMacro(const FileEntry *File,
275 const IdentifierInfo *ControllingMacro) {
276 getFileInfo(File).ControllingMacro = ControllingMacro;
277 }
Mike Stump1eb44332009-09-09 15:08:12 +0000278
Douglas Gregordd3e5542011-05-04 00:14:37 +0000279 /// \brief Determine whether this file is intended to be safe from
280 /// multiple inclusions, e.g., it has #pragma once or a controlling
281 /// macro.
282 ///
283 /// This routine does not consider the effect of #import
284 bool isFileMultipleIncludeGuarded(const FileEntry *File);
285
Chris Lattner822da612007-12-17 06:36:45 +0000286 /// CreateHeaderMap - This method returns a HeaderMap for the specified
287 /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
Chris Lattner1bfd4a62007-12-17 18:34:53 +0000288 const HeaderMap *CreateHeaderMap(const FileEntry *FE);
Mike Stump1eb44332009-09-09 15:08:12 +0000289
Chris Lattnerafded5b2007-12-17 08:13:48 +0000290 void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
Steve Naroff83d63c72009-04-24 20:03:17 +0000291
Douglas Gregor12fab312010-03-16 16:35:32 +0000292 typedef std::vector<HeaderFileInfo>::const_iterator header_file_iterator;
293 header_file_iterator header_file_begin() const { return FileInfo.begin(); }
294 header_file_iterator header_file_end() const { return FileInfo.end(); }
295 unsigned header_file_size() const { return FileInfo.size(); }
Steve Naroff83d63c72009-04-24 20:03:17 +0000296
Sebastian Redlc43b54c2010-08-18 23:56:43 +0000297 // Used by ASTReader.
Steve Naroff83d63c72009-04-24 20:03:17 +0000298 void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
Mike Stump1eb44332009-09-09 15:08:12 +0000299
Douglas Gregorec356c32011-03-06 17:33:53 +0000300 // Used by external tools
301 typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
302 search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
303 search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
304 unsigned search_dir_size() const { return SearchDirs.size(); }
305
Nico Weber74a5fd82011-05-24 04:31:14 +0000306 search_dir_iterator quoted_dir_begin() const {
307 return SearchDirs.begin();
308 }
309 search_dir_iterator quoted_dir_end() const {
310 return SearchDirs.begin() + AngledDirIdx;
311 }
312
313 search_dir_iterator angled_dir_begin() const {
314 return SearchDirs.begin() + AngledDirIdx;
315 }
316 search_dir_iterator angled_dir_end() const {
317 return SearchDirs.begin() + SystemDirIdx;
318 }
319
Douglas Gregorec356c32011-03-06 17:33:53 +0000320 search_dir_iterator system_dir_begin() const {
321 return SearchDirs.begin() + SystemDirIdx;
322 }
323 search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
324
Reid Spencer5f016e22007-07-11 17:01:13 +0000325 void PrintStats();
326private:
Mike Stump1eb44332009-09-09 15:08:12 +0000327
Steve Naroff83d63c72009-04-24 20:03:17 +0000328 /// getFileInfo - Return the HeaderFileInfo structure for the specified
Reid Spencer5f016e22007-07-11 17:01:13 +0000329 /// FileEntry.
Steve Naroff83d63c72009-04-24 20:03:17 +0000330 HeaderFileInfo &getFileInfo(const FileEntry *FE);
Reid Spencer5f016e22007-07-11 17:01:13 +0000331};
332
333} // end namespace clang
334
335#endif