HeaderSearch.h revision 0bc735ffcfb223c0186419547abaa5c84482663e
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- HeaderSearch.h - Resolve Header File Locations ---------*- C++ -*-===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file defines the HeaderSearch interface. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef LLVM_CLANG_LEX_HEADERSEARCH_H 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define LLVM_CLANG_LEX_HEADERSEARCH_H 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/DirectoryLookup.h" 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/StringMap.h" 195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <vector> 205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang { 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileEntry; 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass FileManager; 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass IdentifierInfo; 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// HeaderSearch - This class encapsulates the information needed to find the 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// file referenced by a #include or #include_next, (sub-)framework lookup, etc. 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass HeaderSearch { 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FileManager &FileMgr; 315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// #include search path information. Requests for #include "x" search the 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// directory of the #including file first, then each directory in SearchDirs 345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// consequtively. Requests for <x> search the current dir first, then each 355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// directory in SearchDirs, starting at SystemDirIdx, consequtively. If 365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// NoCurDirSearch is true, then the check for the file in the current 375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// directory is supressed. 385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer std::vector<DirectoryLookup> SearchDirs; 395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned SystemDirIdx; 405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool NoCurDirSearch; 415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// PreFileInfo - The preprocessor keeps track of this information for each 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// file that is #included. 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer struct PerFileInfo { 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isImport - True if this is a #import'd or #pragma once file. 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isImport : 1; 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// DirInfo - Keep track of whether this is a system header, and if so, 495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// whether it is C++ clean or not. This can be set by the include paths or 505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// by #pragma gcc system_header. 515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer DirectoryLookup::DirType DirInfo : 2; 525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// NumIncludes - This is the number of times the file has been included 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// already. 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned short NumIncludes; 565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// that protects the entire contents of the file, this is the identifier 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// for the macro that controls whether or not it has any effect. 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const IdentifierInfo *ControllingMacro; 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer PerFileInfo() : isImport(false), DirInfo(DirectoryLookup::NormalHeaderDir), 635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumIncludes(0), ControllingMacro(0) {} 645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer }; 655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// FileInfo - This contains all of the preprocessor-specific data about files 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// that are included. The vector is indexed by the FileEntry's UID. 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer std::vector<PerFileInfo> FileInfo; 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 719960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner /// LookupFileCache - This is keeps track of each lookup performed by 729960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner /// LookupFile. The first part of the value is the starting index in 739960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner /// SearchDirs that the cached search was performed from. If there is a hit 749960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner /// and this value doesn't match the current query, the cache has to be 759960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner /// ignored. The second value is the entry in SearchDirs that satisfied the 769960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner /// query. 779960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner llvm::StringMap<std::pair<unsigned, unsigned> > LookupFileCache; 789960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner 799960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner 805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// FrameworkMap - This is a collection mapping a framework or subframework 815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// name like "Carbon" to the Carbon.framework directory. 825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::StringMap<const DirectoryEntry *> FrameworkMap; 835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 84822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing 85822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner /// headermaps. This vector owns the headermap. 86822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps; 87822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner 885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Various statistics we track for performance analysis. 895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumIncluded; 905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumMultiIncludeFileOptzn; 915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumFrameworkLookups, NumSubFrameworkLookups; 925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeaderSearch(FileManager &FM); 94822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner ~HeaderSearch(); 955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FileManager &getFileMgr() const { return FileMgr; } 975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// SetSearchPaths - Interface for setting the file search paths. 995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void SetSearchPaths(const std::vector<DirectoryLookup> &dirs, 1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned systemDirIdx, bool noCurDirSearch) { 1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SearchDirs = dirs; 1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SystemDirIdx = systemDirIdx; 1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NoCurDirSearch = noCurDirSearch; 1059960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner //LookupFileCache.clear(); 1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// ClearFileInfo - Forget everything we know about headers so far. 1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void ClearFileInfo() { 1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FileInfo.clear(); 1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file, 1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// return null on failure. isAngled indicates whether the file reference is 1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// a <> reference. If successful, this returns 'UsedDir', the 1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// DirectoryLookup member the file was found in, or null if not applicable. 1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// If CurDir is non-null, the file was found in the specified directory 1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// search location. This is used to implement #include_next. CurFileEnt, if 1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// non-null, indicates where the #including file is, in case a relative 1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// search is needed. 1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const FileEntry *LookupFile(const char *FilenameStart, 1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *FilenameEnd, bool isAngled, 1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const DirectoryLookup *FromDir, 1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const DirectoryLookup *&CurDir, 1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const FileEntry *CurFileEnt); 1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// LookupSubframeworkHeader - Look up a subframework for the specified 1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from 1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox 1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// is a subframework within Carbon.framework. If so, return the FileEntry 1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// for the designated file, otherwise return null. 1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const FileEntry *LookupSubframeworkHeader(const char *FilenameStart, 1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *FilenameEnd, 1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const FileEntry *RelativeFileEnt); 1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 136afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner /// LookupFrameworkCache - Look up the specified framework name in our 137afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner /// framework cache, returning the DirectoryEntry it is in if we know, 138afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner /// otherwise, return null. 139afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner const DirectoryEntry *&LookupFrameworkCache(const char *FWNameStart, 140afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner const char *FWNameEnd) { 141afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner return FrameworkMap.GetOrCreateValue(FWNameStart, FWNameEnd).getValue(); 142afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner } 143afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner 1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// ShouldEnterIncludeFile - Mark the specified file as a target of of a 1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// #include, #include_next, or #import directive. Return false if #including 1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// the file will have no effect or true if we should include it. 1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport); 1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getFileDirFlavor - Return whether the specified file is a normal header, 1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// a system header, or a C++ friendly system header. 1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer DirectoryLookup::DirType getFileDirFlavor(const FileEntry *File) { 1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return getFileInfo(File).DirInfo; 1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g. 1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// due to #pragma once. 1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void MarkFileIncludeOnce(const FileEntry *File) { 1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer getFileInfo(File).isImport = true; 1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// MarkFileSystemHeader - Mark the specified fiel as a system header, e.g. 1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// due to #pragma GCC system_header. 1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void MarkFileSystemHeader(const FileEntry *File) { 1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer getFileInfo(File).DirInfo = DirectoryLookup::SystemHeaderDir; 1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 16825bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner /// IncrementIncludeCount - Increment the count for the number of times the 16925bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner /// specified FileEntry has been entered. 17025bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner void IncrementIncludeCount(const FileEntry *File) { 17125bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner ++getFileInfo(File).NumIncludes; 17225bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner } 17325bfcb927d9169ea675ce6e98d8992efceeb0e42Chris Lattner 1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// SetFileControllingMacro - Mark the specified file as having a controlling 1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// macro. This is used by the multiple-include optimization to eliminate 1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// no-op #includes. 1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void SetFileControllingMacro(const FileEntry *File, 1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const IdentifierInfo *ControllingMacro) { 1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer getFileInfo(File).ControllingMacro = ControllingMacro; 1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 182822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner /// CreateHeaderMap - This method returns a HeaderMap for the specified 183822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure. 1841bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattner const HeaderMap *CreateHeaderMap(const FileEntry *FE); 185822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner 186afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; } 187afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner 1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void PrintStats(); 1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate: 1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getFileInfo - Return the PerFileInfo structure for the specified 1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// FileEntry. 1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer PerFileInfo &getFileInfo(const FileEntry *FE); 1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} // end namespace clang 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif 199