]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.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 "llvm/ADT/StringSet.h"
20 #include "llvm/Support/Allocator.h"
21 #include <vector>
22
23 namespace clang {
24
25 class ExternalIdentifierLookup;
26 class FileEntry;
27 class FileManager;
28 class IdentifierInfo;
29
30 /// HeaderFileInfo - The preprocessor keeps track of this information for each
31 /// file that is #included.
32 struct HeaderFileInfo {
33   /// isImport - True if this is a #import'd or #pragma once file.
34   unsigned isImport : 1;
35
36   /// isPragmaOnce - True if this is  #pragma once file.
37   unsigned isPragmaOnce : 1;
38
39   /// DirInfo - Keep track of whether this is a system header, and if so,
40   /// whether it is C++ clean or not.  This can be set by the include paths or
41   /// by #pragma gcc system_header.  This is an instance of
42   /// SrcMgr::CharacteristicKind.
43   unsigned DirInfo : 2;
44
45   /// \brief Whether this header file info was supplied by an external source.
46   unsigned External : 1;
47   
48   /// \brief Whether this structure is considered to already have been
49   /// "resolved", meaning that it was loaded from the external source.
50   unsigned Resolved : 1;
51   
52   /// \brief Whether this is a header inside a framework that is currently
53   /// being built. 
54   ///
55   /// When a framework is being built, the headers have not yet been placed
56   /// into the appropriate framework subdirectories, and therefore are
57   /// provided via a header map. This bit indicates when this is one of
58   /// those framework headers.
59   unsigned IndexHeaderMapHeader : 1;
60   
61   /// NumIncludes - This is the number of times the file has been included
62   /// already.
63   unsigned short NumIncludes;
64
65   /// \brief The ID number of the controlling macro.
66   ///
67   /// This ID number will be non-zero when there is a controlling
68   /// macro whose IdentifierInfo may not yet have been loaded from
69   /// external storage.
70   unsigned ControllingMacroID;
71
72   /// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard
73   /// that protects the entire contents of the file, this is the identifier
74   /// for the macro that controls whether or not it has any effect.
75   ///
76   /// Note: Most clients should use getControllingMacro() to access
77   /// the controlling macro of this header, since
78   /// getControllingMacro() is able to load a controlling macro from
79   /// external storage.
80   const IdentifierInfo *ControllingMacro;
81
82   /// \brief If this header came from a framework include, this is the name
83   /// of the framework.
84   StringRef Framework;
85   
86   HeaderFileInfo()
87     : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), 
88       External(false), Resolved(false), IndexHeaderMapHeader(false),
89       NumIncludes(0), ControllingMacroID(0), ControllingMacro(0)  {}
90
91   /// \brief Retrieve the controlling macro for this header file, if
92   /// any.
93   const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
94   
95   /// \brief Determine whether this is a non-default header file info, e.g.,
96   /// it corresponds to an actual header we've included or tried to include.
97   bool isNonDefault() const {
98     return isImport || isPragmaOnce || NumIncludes || ControllingMacro || 
99       ControllingMacroID;
100   }
101 };
102
103 /// \brief An external source of header file information, which may supply
104 /// information about header files already included.
105 class ExternalHeaderFileInfoSource {
106 public:
107   virtual ~ExternalHeaderFileInfoSource();
108   
109   /// \brief Retrieve the header file information for the given file entry.
110   ///
111   /// \returns Header file information for the given file entry, with the
112   /// \c External bit set. If the file entry is not known, return a 
113   /// default-constructed \c HeaderFileInfo.
114   virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
115 };
116   
117 /// HeaderSearch - This class encapsulates the information needed to find the
118 /// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
119 class HeaderSearch {
120   FileManager &FileMgr;
121   /// #include search path information.  Requests for #include "x" search the
122   /// directory of the #including file first, then each directory in SearchDirs
123   /// consecutively. Requests for <x> search the current dir first, then each
124   /// directory in SearchDirs, starting at AngledDirIdx, consecutively.  If
125   /// NoCurDirSearch is true, then the check for the file in the current
126   /// directory is suppressed.
127   std::vector<DirectoryLookup> SearchDirs;
128   unsigned AngledDirIdx;
129   unsigned SystemDirIdx;
130   bool NoCurDirSearch;
131
132   /// \brief The path to the module cache.
133   std::string ModuleCachePath;
134   
135   /// \brief The name of the module we're building.
136   std::string BuildingModule;
137   
138   /// FileInfo - This contains all of the preprocessor-specific data about files
139   /// that are included.  The vector is indexed by the FileEntry's UID.
140   ///
141   std::vector<HeaderFileInfo> FileInfo;
142
143   /// LookupFileCache - This is keeps track of each lookup performed by
144   /// LookupFile.  The first part of the value is the starting index in
145   /// SearchDirs that the cached search was performed from.  If there is a hit
146   /// and this value doesn't match the current query, the cache has to be
147   /// ignored.  The second value is the entry in SearchDirs that satisfied the
148   /// query.
149   llvm::StringMap<std::pair<unsigned, unsigned>, llvm::BumpPtrAllocator>
150     LookupFileCache;
151
152
153   /// FrameworkMap - This is a collection mapping a framework or subframework
154   /// name like "Carbon" to the Carbon.framework directory.
155   llvm::StringMap<const DirectoryEntry *, llvm::BumpPtrAllocator>
156     FrameworkMap;
157
158   /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
159   /// headermaps.  This vector owns the headermap.
160   std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
161
162   /// \brief Uniqued set of framework names, which is used to track which 
163   /// headers were included as framework headers.
164   llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
165   
166   /// \brief Entity used to resolve the identifier IDs of controlling
167   /// macros into IdentifierInfo pointers, as needed.
168   ExternalIdentifierLookup *ExternalLookup;
169
170   /// \brief Entity used to look up stored header file information.
171   ExternalHeaderFileInfoSource *ExternalSource;
172   
173   // Various statistics we track for performance analysis.
174   unsigned NumIncluded;
175   unsigned NumMultiIncludeFileOptzn;
176   unsigned NumFrameworkLookups, NumSubFrameworkLookups;
177
178   // HeaderSearch doesn't support default or copy construction.
179   explicit HeaderSearch();
180   explicit HeaderSearch(const HeaderSearch&);
181   void operator=(const HeaderSearch&);
182 public:
183   HeaderSearch(FileManager &FM);
184   ~HeaderSearch();
185
186   FileManager &getFileMgr() const { return FileMgr; }
187
188   /// SetSearchPaths - Interface for setting the file search paths.
189   ///
190   void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
191                       unsigned angledDirIdx, unsigned systemDirIdx,
192                       bool noCurDirSearch) {
193     assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
194         "Directory indicies are unordered");
195     SearchDirs = dirs;
196     AngledDirIdx = angledDirIdx;
197     SystemDirIdx = systemDirIdx;
198     NoCurDirSearch = noCurDirSearch;
199     //LookupFileCache.clear();
200   }
201
202   /// \brief Set the path to the module cache and the name of the module
203   /// we're building
204   void configureModules(StringRef CachePath, StringRef BuildingModule) {
205     ModuleCachePath = CachePath;
206     this->BuildingModule = BuildingModule;
207   }
208   
209   /// ClearFileInfo - Forget everything we know about headers so far.
210   void ClearFileInfo() {
211     FileInfo.clear();
212   }
213
214   void SetExternalLookup(ExternalIdentifierLookup *EIL) {
215     ExternalLookup = EIL;
216   }
217
218   ExternalIdentifierLookup *getExternalLookup() const {
219     return ExternalLookup;
220   }
221   
222   /// \brief Set the external source of header information.
223   void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
224     ExternalSource = ES;
225   }
226   
227   /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
228   /// return null on failure.
229   ///
230   /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
231   /// the file was found in, or null if not applicable.
232   ///
233   /// \param isAngled indicates whether the file reference is a <> reference.
234   ///
235   /// \param CurDir If non-null, the file was found in the specified directory
236   /// search location.  This is used to implement #include_next.
237   ///
238   /// \param CurFileEnt If non-null, indicates where the #including file is, in
239   /// case a relative search is needed.
240   ///
241   /// \param SearchPath If non-null, will be set to the search path relative
242   /// to which the file was found. If the include path is absolute, SearchPath
243   /// will be set to an empty string.
244   ///
245   /// \param RelativePath If non-null, will be set to the path relative to
246   /// SearchPath at which the file was found. This only differs from the
247   /// Filename for framework includes.
248   ///
249   /// \param SuggestedModule If non-null, and the file found is semantically
250   /// part of a known module, this will be set to the name of the module that
251   /// could be imported instead of preprocessing/parsing the file found.
252   const FileEntry *LookupFile(StringRef Filename, bool isAngled,
253                               const DirectoryLookup *FromDir,
254                               const DirectoryLookup *&CurDir,
255                               const FileEntry *CurFileEnt,
256                               SmallVectorImpl<char> *SearchPath,
257                               SmallVectorImpl<char> *RelativePath,
258                               StringRef *SuggestedModule);
259
260   /// LookupSubframeworkHeader - Look up a subframework for the specified
261   /// #include file.  For example, if #include'ing <HIToolbox/HIToolbox.h> from
262   /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
263   /// is a subframework within Carbon.framework.  If so, return the FileEntry
264   /// for the designated file, otherwise return null.
265   const FileEntry *LookupSubframeworkHeader(
266       StringRef Filename,
267       const FileEntry *RelativeFileEnt,
268       SmallVectorImpl<char> *SearchPath,
269       SmallVectorImpl<char> *RelativePath);
270
271   /// LookupFrameworkCache - Look up the specified framework name in our
272   /// framework cache, returning the DirectoryEntry it is in if we know,
273   /// otherwise, return null.
274   const DirectoryEntry *&LookupFrameworkCache(StringRef FWName) {
275     return FrameworkMap.GetOrCreateValue(FWName).getValue();
276   }
277
278   /// ShouldEnterIncludeFile - Mark the specified file as a target of of a
279   /// #include, #include_next, or #import directive.  Return false if #including
280   /// the file will have no effect or true if we should include it.
281   bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
282
283
284   /// getFileDirFlavor - Return whether the specified file is a normal header,
285   /// a system header, or a C++ friendly system header.
286   SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
287     return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
288   }
289
290   /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.
291   /// due to #pragma once.
292   void MarkFileIncludeOnce(const FileEntry *File) {
293     HeaderFileInfo &FI = getFileInfo(File);
294     FI.isImport = true;
295     FI.isPragmaOnce = true;
296   }
297
298   /// MarkFileSystemHeader - Mark the specified file as a system header, e.g.
299   /// due to #pragma GCC system_header.
300   void MarkFileSystemHeader(const FileEntry *File) {
301     getFileInfo(File).DirInfo = SrcMgr::C_System;
302   }
303
304   /// IncrementIncludeCount - Increment the count for the number of times the
305   /// specified FileEntry has been entered.
306   void IncrementIncludeCount(const FileEntry *File) {
307     ++getFileInfo(File).NumIncludes;
308   }
309
310   /// SetFileControllingMacro - Mark the specified file as having a controlling
311   /// macro.  This is used by the multiple-include optimization to eliminate
312   /// no-op #includes.
313   void SetFileControllingMacro(const FileEntry *File,
314                                const IdentifierInfo *ControllingMacro) {
315     getFileInfo(File).ControllingMacro = ControllingMacro;
316   }
317
318   /// \brief Determine whether this file is intended to be safe from
319   /// multiple inclusions, e.g., it has #pragma once or a controlling
320   /// macro.
321   ///
322   /// This routine does not consider the effect of #import 
323   bool isFileMultipleIncludeGuarded(const FileEntry *File);
324
325   /// CreateHeaderMap - This method returns a HeaderMap for the specified
326   /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
327   const HeaderMap *CreateHeaderMap(const FileEntry *FE);
328
329   /// \brief Search in the module cache path for a module with the given
330   /// name.
331   ///
332   /// \param If non-NULL, will be set to the module file name we expected to
333   /// find (regardless of whether it was actually found or not).
334   ///
335   /// \param UmbrellaHeader If non-NULL, and no module was found in the module
336   /// cache, this routine will search in the framework paths to determine
337   /// whether a module can be built from an umbrella header. If so, the pointee
338   /// will be set to the path of the umbrella header.
339   ///
340   /// \returns A file describing the named module, if available, or NULL to
341   /// indicate that the module could not be found.
342   const FileEntry *lookupModule(StringRef ModuleName,
343                                 std::string *ModuleFileName = 0,
344                                 std::string *UmbrellaHeader = 0);
345   
346   void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
347
348   typedef std::vector<HeaderFileInfo>::const_iterator header_file_iterator;
349   header_file_iterator header_file_begin() const { return FileInfo.begin(); }
350   header_file_iterator header_file_end() const { return FileInfo.end(); }
351   unsigned header_file_size() const { return FileInfo.size(); }
352
353   // Used by ASTReader.
354   void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
355
356   // Used by external tools
357   typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
358   search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
359   search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
360   unsigned search_dir_size() const { return SearchDirs.size(); }
361
362   search_dir_iterator quoted_dir_begin() const {
363     return SearchDirs.begin();
364   }
365   search_dir_iterator quoted_dir_end() const {
366     return SearchDirs.begin() + AngledDirIdx;
367   }
368
369   search_dir_iterator angled_dir_begin() const {
370     return SearchDirs.begin() + AngledDirIdx;
371   }
372   search_dir_iterator angled_dir_end() const {
373     return SearchDirs.begin() + SystemDirIdx;
374   }
375
376   search_dir_iterator system_dir_begin() const {
377     return SearchDirs.begin() + SystemDirIdx;
378   }
379   search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
380
381   /// \brief Retrieve a uniqued framework name.
382   StringRef getUniqueFrameworkName(StringRef Framework);
383   
384   void PrintStats();
385   
386   size_t getTotalMemory() const;
387
388 private:
389
390   /// getFileInfo - Return the HeaderFileInfo structure for the specified
391   /// FileEntry.
392   HeaderFileInfo &getFileInfo(const FileEntry *FE);
393 };
394
395 }  // end namespace clang
396
397 #endif