diff options
author | dim <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
commit | 50b73317314e889cf39c7b1d6cbf419fa7502f22 (patch) | |
tree | be1815eb79b42ff482a8562b13c2dcbf0c5dcbee /include/clang/Lex/HeaderSearch.h | |
parent | dc04cb328508e61aad809d9b53b12f9799a00e7d (diff) | |
download | FreeBSD-src-50b73317314e889cf39c7b1d6cbf419fa7502f22.zip FreeBSD-src-50b73317314e889cf39c7b1d6cbf419fa7502f22.tar.gz |
Vendor import of clang trunk r154661:
http://llvm.org/svn/llvm-project/cfe/trunk@r154661
Diffstat (limited to 'include/clang/Lex/HeaderSearch.h')
-rw-r--r-- | include/clang/Lex/HeaderSearch.h | 229 |
1 files changed, 197 insertions, 32 deletions
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 84d59f7..5128ce6 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -15,13 +15,16 @@ #define LLVM_CLANG_LEX_HEADERSEARCH_H #include "clang/Lex/DirectoryLookup.h" +#include "clang/Lex/ModuleMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/Allocator.h" +#include "llvm/ADT/OwningPtr.h" #include <vector> namespace clang { - + +class DiagnosticsEngine; class ExternalIdentifierLookup; class FileEntry; class FileManager; @@ -117,7 +120,19 @@ public: /// HeaderSearch - This class encapsulates the information needed to find the /// file referenced by a #include or #include_next, (sub-)framework lookup, etc. class HeaderSearch { + /// This structure is used to record entries in our framework cache. + struct FrameworkCacheEntry { + /// The directory entry which should be used for the cached framework. + const DirectoryEntry *Directory; + + /// Whether this framework has been "user-specified" to be treated as if it + /// were a system framework (even if it was found outside a system framework + /// directory). + bool IsUserSpecifiedSystemFramework; + }; + FileManager &FileMgr; + DiagnosticsEngine &Diags; /// #include search path information. Requests for #include "x" search the /// directory of the #including file first, then each directory in SearchDirs /// consecutively. Requests for <x> search the current dir first, then each @@ -132,9 +147,6 @@ class HeaderSearch { /// \brief The path to the module cache. std::string ModuleCachePath; - /// \brief The name of the module we're building. - std::string BuildingModule; - /// FileInfo - This contains all of the preprocessor-specific data about files /// that are included. The vector is indexed by the FileEntry's UID. /// @@ -149,16 +161,27 @@ class HeaderSearch { llvm::StringMap<std::pair<unsigned, unsigned>, llvm::BumpPtrAllocator> LookupFileCache; - /// FrameworkMap - This is a collection mapping a framework or subframework /// name like "Carbon" to the Carbon.framework directory. - llvm::StringMap<const DirectoryEntry *, llvm::BumpPtrAllocator> - FrameworkMap; + llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap; + + /// IncludeAliases - maps include file names (including the quotes or + /// angle brackets) to other include file names. This is used to support the + /// include_alias pragma for Microsoft compatibility. + typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator> + IncludeAliasMap; + OwningPtr<IncludeAliasMap> IncludeAliases; /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing /// headermaps. This vector owns the headermap. std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps; + /// \brief The mapping between modules and headers. + ModuleMap ModMap; + + /// \brief Describes whether a given directory has a module map in it. + llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap; + /// \brief Uniqued set of framework names, which is used to track which /// headers were included as framework headers. llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames; @@ -179,8 +202,12 @@ class HeaderSearch { explicit HeaderSearch(); explicit HeaderSearch(const HeaderSearch&); void operator=(const HeaderSearch&); + + friend class DirectoryLookup; + public: - HeaderSearch(FileManager &FM); + HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags, + const LangOptions &LangOpts, const TargetInfo *Target); ~HeaderSearch(); FileManager &getFileMgr() const { return FileMgr; } @@ -199,13 +226,51 @@ public: //LookupFileCache.clear(); } - /// \brief Set the path to the module cache and the name of the module - /// we're building - void configureModules(StringRef CachePath, StringRef BuildingModule) { + /// AddSearchPath - Add an additional search path. + void AddSearchPath(const DirectoryLookup &dir, bool isAngled) { + unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx; + SearchDirs.insert(SearchDirs.begin() + idx, dir); + if (!isAngled) + AngledDirIdx++; + SystemDirIdx++; + } + + /// HasIncludeAliasMap - Checks whether the map exists or not + bool HasIncludeAliasMap() const { + return IncludeAliases; + } + + /// AddIncludeAlias - Map the source include name to the dest include name. + /// The Source should include the angle brackets or quotes, the dest + /// should not. This allows for distinction between <> and "" headers. + void AddIncludeAlias(StringRef Source, StringRef Dest) { + if (!IncludeAliases) + IncludeAliases.reset(new IncludeAliasMap); + (*IncludeAliases)[Source] = Dest; + } + + /// MapHeaderToIncludeAlias - Maps one header file name to a different header + /// file name, for use with the include_alias pragma. Note that the source + /// file name should include the angle brackets or quotes. Returns StringRef + /// as null if the header cannot be mapped. + StringRef MapHeaderToIncludeAlias(StringRef Source) { + assert(IncludeAliases && "Trying to map headers when there's no map"); + + // Do any filename replacements before anything else + IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source); + if (Iter != IncludeAliases->end()) + return Iter->second; + return StringRef(); + } + + /// \brief Set the path to the module cache. + void setModuleCachePath(StringRef CachePath) { ModuleCachePath = CachePath; - this->BuildingModule = BuildingModule; } + /// \brief Retrieve the path to the module cache. + StringRef getModuleCachePath() const { return ModuleCachePath; } + /// ClearFileInfo - Forget everything we know about headers so far. void ClearFileInfo() { FileInfo.clear(); @@ -224,6 +289,10 @@ public: ExternalSource = ES; } + /// \brief Set the target information for the header search, if not + /// already known. + void setTarget(const TargetInfo &Target); + /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file, /// return null on failure. /// @@ -247,15 +316,16 @@ public: /// Filename for framework includes. /// /// \param SuggestedModule If non-null, and the file found is semantically - /// part of a known module, this will be set to the name of the module that - /// could be imported instead of preprocessing/parsing the file found. + /// part of a known module, this will be set to the module that should + /// be imported instead of preprocessing/parsing the file found. const FileEntry *LookupFile(StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, const FileEntry *CurFileEnt, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - StringRef *SuggestedModule); + Module **SuggestedModule, + bool SkipCache = false); /// LookupSubframeworkHeader - Look up a subframework for the specified /// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from @@ -271,7 +341,7 @@ public: /// LookupFrameworkCache - Look up the specified framework name in our /// framework cache, returning the DirectoryEntry it is in if we know, /// otherwise, return null. - const DirectoryEntry *&LookupFrameworkCache(StringRef FWName) { + FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) { return FrameworkMap.GetOrCreateValue(FWName).getValue(); } @@ -326,33 +396,96 @@ public: /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure. const HeaderMap *CreateHeaderMap(const FileEntry *FE); - /// \brief Search in the module cache path for a module with the given - /// name. + /// \brief Retrieve the name of the module file that should be used to + /// load the given module. /// - /// \param If non-NULL, will be set to the module file name we expected to - /// find (regardless of whether it was actually found or not). + /// \param Module The module whose module file name will be returned. /// - /// \param UmbrellaHeader If non-NULL, and no module was found in the module - /// cache, this routine will search in the framework paths to determine - /// whether a module can be built from an umbrella header. If so, the pointee - /// will be set to the path of the umbrella header. + /// \returns The name of the module file that corresponds to this module, + /// or an empty string if this module does not correspond to any module file. + std::string getModuleFileName(Module *Module); + + /// \brief Retrieve the name of the module file that should be used to + /// load a module with the given name. + /// + /// \param Module The module whose module file name will be returned. + /// + /// \returns The name of the module file that corresponds to this module, + /// or an empty string if this module does not correspond to any module file. + std::string getModuleFileName(StringRef ModuleName); + + /// \brief Lookup a module Search for a module with the given name. /// - /// \returns A file describing the named module, if available, or NULL to - /// indicate that the module could not be found. - const FileEntry *lookupModule(StringRef ModuleName, - std::string *ModuleFileName = 0, - std::string *UmbrellaHeader = 0); + /// \param ModuleName The name of the module we're looking for. + /// + /// \param AllowSearch Whether we are allowed to search in the various + /// search directories to produce a module definition. If not, this lookup + /// will only return an already-known module. + /// + /// \returns The module with the given name. + Module *lookupModule(StringRef ModuleName, bool AllowSearch = true); void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; } - typedef std::vector<HeaderFileInfo>::const_iterator header_file_iterator; - header_file_iterator header_file_begin() const { return FileInfo.begin(); } - header_file_iterator header_file_end() const { return FileInfo.end(); } + /// \brief Determine whether there is a module map that may map the header + /// with the given file name to a (sub)module. + /// + /// \param Filename The name of the file. + /// + /// \param Root The "root" directory, at which we should stop looking for + /// module maps. + bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root); + + /// \brief Retrieve the module that corresponds to the given file, if any. + /// + /// \param File The header that we wish to map to a module. + Module *findModuleForHeader(const FileEntry *File); + + /// \brief Read the contents of the given module map file. + /// + /// \param File The module map file. + /// + /// \param OnlyModule If non-NULL, this will receive the + /// + /// \returns true if an error occurred, false otherwise. + bool loadModuleMapFile(const FileEntry *File); + + /// \brief Collect the set of all known, top-level modules. + /// + /// \param Modules Will be filled with the set of known, top-level modules. + void collectAllModules(llvm::SmallVectorImpl<Module *> &Modules); + +private: + /// \brief Retrieve a module with the given name, which may be part of the + /// given framework. + /// + /// \param Name The name of the module to retrieve. + /// + /// \param Dir The framework directory (e.g., ModuleName.framework). + /// + /// \param IsSystem Whether the framework directory is part of the system + /// frameworks. + /// + /// \returns The module, if found; otherwise, null. + Module *loadFrameworkModule(StringRef Name, + const DirectoryEntry *Dir, + bool IsSystem); + +public: + /// \brief Retrieve the module map. + ModuleMap &getModuleMap() { return ModMap; } + unsigned header_file_size() const { return FileInfo.size(); } // Used by ASTReader. void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID); + /// getFileInfo - Return the HeaderFileInfo structure for the specified + /// FileEntry. + const HeaderFileInfo &getFileInfo(const FileEntry *FE) const { + return const_cast<HeaderSearch*>(this)->getFileInfo(FE); + } + // Used by external tools typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator; search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); } @@ -385,7 +518,39 @@ public: size_t getTotalMemory() const; + static std::string NormalizeDashIncludePath(StringRef File, + FileManager &FileMgr); + private: + /// \brief Describes what happened when we tried to load a module map file. + enum LoadModuleMapResult { + /// \brief The module map file had already been loaded. + LMM_AlreadyLoaded, + /// \brief The module map file was loaded by this invocation. + LMM_NewlyLoaded, + /// \brief There is was directory with the given name. + LMM_NoDirectory, + /// \brief There was either no module map file or the module map file was + /// invalid. + LMM_InvalidModuleMap + }; + + /// \brief Try to load the module map file in the given directory. + /// + /// \param DirName The name of the directory where we will look for a module + /// map file. + /// + /// \returns The result of attempting to load the module map file from the + /// named directory. + LoadModuleMapResult loadModuleMapFile(StringRef DirName); + + /// \brief Try to load the module map file in the given directory. + /// + /// \param Dir The directory where we will look for a module map file. + /// + /// \returns The result of attempting to load the module map file from the + /// named directory. + LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir); /// getFileInfo - Return the HeaderFileInfo structure for the specified /// FileEntry. |