1 //===- HeaderSearch.h - Resolve Header File Locations -----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the HeaderSearch interface. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_LEX_HEADERSEARCH_H 14 #define LLVM_CLANG_LEX_HEADERSEARCH_H 15 16 #include "clang/Basic/SourceLocation.h" 17 #include "clang/Basic/SourceManager.h" 18 #include "clang/Lex/DirectoryLookup.h" 19 #include "clang/Lex/HeaderMap.h" 20 #include "clang/Lex/ModuleMap.h" 21 #include "llvm/ADT/ArrayRef.h" 22 #include "llvm/ADT/DenseMap.h" 23 #include "llvm/ADT/SetVector.h" 24 #include "llvm/ADT/SmallSet.h" 25 #include "llvm/ADT/SmallString.h" 26 #include "llvm/ADT/StringMap.h" 27 #include "llvm/ADT/StringRef.h" 28 #include "llvm/ADT/StringSet.h" 29 #include "llvm/Support/Allocator.h" 30 #include <cassert> 31 #include <cstddef> 32 #include <memory> 33 #include <string> 34 #include <utility> 35 #include <vector> 36 37 namespace clang { 38 39 class DiagnosticsEngine; 40 class DirectoryEntry; 41 class ExternalPreprocessorSource; 42 class FileEntry; 43 class FileManager; 44 class HeaderSearchOptions; 45 class IdentifierInfo; 46 class LangOptions; 47 class Module; 48 class Preprocessor; 49 class TargetInfo; 50 51 /// The preprocessor keeps track of this information for each 52 /// file that is \#included. 53 struct HeaderFileInfo { 54 /// True if this is a \#import'd or \#pragma once file. 55 unsigned isImport : 1; 56 57 /// True if this is a \#pragma once file. 58 unsigned isPragmaOnce : 1; 59 60 /// Keep track of whether this is a system header, and if so, 61 /// whether it is C++ clean or not. This can be set by the include paths or 62 /// by \#pragma gcc system_header. This is an instance of 63 /// SrcMgr::CharacteristicKind. 64 unsigned DirInfo : 3; 65 66 /// Whether this header file info was supplied by an external source, 67 /// and has not changed since. 68 unsigned External : 1; 69 70 /// Whether this header is part of a module. 71 unsigned isModuleHeader : 1; 72 73 /// Whether this header is part of the module that we are building. 74 unsigned isCompilingModuleHeader : 1; 75 76 /// Whether this structure is considered to already have been 77 /// "resolved", meaning that it was loaded from the external source. 78 unsigned Resolved : 1; 79 80 /// Whether this is a header inside a framework that is currently 81 /// being built. 82 /// 83 /// When a framework is being built, the headers have not yet been placed 84 /// into the appropriate framework subdirectories, and therefore are 85 /// provided via a header map. This bit indicates when this is one of 86 /// those framework headers. 87 unsigned IndexHeaderMapHeader : 1; 88 89 /// Whether this file has been looked up as a header. 90 unsigned IsValid : 1; 91 92 /// The number of times the file has been included already. 93 unsigned short NumIncludes = 0; 94 95 /// The ID number of the controlling macro. 96 /// 97 /// This ID number will be non-zero when there is a controlling 98 /// macro whose IdentifierInfo may not yet have been loaded from 99 /// external storage. 100 unsigned ControllingMacroID = 0; 101 102 /// If this file has a \#ifndef XXX (or equivalent) guard that 103 /// protects the entire contents of the file, this is the identifier 104 /// for the macro that controls whether or not it has any effect. 105 /// 106 /// Note: Most clients should use getControllingMacro() to access 107 /// the controlling macro of this header, since 108 /// getControllingMacro() is able to load a controlling macro from 109 /// external storage. 110 const IdentifierInfo *ControllingMacro = nullptr; 111 112 /// If this header came from a framework include, this is the name 113 /// of the framework. 114 StringRef Framework; 115 116 /// List of aliases that this header is known as. 117 /// Most headers should only have at most one alias, but a handful 118 /// have two. 119 llvm::SetVector<llvm::SmallString<32>, 120 llvm::SmallVector<llvm::SmallString<32>, 2>, 121 llvm::SmallSet<llvm::SmallString<32>, 2>> 122 Aliases; 123 HeaderFileInfoHeaderFileInfo124 HeaderFileInfo() 125 : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), 126 External(false), isModuleHeader(false), isCompilingModuleHeader(false), 127 Resolved(false), IndexHeaderMapHeader(false), IsValid(false) {} 128 129 /// Retrieve the controlling macro for this header file, if 130 /// any. 131 const IdentifierInfo * 132 getControllingMacro(ExternalPreprocessorSource *External); 133 134 /// Determine whether this is a non-default header file info, e.g., 135 /// it corresponds to an actual header we've included or tried to include. isNonDefaultHeaderFileInfo136 bool isNonDefault() const { 137 return isImport || isPragmaOnce || NumIncludes || ControllingMacro || 138 ControllingMacroID; 139 } 140 }; 141 142 /// An external source of header file information, which may supply 143 /// information about header files already included. 144 class ExternalHeaderFileInfoSource { 145 public: 146 virtual ~ExternalHeaderFileInfoSource(); 147 148 /// Retrieve the header file information for the given file entry. 149 /// 150 /// \returns Header file information for the given file entry, with the 151 /// \c External bit set. If the file entry is not known, return a 152 /// default-constructed \c HeaderFileInfo. 153 virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0; 154 }; 155 156 /// This structure is used to record entries in our framework cache. 157 struct FrameworkCacheEntry { 158 /// The directory entry which should be used for the cached framework. 159 const DirectoryEntry *Directory; 160 161 /// Whether this framework has been "user-specified" to be treated as if it 162 /// were a system framework (even if it was found outside a system framework 163 /// directory). 164 bool IsUserSpecifiedSystemFramework; 165 }; 166 167 /// Encapsulates the information needed to find the file referenced 168 /// by a \#include or \#include_next, (sub-)framework lookup, etc. 169 class HeaderSearch { 170 friend class DirectoryLookup; 171 172 /// Header-search options used to initialize this header search. 173 std::shared_ptr<HeaderSearchOptions> HSOpts; 174 175 DiagnosticsEngine &Diags; 176 FileManager &FileMgr; 177 178 /// \#include search path information. Requests for \#include "x" search the 179 /// directory of the \#including file first, then each directory in SearchDirs 180 /// consecutively. Requests for <x> search the current dir first, then each 181 /// directory in SearchDirs, starting at AngledDirIdx, consecutively. If 182 /// NoCurDirSearch is true, then the check for the file in the current 183 /// directory is suppressed. 184 std::vector<DirectoryLookup> SearchDirs; 185 unsigned AngledDirIdx = 0; 186 unsigned SystemDirIdx = 0; 187 bool NoCurDirSearch = false; 188 189 /// \#include prefixes for which the 'system header' property is 190 /// overridden. 191 /// 192 /// For a \#include "x" or \#include \<x> directive, the last string in this 193 /// list which is a prefix of 'x' determines whether the file is treated as 194 /// a system header. 195 std::vector<std::pair<std::string, bool>> SystemHeaderPrefixes; 196 197 /// The hash used for module cache paths. 198 std::string ModuleHash; 199 200 /// The path to the module cache. 201 std::string ModuleCachePath; 202 203 /// All of the preprocessor-specific data about files that are 204 /// included, indexed by the FileEntry's UID. 205 mutable std::vector<HeaderFileInfo> FileInfo; 206 207 /// Keeps track of each lookup performed by LookupFile. 208 struct LookupFileCacheInfo { 209 /// Starting index in SearchDirs that the cached search was performed from. 210 /// If there is a hit and this value doesn't match the current query, the 211 /// cache has to be ignored. 212 unsigned StartIdx = 0; 213 214 /// The entry in SearchDirs that satisfied the query. 215 unsigned HitIdx = 0; 216 217 /// This is non-null if the original filename was mapped to a framework 218 /// include via a headermap. 219 const char *MappedName = nullptr; 220 221 /// Default constructor -- Initialize all members with zero. 222 LookupFileCacheInfo() = default; 223 resetLookupFileCacheInfo224 void reset(unsigned StartIdx) { 225 this->StartIdx = StartIdx; 226 this->MappedName = nullptr; 227 } 228 }; 229 llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache; 230 231 /// Collection mapping a framework or subframework 232 /// name like "Carbon" to the Carbon.framework directory. 233 llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap; 234 235 /// Maps include file names (including the quotes or 236 /// angle brackets) to other include file names. This is used to support the 237 /// include_alias pragma for Microsoft compatibility. 238 using IncludeAliasMap = 239 llvm::StringMap<std::string, llvm::BumpPtrAllocator>; 240 std::unique_ptr<IncludeAliasMap> IncludeAliases; 241 242 /// This is a mapping from FileEntry -> HeaderMap, uniquing headermaps. 243 std::vector<std::pair<const FileEntry *, std::unique_ptr<HeaderMap>>> HeaderMaps; 244 245 /// The mapping between modules and headers. 246 mutable ModuleMap ModMap; 247 248 /// Describes whether a given directory has a module map in it. 249 llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap; 250 251 /// Set of module map files we've already loaded, and a flag indicating 252 /// whether they were valid or not. 253 llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps; 254 255 /// Uniqued set of framework names, which is used to track which 256 /// headers were included as framework headers. 257 llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames; 258 259 /// Entity used to resolve the identifier IDs of controlling 260 /// macros into IdentifierInfo pointers, and keep the identifire up to date, 261 /// as needed. 262 ExternalPreprocessorSource *ExternalLookup = nullptr; 263 264 /// Entity used to look up stored header file information. 265 ExternalHeaderFileInfoSource *ExternalSource = nullptr; 266 267 public: 268 HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts, 269 SourceManager &SourceMgr, DiagnosticsEngine &Diags, 270 const LangOptions &LangOpts, const TargetInfo *Target); 271 HeaderSearch(const HeaderSearch &) = delete; 272 HeaderSearch &operator=(const HeaderSearch &) = delete; 273 274 /// Retrieve the header-search options with which this header search 275 /// was initialized. getHeaderSearchOpts()276 HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; } 277 getFileMgr()278 FileManager &getFileMgr() const { return FileMgr; } 279 getDiags()280 DiagnosticsEngine &getDiags() const { return Diags; } 281 282 /// Interface for setting the file search paths. SetSearchPaths(const std::vector<DirectoryLookup> & dirs,unsigned angledDirIdx,unsigned systemDirIdx,bool noCurDirSearch)283 void SetSearchPaths(const std::vector<DirectoryLookup> &dirs, 284 unsigned angledDirIdx, unsigned systemDirIdx, 285 bool noCurDirSearch) { 286 assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() && 287 "Directory indices are unordered"); 288 SearchDirs = dirs; 289 AngledDirIdx = angledDirIdx; 290 SystemDirIdx = systemDirIdx; 291 NoCurDirSearch = noCurDirSearch; 292 //LookupFileCache.clear(); 293 } 294 295 /// Add an additional search path. AddSearchPath(const DirectoryLookup & dir,bool isAngled)296 void AddSearchPath(const DirectoryLookup &dir, bool isAngled) { 297 unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx; 298 SearchDirs.insert(SearchDirs.begin() + idx, dir); 299 if (!isAngled) 300 AngledDirIdx++; 301 SystemDirIdx++; 302 } 303 304 /// Set the list of system header prefixes. SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string,bool>> P)305 void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool>> P) { 306 SystemHeaderPrefixes.assign(P.begin(), P.end()); 307 } 308 309 /// Checks whether the map exists or not. HasIncludeAliasMap()310 bool HasIncludeAliasMap() const { return (bool)IncludeAliases; } 311 312 /// Map the source include name to the dest include name. 313 /// 314 /// The Source should include the angle brackets or quotes, the dest 315 /// should not. This allows for distinction between <> and "" headers. AddIncludeAlias(StringRef Source,StringRef Dest)316 void AddIncludeAlias(StringRef Source, StringRef Dest) { 317 if (!IncludeAliases) 318 IncludeAliases.reset(new IncludeAliasMap); 319 (*IncludeAliases)[Source] = std::string(Dest); 320 } 321 322 /// Maps one header file name to a different header 323 /// file name, for use with the include_alias pragma. Note that the source 324 /// file name should include the angle brackets or quotes. Returns StringRef 325 /// as null if the header cannot be mapped. MapHeaderToIncludeAlias(StringRef Source)326 StringRef MapHeaderToIncludeAlias(StringRef Source) { 327 assert(IncludeAliases && "Trying to map headers when there's no map"); 328 329 // Do any filename replacements before anything else 330 IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source); 331 if (Iter != IncludeAliases->end()) 332 return Iter->second; 333 return {}; 334 } 335 336 /// Set the hash to use for module cache paths. setModuleHash(StringRef Hash)337 void setModuleHash(StringRef Hash) { ModuleHash = std::string(Hash); } 338 339 /// Set the path to the module cache. setModuleCachePath(StringRef CachePath)340 void setModuleCachePath(StringRef CachePath) { 341 ModuleCachePath = std::string(CachePath); 342 } 343 344 /// Retrieve the module hash. getModuleHash()345 StringRef getModuleHash() const { return ModuleHash; } 346 347 /// Retrieve the path to the module cache. getModuleCachePath()348 StringRef getModuleCachePath() const { return ModuleCachePath; } 349 350 /// Consider modules when including files from this directory. setDirectoryHasModuleMap(const DirectoryEntry * Dir)351 void setDirectoryHasModuleMap(const DirectoryEntry* Dir) { 352 DirectoryHasModuleMap[Dir] = true; 353 } 354 355 /// Forget everything we know about headers so far. ClearFileInfo()356 void ClearFileInfo() { 357 FileInfo.clear(); 358 } 359 SetExternalLookup(ExternalPreprocessorSource * EPS)360 void SetExternalLookup(ExternalPreprocessorSource *EPS) { 361 ExternalLookup = EPS; 362 } 363 getExternalLookup()364 ExternalPreprocessorSource *getExternalLookup() const { 365 return ExternalLookup; 366 } 367 368 /// Set the external source of header information. SetExternalSource(ExternalHeaderFileInfoSource * ES)369 void SetExternalSource(ExternalHeaderFileInfoSource *ES) { 370 ExternalSource = ES; 371 } 372 373 /// Set the target information for the header search, if not 374 /// already known. 375 void setTarget(const TargetInfo &Target); 376 377 /// Given a "foo" or \<foo> reference, look up the indicated file, 378 /// return null on failure. 379 /// 380 /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member 381 /// the file was found in, or null if not applicable. 382 /// 383 /// \param IncludeLoc Used for diagnostics if valid. 384 /// 385 /// \param isAngled indicates whether the file reference is a <> reference. 386 /// 387 /// \param CurDir If non-null, the file was found in the specified directory 388 /// search location. This is used to implement \#include_next. 389 /// 390 /// \param Includers Indicates where the \#including file(s) are, in case 391 /// relative searches are needed. In reverse order of inclusion. 392 /// 393 /// \param SearchPath If non-null, will be set to the search path relative 394 /// to which the file was found. If the include path is absolute, SearchPath 395 /// will be set to an empty string. 396 /// 397 /// \param RelativePath If non-null, will be set to the path relative to 398 /// SearchPath at which the file was found. This only differs from the 399 /// Filename for framework includes. 400 /// 401 /// \param SuggestedModule If non-null, and the file found is semantically 402 /// part of a known module, this will be set to the module that should 403 /// be imported instead of preprocessing/parsing the file found. 404 /// 405 /// \param IsMapped If non-null, and the search involved header maps, set to 406 /// true. 407 /// 408 /// \param IsFrameworkFound If non-null, will be set to true if a framework is 409 /// found in any of searched SearchDirs. Will be set to false if a framework 410 /// is found only through header maps. Doesn't guarantee the requested file is 411 /// found. 412 Optional<FileEntryRef> LookupFile( 413 StringRef Filename, SourceLocation IncludeLoc, bool isAngled, 414 const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, 415 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, 416 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, 417 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, 418 bool *IsMapped, bool *IsFrameworkFound, bool SkipCache = false, 419 bool BuildSystemModule = false); 420 421 /// Look up a subframework for the specified \#include file. 422 /// 423 /// For example, if \#include'ing <HIToolbox/HIToolbox.h> from 424 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if 425 /// HIToolbox is a subframework within Carbon.framework. If so, return 426 /// the FileEntry for the designated file, otherwise return null. 427 Optional<FileEntryRef> LookupSubframeworkHeader( 428 StringRef Filename, const FileEntry *ContextFileEnt, 429 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, 430 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule); 431 432 /// Look up the specified framework name in our framework cache. 433 /// \returns The DirectoryEntry it is in if we know, null otherwise. LookupFrameworkCache(StringRef FWName)434 FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) { 435 return FrameworkMap[FWName]; 436 } 437 438 /// Mark the specified file as a target of a \#include, 439 /// \#include_next, or \#import directive. 440 /// 441 /// \return false if \#including the file will have no effect or true 442 /// if we should include it. 443 bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File, 444 bool isImport, bool ModulesEnabled, 445 Module *M); 446 447 /// Return whether the specified file is a normal header, 448 /// a system header, or a C++ friendly system header. getFileDirFlavor(const FileEntry * File)449 SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) { 450 return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo; 451 } 452 453 /// Mark the specified file as a "once only" file, e.g. due to 454 /// \#pragma once. MarkFileIncludeOnce(const FileEntry * File)455 void MarkFileIncludeOnce(const FileEntry *File) { 456 HeaderFileInfo &FI = getFileInfo(File); 457 FI.isImport = true; 458 FI.isPragmaOnce = true; 459 } 460 461 /// Mark the specified file as a system header, e.g. due to 462 /// \#pragma GCC system_header. MarkFileSystemHeader(const FileEntry * File)463 void MarkFileSystemHeader(const FileEntry *File) { 464 getFileInfo(File).DirInfo = SrcMgr::C_System; 465 } 466 AddFileAlias(const FileEntry * File,StringRef Alias)467 void AddFileAlias(const FileEntry *File, StringRef Alias) { 468 getFileInfo(File).Aliases.insert(Alias); 469 } 470 471 /// Mark the specified file as part of a module. 472 void MarkFileModuleHeader(const FileEntry *FE, 473 ModuleMap::ModuleHeaderRole Role, 474 bool isCompilingModuleHeader); 475 476 /// Increment the count for the number of times the specified 477 /// FileEntry has been entered. IncrementIncludeCount(const FileEntry * File)478 void IncrementIncludeCount(const FileEntry *File) { 479 ++getFileInfo(File).NumIncludes; 480 } 481 482 /// Mark the specified file as having a controlling macro. 483 /// 484 /// This is used by the multiple-include optimization to eliminate 485 /// no-op \#includes. SetFileControllingMacro(const FileEntry * File,const IdentifierInfo * ControllingMacro)486 void SetFileControllingMacro(const FileEntry *File, 487 const IdentifierInfo *ControllingMacro) { 488 getFileInfo(File).ControllingMacro = ControllingMacro; 489 } 490 491 /// Return true if this is the first time encountering this header. FirstTimeLexingFile(const FileEntry * File)492 bool FirstTimeLexingFile(const FileEntry *File) { 493 return getFileInfo(File).NumIncludes == 1; 494 } 495 496 /// Determine whether this file is intended to be safe from 497 /// multiple inclusions, e.g., it has \#pragma once or a controlling 498 /// macro. 499 /// 500 /// This routine does not consider the effect of \#import 501 bool isFileMultipleIncludeGuarded(const FileEntry *File); 502 503 /// Determine whether the given file is known to have ever been \#imported 504 /// (or if it has been \#included and we've encountered a \#pragma once). hasFileBeenImported(const FileEntry * File)505 bool hasFileBeenImported(const FileEntry *File) { 506 const HeaderFileInfo *FI = getExistingFileInfo(File); 507 return FI && FI->isImport; 508 } 509 510 /// This method returns a HeaderMap for the specified 511 /// FileEntry, uniquing them through the 'HeaderMaps' datastructure. 512 const HeaderMap *CreateHeaderMap(const FileEntry *FE); 513 514 /// Get filenames for all registered header maps. 515 void getHeaderMapFileNames(SmallVectorImpl<std::string> &Names) const; 516 517 /// Retrieve the name of the cached module file that should be used 518 /// to load the given module. 519 /// 520 /// \param Module The module whose module file name will be returned. 521 /// 522 /// \returns The name of the module file that corresponds to this module, 523 /// or an empty string if this module does not correspond to any module file. 524 std::string getCachedModuleFileName(Module *Module); 525 526 /// Retrieve the name of the prebuilt module file that should be used 527 /// to load a module with the given name. 528 /// 529 /// \param ModuleName The module whose module file name will be returned. 530 /// 531 /// \param FileMapOnly If true, then only look in the explicit module name 532 // to file name map and skip the directory search. 533 /// 534 /// \returns The name of the module file that corresponds to this module, 535 /// or an empty string if this module does not correspond to any module file. 536 std::string getPrebuiltModuleFileName(StringRef ModuleName, 537 bool FileMapOnly = false); 538 539 /// Retrieve the name of the prebuilt module file that should be used 540 /// to load the given module. 541 /// 542 /// \param Module The module whose module file name will be returned. 543 /// 544 /// \returns The name of the module file that corresponds to this module, 545 /// or an empty string if this module does not correspond to any module file. 546 std::string getPrebuiltImplicitModuleFileName(Module *Module); 547 548 /// Retrieve the name of the (to-be-)cached module file that should 549 /// be used to load a module with the given name. 550 /// 551 /// \param ModuleName The module whose module file name will be returned. 552 /// 553 /// \param ModuleMapPath A path that when combined with \c ModuleName 554 /// uniquely identifies this module. See Module::ModuleMap. 555 /// 556 /// \returns The name of the module file that corresponds to this module, 557 /// or an empty string if this module does not correspond to any module file. 558 std::string getCachedModuleFileName(StringRef ModuleName, 559 StringRef ModuleMapPath); 560 561 /// Lookup a module Search for a module with the given name. 562 /// 563 /// \param ModuleName The name of the module we're looking for. 564 /// 565 /// \param AllowSearch Whether we are allowed to search in the various 566 /// search directories to produce a module definition. If not, this lookup 567 /// will only return an already-known module. 568 /// 569 /// \param AllowExtraModuleMapSearch Whether we allow to search modulemaps 570 /// in subdirectories. 571 /// 572 /// \returns The module with the given name. 573 Module *lookupModule(StringRef ModuleName, bool AllowSearch = true, 574 bool AllowExtraModuleMapSearch = false); 575 576 /// Try to find a module map file in the given directory, returning 577 /// \c nullptr if none is found. 578 const FileEntry *lookupModuleMapFile(const DirectoryEntry *Dir, 579 bool IsFramework); 580 581 /// Determine whether there is a module map that may map the header 582 /// with the given file name to a (sub)module. 583 /// Always returns false if modules are disabled. 584 /// 585 /// \param Filename The name of the file. 586 /// 587 /// \param Root The "root" directory, at which we should stop looking for 588 /// module maps. 589 /// 590 /// \param IsSystem Whether the directories we're looking at are system 591 /// header directories. 592 bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root, 593 bool IsSystem); 594 595 /// Retrieve the module that corresponds to the given file, if any. 596 /// 597 /// \param File The header that we wish to map to a module. 598 /// \param AllowTextual Whether we want to find textual headers too. 599 ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File, 600 bool AllowTextual = false) const; 601 602 /// Retrieve all the modules corresponding to the given file. 603 /// 604 /// \ref findModuleForHeader should typically be used instead of this. 605 ArrayRef<ModuleMap::KnownHeader> 606 findAllModulesForHeader(const FileEntry *File) const; 607 608 /// Read the contents of the given module map file. 609 /// 610 /// \param File The module map file. 611 /// \param IsSystem Whether this file is in a system header directory. 612 /// \param ID If the module map file is already mapped (perhaps as part of 613 /// processing a preprocessed module), the ID of the file. 614 /// \param Offset [inout] An offset within ID to start parsing. On exit, 615 /// filled by the end of the parsed contents (either EOF or the 616 /// location of an end-of-module-map pragma). 617 /// \param OriginalModuleMapFile The original path to the module map file, 618 /// used to resolve paths within the module (this is required when 619 /// building the module from preprocessed source). 620 /// \returns true if an error occurred, false otherwise. 621 bool loadModuleMapFile(const FileEntry *File, bool IsSystem, 622 FileID ID = FileID(), unsigned *Offset = nullptr, 623 StringRef OriginalModuleMapFile = StringRef()); 624 625 /// Collect the set of all known, top-level modules. 626 /// 627 /// \param Modules Will be filled with the set of known, top-level modules. 628 void collectAllModules(SmallVectorImpl<Module *> &Modules); 629 630 /// Load all known, top-level system modules. 631 void loadTopLevelSystemModules(); 632 633 private: 634 /// Lookup a module with the given module name and search-name. 635 /// 636 /// \param ModuleName The name of the module we're looking for. 637 /// 638 /// \param SearchName The "search-name" to derive filesystem paths from 639 /// when looking for the module map; this is usually equal to ModuleName, 640 /// but for compatibility with some buggy frameworks, additional attempts 641 /// may be made to find the module under a related-but-different search-name. 642 /// 643 /// \param AllowExtraModuleMapSearch Whether we allow to search modulemaps 644 /// in subdirectories. 645 /// 646 /// \returns The module named ModuleName. 647 Module *lookupModule(StringRef ModuleName, StringRef SearchName, 648 bool AllowExtraModuleMapSearch = false); 649 650 /// Retrieve the name of the (to-be-)cached module file that should 651 /// be used to load a module with the given name. 652 /// 653 /// \param ModuleName The module whose module file name will be returned. 654 /// 655 /// \param ModuleMapPath A path that when combined with \c ModuleName 656 /// uniquely identifies this module. See Module::ModuleMap. 657 /// 658 /// \param CachePath A path to the module cache. 659 /// 660 /// \returns The name of the module file that corresponds to this module, 661 /// or an empty string if this module does not correspond to any module file. 662 std::string getCachedModuleFileNameImpl(StringRef ModuleName, 663 StringRef ModuleMapPath, 664 StringRef CachePath); 665 666 /// Retrieve a module with the given name, which may be part of the 667 /// given framework. 668 /// 669 /// \param Name The name of the module to retrieve. 670 /// 671 /// \param Dir The framework directory (e.g., ModuleName.framework). 672 /// 673 /// \param IsSystem Whether the framework directory is part of the system 674 /// frameworks. 675 /// 676 /// \returns The module, if found; otherwise, null. 677 Module *loadFrameworkModule(StringRef Name, 678 const DirectoryEntry *Dir, 679 bool IsSystem); 680 681 /// Load all of the module maps within the immediate subdirectories 682 /// of the given search directory. 683 void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir); 684 685 /// Find and suggest a usable module for the given file. 686 /// 687 /// \return \c true if the file can be used, \c false if we are not permitted to 688 /// find this file due to requirements from \p RequestingModule. 689 bool findUsableModuleForHeader(const FileEntry *File, 690 const DirectoryEntry *Root, 691 Module *RequestingModule, 692 ModuleMap::KnownHeader *SuggestedModule, 693 bool IsSystemHeaderDir); 694 695 /// Find and suggest a usable module for the given file, which is part of 696 /// the specified framework. 697 /// 698 /// \return \c true if the file can be used, \c false if we are not permitted to 699 /// find this file due to requirements from \p RequestingModule. 700 bool findUsableModuleForFrameworkHeader( 701 const FileEntry *File, StringRef FrameworkName, Module *RequestingModule, 702 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework); 703 704 /// Look up the file with the specified name and determine its owning 705 /// module. 706 Optional<FileEntryRef> 707 getFileAndSuggestModule(StringRef FileName, SourceLocation IncludeLoc, 708 const DirectoryEntry *Dir, bool IsSystemHeaderDir, 709 Module *RequestingModule, 710 ModuleMap::KnownHeader *SuggestedModule); 711 712 public: 713 /// Retrieve the module map. getModuleMap()714 ModuleMap &getModuleMap() { return ModMap; } 715 716 /// Retrieve the module map. getModuleMap()717 const ModuleMap &getModuleMap() const { return ModMap; } 718 header_file_size()719 unsigned header_file_size() const { return FileInfo.size(); } 720 721 /// Return the HeaderFileInfo structure for the specified FileEntry, 722 /// in preparation for updating it in some way. 723 HeaderFileInfo &getFileInfo(const FileEntry *FE); 724 725 /// Return the HeaderFileInfo structure for the specified FileEntry, 726 /// if it has ever been filled in. 727 /// \param WantExternal Whether the caller wants purely-external header file 728 /// info (where \p External is true). 729 const HeaderFileInfo *getExistingFileInfo(const FileEntry *FE, 730 bool WantExternal = true) const; 731 732 // Used by external tools 733 using search_dir_iterator = std::vector<DirectoryLookup>::const_iterator; 734 search_dir_begin()735 search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); } search_dir_end()736 search_dir_iterator search_dir_end() const { return SearchDirs.end(); } search_dir_size()737 unsigned search_dir_size() const { return SearchDirs.size(); } 738 quoted_dir_begin()739 search_dir_iterator quoted_dir_begin() const { 740 return SearchDirs.begin(); 741 } 742 quoted_dir_end()743 search_dir_iterator quoted_dir_end() const { 744 return SearchDirs.begin() + AngledDirIdx; 745 } 746 angled_dir_begin()747 search_dir_iterator angled_dir_begin() const { 748 return SearchDirs.begin() + AngledDirIdx; 749 } 750 angled_dir_end()751 search_dir_iterator angled_dir_end() const { 752 return SearchDirs.begin() + SystemDirIdx; 753 } 754 system_dir_begin()755 search_dir_iterator system_dir_begin() const { 756 return SearchDirs.begin() + SystemDirIdx; 757 } 758 system_dir_end()759 search_dir_iterator system_dir_end() const { return SearchDirs.end(); } 760 761 /// Retrieve a uniqued framework name. 762 StringRef getUniqueFrameworkName(StringRef Framework); 763 764 /// Suggest a path by which the specified file could be found, for use in 765 /// diagnostics to suggest a #include. Returned path will only contain forward 766 /// slashes as separators. MainFile is the absolute path of the file that we 767 /// are generating the diagnostics for. It will try to shorten the path using 768 /// MainFile location, if none of the include search directories were prefix 769 /// of File. 770 /// 771 /// \param IsSystem If non-null, filled in to indicate whether the suggested 772 /// path is relative to a system header directory. 773 std::string suggestPathToFileForDiagnostics(const FileEntry *File, 774 llvm::StringRef MainFile, 775 bool *IsSystem = nullptr); 776 777 /// Suggest a path by which the specified file could be found, for use in 778 /// diagnostics to suggest a #include. Returned path will only contain forward 779 /// slashes as separators. MainFile is the absolute path of the file that we 780 /// are generating the diagnostics for. It will try to shorten the path using 781 /// MainFile location, if none of the include search directories were prefix 782 /// of File. 783 /// 784 /// \param WorkingDir If non-empty, this will be prepended to search directory 785 /// paths that are relative. 786 std::string suggestPathToFileForDiagnostics(llvm::StringRef File, 787 llvm::StringRef WorkingDir, 788 llvm::StringRef MainFile, 789 bool *IsSystem = nullptr); 790 791 void PrintStats(); 792 793 size_t getTotalMemory() const; 794 795 private: 796 /// Describes what happened when we tried to load a module map file. 797 enum LoadModuleMapResult { 798 /// The module map file had already been loaded. 799 LMM_AlreadyLoaded, 800 801 /// The module map file was loaded by this invocation. 802 LMM_NewlyLoaded, 803 804 /// There is was directory with the given name. 805 LMM_NoDirectory, 806 807 /// There was either no module map file or the module map file was 808 /// invalid. 809 LMM_InvalidModuleMap 810 }; 811 812 LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File, 813 bool IsSystem, 814 const DirectoryEntry *Dir, 815 FileID ID = FileID(), 816 unsigned *Offset = nullptr); 817 818 /// Try to load the module map file in the given directory. 819 /// 820 /// \param DirName The name of the directory where we will look for a module 821 /// map file. 822 /// \param IsSystem Whether this is a system header directory. 823 /// \param IsFramework Whether this is a framework directory. 824 /// 825 /// \returns The result of attempting to load the module map file from the 826 /// named directory. 827 LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem, 828 bool IsFramework); 829 830 /// Try to load the module map file in the given directory. 831 /// 832 /// \param Dir The directory where we will look for a module map file. 833 /// \param IsSystem Whether this is a system header directory. 834 /// \param IsFramework Whether this is a framework directory. 835 /// 836 /// \returns The result of attempting to load the module map file from the 837 /// named directory. 838 LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir, 839 bool IsSystem, bool IsFramework); 840 }; 841 842 } // namespace clang 843 844 #endif // LLVM_CLANG_LEX_HEADERSEARCH_H 845