1 //===--- HeaderSearch.h - Resolve Header File Locations ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the HeaderSearch interface.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
15 #define LLVM_CLANG_LEX_HEADERSEARCH_H
17 #include "clang/Lex/DirectoryLookup.h"
18 #include "llvm/ADT/StringMap.h"
23 class ExternalIdentifierLookup;
28 /// HeaderFileInfo - The preprocessor keeps track of this information for each
29 /// file that is #included.
30 struct HeaderFileInfo {
31 /// isImport - True if this is a #import'd or #pragma once file.
32 unsigned isImport : 1;
34 /// isPragmaOnce - True if this is #pragma once file.
35 unsigned isPragmaOnce : 1;
37 /// 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.
43 /// \brief Whether this header file info was supplied by an external source.
44 unsigned External : 1;
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;
50 /// NumIncludes - This is the number of times the file has been included
52 unsigned short NumIncludes;
54 /// \brief The ID number of the controlling macro.
56 /// This ID number will be non-zero when there is a controlling
57 /// macro whose IdentifierInfo may not yet have been loaded from
59 unsigned ControllingMacroID;
61 /// 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.
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
69 const IdentifierInfo *ControllingMacro;
72 : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
73 External(false), Resolved(false), NumIncludes(0), ControllingMacroID(0),
74 ControllingMacro(0) {}
76 /// \brief Retrieve the controlling macro for this header file, if
78 const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
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 {
83 return isImport || isPragmaOnce || NumIncludes || ControllingMacro ||
88 /// \brief An external source of header file information, which may supply
89 /// information about header files already included.
90 class ExternalHeaderFileInfoSource {
92 virtual ~ExternalHeaderFileInfoSource();
94 /// \brief Retrieve the header file information for the given file entry.
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;
102 /// HeaderSearch - This class encapsulates the information needed to find the
103 /// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
105 FileManager &FileMgr;
106 /// #include search path information. Requests for #include "x" search the
107 /// directory of the #including file first, then each directory in SearchDirs
108 /// consecutively. Requests for <x> search the current dir first, then each
109 /// directory in SearchDirs, starting at AngledDirIdx, consecutively. If
110 /// NoCurDirSearch is true, then the check for the file in the current
111 /// directory is suppressed.
112 std::vector<DirectoryLookup> SearchDirs;
113 unsigned AngledDirIdx;
114 unsigned SystemDirIdx;
117 /// FileInfo - This contains all of the preprocessor-specific data about files
118 /// that are included. The vector is indexed by the FileEntry's UID.
120 std::vector<HeaderFileInfo> FileInfo;
122 /// 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
128 llvm::StringMap<std::pair<unsigned, unsigned> > LookupFileCache;
131 /// 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;
135 /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
136 /// headermaps. This vector owns the headermap.
137 std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
139 /// \brief Entity used to resolve the identifier IDs of controlling
140 /// macros into IdentifierInfo pointers, as needed.
141 ExternalIdentifierLookup *ExternalLookup;
143 /// \brief Entity used to look up stored header file information.
144 ExternalHeaderFileInfoSource *ExternalSource;
146 // Various statistics we track for performance analysis.
147 unsigned NumIncluded;
148 unsigned NumMultiIncludeFileOptzn;
149 unsigned NumFrameworkLookups, NumSubFrameworkLookups;
151 // HeaderSearch doesn't support default or copy construction.
152 explicit HeaderSearch();
153 explicit HeaderSearch(const HeaderSearch&);
154 void operator=(const HeaderSearch&);
156 HeaderSearch(FileManager &FM);
159 FileManager &getFileMgr() const { return FileMgr; }
161 /// SetSearchPaths - Interface for setting the file search paths.
163 void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
164 unsigned angledDirIdx, unsigned systemDirIdx,
165 bool noCurDirSearch) {
166 assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
167 "Directory indicies are unordered");
169 AngledDirIdx = angledDirIdx;
170 SystemDirIdx = systemDirIdx;
171 NoCurDirSearch = noCurDirSearch;
172 //LookupFileCache.clear();
175 /// ClearFileInfo - Forget everything we know about headers so far.
176 void ClearFileInfo() {
180 void SetExternalLookup(ExternalIdentifierLookup *EIL) {
181 ExternalLookup = EIL;
184 ExternalIdentifierLookup *getExternalLookup() const {
185 return ExternalLookup;
188 /// \brief Set the external source of header information.
189 void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
193 /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
194 /// return null on failure.
196 /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
197 /// the file was found in, or null if not applicable.
199 /// \param isAngled indicates whether the file reference is a <> reference.
201 /// \param CurDir If non-null, the file was found in the specified directory
202 /// search location. This is used to implement #include_next.
204 /// \param CurFileEnt If non-null, indicates where the #including file is, in
205 /// case a relative search is needed.
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.
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.
214 const FileEntry *LookupFile(llvm::StringRef Filename, bool isAngled,
215 const DirectoryLookup *FromDir,
216 const DirectoryLookup *&CurDir,
217 const FileEntry *CurFileEnt,
218 llvm::SmallVectorImpl<char> *SearchPath,
219 llvm::SmallVectorImpl<char> *RelativePath);
221 /// 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.
226 const FileEntry *LookupSubframeworkHeader(
227 llvm::StringRef Filename,
228 const FileEntry *RelativeFileEnt,
229 llvm::SmallVectorImpl<char> *SearchPath,
230 llvm::SmallVectorImpl<char> *RelativePath);
232 /// 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.
235 const DirectoryEntry *&LookupFrameworkCache(llvm::StringRef FWName) {
236 return FrameworkMap.GetOrCreateValue(FWName).getValue();
239 /// 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);
245 /// getFileDirFlavor - Return whether the specified file is a normal header,
246 /// a system header, or a C++ friendly system header.
247 SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
248 return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
251 /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.
252 /// due to #pragma once.
253 void MarkFileIncludeOnce(const FileEntry *File) {
254 HeaderFileInfo &FI = getFileInfo(File);
256 FI.isPragmaOnce = true;
259 /// MarkFileSystemHeader - Mark the specified file as a system header, e.g.
260 /// due to #pragma GCC system_header.
261 void MarkFileSystemHeader(const FileEntry *File) {
262 getFileInfo(File).DirInfo = SrcMgr::C_System;
265 /// 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;
271 /// SetFileControllingMacro - Mark the specified file as having a controlling
272 /// macro. This is used by the multiple-include optimization to eliminate
274 void SetFileControllingMacro(const FileEntry *File,
275 const IdentifierInfo *ControllingMacro) {
276 getFileInfo(File).ControllingMacro = ControllingMacro;
279 /// \brief Determine whether this file is intended to be safe from
280 /// multiple inclusions, e.g., it has #pragma once or a controlling
283 /// This routine does not consider the effect of #import
284 bool isFileMultipleIncludeGuarded(const FileEntry *File);
286 /// CreateHeaderMap - This method returns a HeaderMap for the specified
287 /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
288 const HeaderMap *CreateHeaderMap(const FileEntry *FE);
290 void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
292 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(); }
297 // Used by ASTReader.
298 void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
300 // 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(); }
306 search_dir_iterator quoted_dir_begin() const {
307 return SearchDirs.begin();
309 search_dir_iterator quoted_dir_end() const {
310 return SearchDirs.begin() + AngledDirIdx;
313 search_dir_iterator angled_dir_begin() const {
314 return SearchDirs.begin() + AngledDirIdx;
316 search_dir_iterator angled_dir_end() const {
317 return SearchDirs.begin() + SystemDirIdx;
320 search_dir_iterator system_dir_begin() const {
321 return SearchDirs.begin() + SystemDirIdx;
323 search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
328 /// getFileInfo - Return the HeaderFileInfo structure for the specified
330 HeaderFileInfo &getFileInfo(const FileEntry *FE);
333 } // end namespace clang