• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "clang/Lex/ModuleMap.h"
19 #include "llvm/ADT/StringMap.h"
20 #include "llvm/ADT/StringSet.h"
21 #include "llvm/Support/Allocator.h"
22 #include "llvm/ADT/OwningPtr.h"
23 #include <vector>
24 
25 namespace clang {
26 
27 class DiagnosticsEngine;
28 class ExternalIdentifierLookup;
29 class FileEntry;
30 class FileManager;
31 class IdentifierInfo;
32 
33 /// HeaderFileInfo - The preprocessor keeps track of this information for each
34 /// file that is #included.
35 struct HeaderFileInfo {
36   /// isImport - True if this is a #import'd or #pragma once file.
37   unsigned isImport : 1;
38 
39   /// isPragmaOnce - True if this is  #pragma once file.
40   unsigned isPragmaOnce : 1;
41 
42   /// DirInfo - Keep track of whether this is a system header, and if so,
43   /// whether it is C++ clean or not.  This can be set by the include paths or
44   /// by #pragma gcc system_header.  This is an instance of
45   /// SrcMgr::CharacteristicKind.
46   unsigned DirInfo : 2;
47 
48   /// \brief Whether this header file info was supplied by an external source.
49   unsigned External : 1;
50 
51   /// \brief Whether this structure is considered to already have been
52   /// "resolved", meaning that it was loaded from the external source.
53   unsigned Resolved : 1;
54 
55   /// \brief Whether this is a header inside a framework that is currently
56   /// being built.
57   ///
58   /// When a framework is being built, the headers have not yet been placed
59   /// into the appropriate framework subdirectories, and therefore are
60   /// provided via a header map. This bit indicates when this is one of
61   /// those framework headers.
62   unsigned IndexHeaderMapHeader : 1;
63 
64   /// NumIncludes - This is the number of times the file has been included
65   /// already.
66   unsigned short NumIncludes;
67 
68   /// \brief The ID number of the controlling macro.
69   ///
70   /// This ID number will be non-zero when there is a controlling
71   /// macro whose IdentifierInfo may not yet have been loaded from
72   /// external storage.
73   unsigned ControllingMacroID;
74 
75   /// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard
76   /// that protects the entire contents of the file, this is the identifier
77   /// for the macro that controls whether or not it has any effect.
78   ///
79   /// Note: Most clients should use getControllingMacro() to access
80   /// the controlling macro of this header, since
81   /// getControllingMacro() is able to load a controlling macro from
82   /// external storage.
83   const IdentifierInfo *ControllingMacro;
84 
85   /// \brief If this header came from a framework include, this is the name
86   /// of the framework.
87   StringRef Framework;
88 
HeaderFileInfoHeaderFileInfo89   HeaderFileInfo()
90     : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
91       External(false), Resolved(false), IndexHeaderMapHeader(false),
92       NumIncludes(0), ControllingMacroID(0), ControllingMacro(0)  {}
93 
94   /// \brief Retrieve the controlling macro for this header file, if
95   /// any.
96   const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
97 
98   /// \brief Determine whether this is a non-default header file info, e.g.,
99   /// it corresponds to an actual header we've included or tried to include.
isNonDefaultHeaderFileInfo100   bool isNonDefault() const {
101     return isImport || isPragmaOnce || NumIncludes || ControllingMacro ||
102       ControllingMacroID;
103   }
104 };
105 
106 /// \brief An external source of header file information, which may supply
107 /// information about header files already included.
108 class ExternalHeaderFileInfoSource {
109 public:
110   virtual ~ExternalHeaderFileInfoSource();
111 
112   /// \brief Retrieve the header file information for the given file entry.
113   ///
114   /// \returns Header file information for the given file entry, with the
115   /// \c External bit set. If the file entry is not known, return a
116   /// default-constructed \c HeaderFileInfo.
117   virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
118 };
119 
120 /// HeaderSearch - This class encapsulates the information needed to find the
121 /// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
122 class HeaderSearch {
123   /// This structure is used to record entries in our framework cache.
124   struct FrameworkCacheEntry {
125     /// The directory entry which should be used for the cached framework.
126     const DirectoryEntry *Directory;
127 
128     /// Whether this framework has been "user-specified" to be treated as if it
129     /// were a system framework (even if it was found outside a system framework
130     /// directory).
131     bool IsUserSpecifiedSystemFramework;
132   };
133 
134   FileManager &FileMgr;
135   DiagnosticsEngine &Diags;
136   /// #include search path information.  Requests for #include "x" search the
137   /// directory of the #including file first, then each directory in SearchDirs
138   /// consecutively. Requests for <x> search the current dir first, then each
139   /// directory in SearchDirs, starting at AngledDirIdx, consecutively.  If
140   /// NoCurDirSearch is true, then the check for the file in the current
141   /// directory is suppressed.
142   std::vector<DirectoryLookup> SearchDirs;
143   unsigned AngledDirIdx;
144   unsigned SystemDirIdx;
145   bool NoCurDirSearch;
146 
147   /// \brief The path to the module cache.
148   std::string ModuleCachePath;
149 
150   /// FileInfo - This contains all of the preprocessor-specific data about files
151   /// that are included.  The vector is indexed by the FileEntry's UID.
152   ///
153   std::vector<HeaderFileInfo> FileInfo;
154 
155   /// LookupFileCache - This is keeps track of each lookup performed by
156   /// LookupFile.  The first part of the value is the starting index in
157   /// SearchDirs that the cached search was performed from.  If there is a hit
158   /// and this value doesn't match the current query, the cache has to be
159   /// ignored.  The second value is the entry in SearchDirs that satisfied the
160   /// query.
161   llvm::StringMap<std::pair<unsigned, unsigned>, llvm::BumpPtrAllocator>
162     LookupFileCache;
163 
164   /// FrameworkMap - This is a collection mapping a framework or subframework
165   /// name like "Carbon" to the Carbon.framework directory.
166   llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap;
167 
168   /// IncludeAliases - maps include file names (including the quotes or
169   /// angle brackets) to other include file names.  This is used to support the
170   /// include_alias pragma for Microsoft compatibility.
171   typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator>
172     IncludeAliasMap;
173   OwningPtr<IncludeAliasMap> IncludeAliases;
174 
175   /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
176   /// headermaps.  This vector owns the headermap.
177   std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
178 
179   /// \brief The mapping between modules and headers.
180   ModuleMap ModMap;
181 
182   /// \brief Describes whether a given directory has a module map in it.
183   llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
184 
185   /// \brief Uniqued set of framework names, which is used to track which
186   /// headers were included as framework headers.
187   llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
188 
189   /// \brief Entity used to resolve the identifier IDs of controlling
190   /// macros into IdentifierInfo pointers, as needed.
191   ExternalIdentifierLookup *ExternalLookup;
192 
193   /// \brief Entity used to look up stored header file information.
194   ExternalHeaderFileInfoSource *ExternalSource;
195 
196   // Various statistics we track for performance analysis.
197   unsigned NumIncluded;
198   unsigned NumMultiIncludeFileOptzn;
199   unsigned NumFrameworkLookups, NumSubFrameworkLookups;
200 
201   // HeaderSearch doesn't support default or copy construction.
202   explicit HeaderSearch();
203   explicit HeaderSearch(const HeaderSearch&);
204   void operator=(const HeaderSearch&);
205 
206   friend class DirectoryLookup;
207 
208 public:
209   HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags,
210                const LangOptions &LangOpts, const TargetInfo *Target);
211   ~HeaderSearch();
212 
getFileMgr()213   FileManager &getFileMgr() const { return FileMgr; }
214 
215   /// SetSearchPaths - Interface for setting the file search paths.
216   ///
SetSearchPaths(const std::vector<DirectoryLookup> & dirs,unsigned angledDirIdx,unsigned systemDirIdx,bool noCurDirSearch)217   void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
218                       unsigned angledDirIdx, unsigned systemDirIdx,
219                       bool noCurDirSearch) {
220     assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
221         "Directory indicies are unordered");
222     SearchDirs = dirs;
223     AngledDirIdx = angledDirIdx;
224     SystemDirIdx = systemDirIdx;
225     NoCurDirSearch = noCurDirSearch;
226     //LookupFileCache.clear();
227   }
228 
229   /// AddSearchPath - Add an additional search path.
AddSearchPath(const DirectoryLookup & dir,bool isAngled)230   void AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
231     unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
232     SearchDirs.insert(SearchDirs.begin() + idx, dir);
233     if (!isAngled)
234       AngledDirIdx++;
235     SystemDirIdx++;
236   }
237 
238   /// HasIncludeAliasMap - Checks whether the map exists or not
HasIncludeAliasMap()239   bool HasIncludeAliasMap() const {
240     return IncludeAliases;
241   }
242 
243   /// AddIncludeAlias - Map the source include name to the dest include name.
244   /// The Source should include the angle brackets or quotes, the dest
245   /// should not.  This allows for distinction between <> and "" headers.
AddIncludeAlias(StringRef Source,StringRef Dest)246   void AddIncludeAlias(StringRef Source, StringRef Dest) {
247     if (!IncludeAliases)
248       IncludeAliases.reset(new IncludeAliasMap);
249     (*IncludeAliases)[Source] = Dest;
250   }
251 
252   /// MapHeaderToIncludeAlias - Maps one header file name to a different header
253   /// file name, for use with the include_alias pragma.  Note that the source
254   /// file name should include the angle brackets or quotes.  Returns StringRef
255   /// as null if the header cannot be mapped.
MapHeaderToIncludeAlias(StringRef Source)256   StringRef MapHeaderToIncludeAlias(StringRef Source) {
257     assert(IncludeAliases && "Trying to map headers when there's no map");
258 
259     // Do any filename replacements before anything else
260     IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source);
261     if (Iter != IncludeAliases->end())
262       return Iter->second;
263     return StringRef();
264   }
265 
266   /// \brief Set the path to the module cache.
setModuleCachePath(StringRef CachePath)267   void setModuleCachePath(StringRef CachePath) {
268     ModuleCachePath = CachePath;
269   }
270 
271   /// \brief Retrieve the path to the module cache.
getModuleCachePath()272   StringRef getModuleCachePath() const { return ModuleCachePath; }
273 
274   /// ClearFileInfo - Forget everything we know about headers so far.
ClearFileInfo()275   void ClearFileInfo() {
276     FileInfo.clear();
277   }
278 
SetExternalLookup(ExternalIdentifierLookup * EIL)279   void SetExternalLookup(ExternalIdentifierLookup *EIL) {
280     ExternalLookup = EIL;
281   }
282 
getExternalLookup()283   ExternalIdentifierLookup *getExternalLookup() const {
284     return ExternalLookup;
285   }
286 
287   /// \brief Set the external source of header information.
SetExternalSource(ExternalHeaderFileInfoSource * ES)288   void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
289     ExternalSource = ES;
290   }
291 
292   /// \brief Set the target information for the header search, if not
293   /// already known.
294   void setTarget(const TargetInfo &Target);
295 
296   /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
297   /// return null on failure.
298   ///
299   /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
300   /// the file was found in, or null if not applicable.
301   ///
302   /// \param isAngled indicates whether the file reference is a <> reference.
303   ///
304   /// \param CurDir If non-null, the file was found in the specified directory
305   /// search location.  This is used to implement #include_next.
306   ///
307   /// \param CurFileEnt If non-null, indicates where the #including file is, in
308   /// case a relative search is needed.
309   ///
310   /// \param SearchPath If non-null, will be set to the search path relative
311   /// to which the file was found. If the include path is absolute, SearchPath
312   /// will be set to an empty string.
313   ///
314   /// \param RelativePath If non-null, will be set to the path relative to
315   /// SearchPath at which the file was found. This only differs from the
316   /// Filename for framework includes.
317   ///
318   /// \param SuggestedModule If non-null, and the file found is semantically
319   /// part of a known module, this will be set to the module that should
320   /// be imported instead of preprocessing/parsing the file found.
321   const FileEntry *LookupFile(StringRef Filename, bool isAngled,
322                               const DirectoryLookup *FromDir,
323                               const DirectoryLookup *&CurDir,
324                               const FileEntry *CurFileEnt,
325                               SmallVectorImpl<char> *SearchPath,
326                               SmallVectorImpl<char> *RelativePath,
327                               Module **SuggestedModule,
328                               bool SkipCache = false);
329 
330   /// LookupSubframeworkHeader - Look up a subframework for the specified
331   /// #include file.  For example, if #include'ing <HIToolbox/HIToolbox.h> from
332   /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
333   /// is a subframework within Carbon.framework.  If so, return the FileEntry
334   /// for the designated file, otherwise return null.
335   const FileEntry *LookupSubframeworkHeader(
336       StringRef Filename,
337       const FileEntry *RelativeFileEnt,
338       SmallVectorImpl<char> *SearchPath,
339       SmallVectorImpl<char> *RelativePath);
340 
341   /// LookupFrameworkCache - Look up the specified framework name in our
342   /// framework cache, returning the DirectoryEntry it is in if we know,
343   /// otherwise, return null.
LookupFrameworkCache(StringRef FWName)344   FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) {
345     return FrameworkMap.GetOrCreateValue(FWName).getValue();
346   }
347 
348   /// ShouldEnterIncludeFile - Mark the specified file as a target of of a
349   /// #include, #include_next, or #import directive.  Return false if #including
350   /// the file will have no effect or true if we should include it.
351   bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
352 
353 
354   /// getFileDirFlavor - Return whether the specified file is a normal header,
355   /// a system header, or a C++ friendly system header.
getFileDirFlavor(const FileEntry * File)356   SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
357     return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
358   }
359 
360   /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.
361   /// due to #pragma once.
MarkFileIncludeOnce(const FileEntry * File)362   void MarkFileIncludeOnce(const FileEntry *File) {
363     HeaderFileInfo &FI = getFileInfo(File);
364     FI.isImport = true;
365     FI.isPragmaOnce = true;
366   }
367 
368   /// MarkFileSystemHeader - Mark the specified file as a system header, e.g.
369   /// due to #pragma GCC system_header.
MarkFileSystemHeader(const FileEntry * File)370   void MarkFileSystemHeader(const FileEntry *File) {
371     getFileInfo(File).DirInfo = SrcMgr::C_System;
372   }
373 
374   /// IncrementIncludeCount - Increment the count for the number of times the
375   /// specified FileEntry has been entered.
IncrementIncludeCount(const FileEntry * File)376   void IncrementIncludeCount(const FileEntry *File) {
377     ++getFileInfo(File).NumIncludes;
378   }
379 
380   /// SetFileControllingMacro - Mark the specified file as having a controlling
381   /// macro.  This is used by the multiple-include optimization to eliminate
382   /// no-op #includes.
SetFileControllingMacro(const FileEntry * File,const IdentifierInfo * ControllingMacro)383   void SetFileControllingMacro(const FileEntry *File,
384                                const IdentifierInfo *ControllingMacro) {
385     getFileInfo(File).ControllingMacro = ControllingMacro;
386   }
387 
388   /// \brief Determine whether this file is intended to be safe from
389   /// multiple inclusions, e.g., it has #pragma once or a controlling
390   /// macro.
391   ///
392   /// This routine does not consider the effect of #import
393   bool isFileMultipleIncludeGuarded(const FileEntry *File);
394 
395   /// CreateHeaderMap - This method returns a HeaderMap for the specified
396   /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
397   const HeaderMap *CreateHeaderMap(const FileEntry *FE);
398 
399   /// \brief Retrieve the name of the module file that should be used to
400   /// load the given module.
401   ///
402   /// \param Module The module whose module file name will be returned.
403   ///
404   /// \returns The name of the module file that corresponds to this module,
405   /// or an empty string if this module does not correspond to any module file.
406   std::string getModuleFileName(Module *Module);
407 
408   /// \brief Retrieve the name of the module file that should be used to
409   /// load a module with the given name.
410   ///
411   /// \param Module The module whose module file name will be returned.
412   ///
413   /// \returns The name of the module file that corresponds to this module,
414   /// or an empty string if this module does not correspond to any module file.
415   std::string getModuleFileName(StringRef ModuleName);
416 
417   /// \brief Lookup a module Search for a module with the given name.
418   ///
419   /// \param ModuleName The name of the module we're looking for.
420   ///
421   /// \param AllowSearch Whether we are allowed to search in the various
422   /// search directories to produce a module definition. If not, this lookup
423   /// will only return an already-known module.
424   ///
425   /// \returns The module with the given name.
426   Module *lookupModule(StringRef ModuleName, bool AllowSearch = true);
427 
IncrementFrameworkLookupCount()428   void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
429 
430   /// \brief Determine whether there is a module map that may map the header
431   /// with the given file name to a (sub)module.
432   ///
433   /// \param Filename The name of the file.
434   ///
435   /// \param Root The "root" directory, at which we should stop looking for
436   /// module maps.
437   bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root);
438 
439   /// \brief Retrieve the module that corresponds to the given file, if any.
440   ///
441   /// \param File The header that we wish to map to a module.
442   Module *findModuleForHeader(const FileEntry *File);
443 
444   /// \brief Read the contents of the given module map file.
445   ///
446   /// \param File The module map file.
447   ///
448   /// \param OnlyModule If non-NULL, this will receive the
449   ///
450   /// \returns true if an error occurred, false otherwise.
451   bool loadModuleMapFile(const FileEntry *File);
452 
453   /// \brief Collect the set of all known, top-level modules.
454   ///
455   /// \param Modules Will be filled with the set of known, top-level modules.
456   void collectAllModules(llvm::SmallVectorImpl<Module *> &Modules);
457 
458 private:
459   /// \brief Retrieve a module with the given name, which may be part of the
460   /// given framework.
461   ///
462   /// \param Name The name of the module to retrieve.
463   ///
464   /// \param Dir The framework directory (e.g., ModuleName.framework).
465   ///
466   /// \param IsSystem Whether the framework directory is part of the system
467   /// frameworks.
468   ///
469   /// \returns The module, if found; otherwise, null.
470   Module *loadFrameworkModule(StringRef Name,
471                               const DirectoryEntry *Dir,
472                               bool IsSystem);
473 
474 public:
475   /// \brief Retrieve the module map.
getModuleMap()476   ModuleMap &getModuleMap() { return ModMap; }
477 
header_file_size()478   unsigned header_file_size() const { return FileInfo.size(); }
479 
480   // Used by ASTReader.
481   void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
482 
483   /// getFileInfo - Return the HeaderFileInfo structure for the specified
484   /// FileEntry.
getFileInfo(const FileEntry * FE)485   const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
486     return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
487   }
488 
489   // Used by external tools
490   typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
search_dir_begin()491   search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
search_dir_end()492   search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
search_dir_size()493   unsigned search_dir_size() const { return SearchDirs.size(); }
494 
quoted_dir_begin()495   search_dir_iterator quoted_dir_begin() const {
496     return SearchDirs.begin();
497   }
quoted_dir_end()498   search_dir_iterator quoted_dir_end() const {
499     return SearchDirs.begin() + AngledDirIdx;
500   }
501 
angled_dir_begin()502   search_dir_iterator angled_dir_begin() const {
503     return SearchDirs.begin() + AngledDirIdx;
504   }
angled_dir_end()505   search_dir_iterator angled_dir_end() const {
506     return SearchDirs.begin() + SystemDirIdx;
507   }
508 
system_dir_begin()509   search_dir_iterator system_dir_begin() const {
510     return SearchDirs.begin() + SystemDirIdx;
511   }
system_dir_end()512   search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
513 
514   /// \brief Retrieve a uniqued framework name.
515   StringRef getUniqueFrameworkName(StringRef Framework);
516 
517   void PrintStats();
518 
519   size_t getTotalMemory() const;
520 
521   static std::string NormalizeDashIncludePath(StringRef File,
522                                               FileManager &FileMgr);
523 
524 private:
525   /// \brief Describes what happened when we tried to load a module map file.
526   enum LoadModuleMapResult {
527     /// \brief The module map file had already been loaded.
528     LMM_AlreadyLoaded,
529     /// \brief The module map file was loaded by this invocation.
530     LMM_NewlyLoaded,
531     /// \brief There is was directory with the given name.
532     LMM_NoDirectory,
533     /// \brief There was either no module map file or the module map file was
534     /// invalid.
535     LMM_InvalidModuleMap
536   };
537 
538   /// \brief Try to load the module map file in the given directory.
539   ///
540   /// \param DirName The name of the directory where we will look for a module
541   /// map file.
542   ///
543   /// \returns The result of attempting to load the module map file from the
544   /// named directory.
545   LoadModuleMapResult loadModuleMapFile(StringRef DirName);
546 
547   /// \brief Try to load the module map file in the given directory.
548   ///
549   /// \param Dir The directory where we will look for a module map file.
550   ///
551   /// \returns The result of attempting to load the module map file from the
552   /// named directory.
553   LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir);
554 
555   /// getFileInfo - Return the HeaderFileInfo structure for the specified
556   /// FileEntry.
557   HeaderFileInfo &getFileInfo(const FileEntry *FE);
558 };
559 
560 }  // end namespace clang
561 
562 #endif
563