]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / include / clang / Lex / HeaderSearch.h
1 //===--- HeaderSearch.h - Resolve Header File Locations ---------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
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
21 namespace clang {
22
23 class ExternalIdentifierLookup;
24 class FileEntry;
25 class FileManager;
26 class IdentifierInfo;
27
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;
33
34   /// isPragmaOnce - True if this is  #pragma once file.
35   unsigned isPragmaOnce : 1;
36
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.
41   unsigned DirInfo : 2;
42
43   /// \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   
50   /// NumIncludes - This is the number of times the file has been included
51   /// already.
52   unsigned short NumIncludes;
53
54   /// \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
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.
64   ///
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.
69   const IdentifierInfo *ControllingMacro;
70
71   HeaderFileInfo()
72     : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), 
73       External(false), Resolved(false), NumIncludes(0), ControllingMacroID(0), 
74       ControllingMacro(0)  {}
75
76   /// \brief Retrieve the controlling macro for this header file, if
77   /// any.
78   const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
79   
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 || 
84       ControllingMacroID;
85   }
86 };
87
88 /// \brief An external source of header file information, which may supply
89 /// information about header files already included.
90 class ExternalHeaderFileInfoSource {
91 public:
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   
102 /// HeaderSearch - This class encapsulates the information needed to find the
103 /// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
104 class HeaderSearch {
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;
115   bool NoCurDirSearch;
116
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.
119   ///
120   std::vector<HeaderFileInfo> FileInfo;
121
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
127   /// query.
128   llvm::StringMap<std::pair<unsigned, unsigned> > LookupFileCache;
129
130
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;
134
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;
138
139   /// \brief Entity used to resolve the identifier IDs of controlling
140   /// macros into IdentifierInfo pointers, as needed.
141   ExternalIdentifierLookup *ExternalLookup;
142
143   /// \brief Entity used to look up stored header file information.
144   ExternalHeaderFileInfoSource *ExternalSource;
145   
146   // Various statistics we track for performance analysis.
147   unsigned NumIncluded;
148   unsigned NumMultiIncludeFileOptzn;
149   unsigned NumFrameworkLookups, NumSubFrameworkLookups;
150
151   // HeaderSearch doesn't support default or copy construction.
152   explicit HeaderSearch();
153   explicit HeaderSearch(const HeaderSearch&);
154   void operator=(const HeaderSearch&);
155 public:
156   HeaderSearch(FileManager &FM);
157   ~HeaderSearch();
158
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,
164                       unsigned angledDirIdx, unsigned systemDirIdx,
165                       bool noCurDirSearch) {
166     assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
167         "Directory indicies are unordered");
168     SearchDirs = dirs;
169     AngledDirIdx = angledDirIdx;
170     SystemDirIdx = systemDirIdx;
171     NoCurDirSearch = noCurDirSearch;
172     //LookupFileCache.clear();
173   }
174
175   /// ClearFileInfo - Forget everything we know about headers so far.
176   void ClearFileInfo() {
177     FileInfo.clear();
178   }
179
180   void SetExternalLookup(ExternalIdentifierLookup *EIL) {
181     ExternalLookup = EIL;
182   }
183
184   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   
193   /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
194   /// 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.
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);
220
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);
231
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();
237   }
238
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);
243
244
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;
249   }
250
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);
255     FI.isImport = true;
256     FI.isPragmaOnce = true;
257   }
258
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;
263   }
264
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;
269   }
270
271   /// 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   }
278
279   /// \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
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);
289
290   void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
291
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(); }
296
297   // Used by ASTReader.
298   void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
299
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(); }
305
306   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
320   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
325   void PrintStats();
326 private:
327
328   /// getFileInfo - Return the HeaderFileInfo structure for the specified
329   /// FileEntry.
330   HeaderFileInfo &getFileInfo(const FileEntry *FE);
331 };
332
333 }  // end namespace clang
334
335 #endif