Home | History | Annotate | Line # | Download | only in Lex
      1 //===--- DirectoryLookup.h - Info for searching for headers -----*- 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 DirectoryLookup interface.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
     14 #define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
     15 
     16 #include "clang/Basic/LLVM.h"
     17 #include "clang/Basic/FileManager.h"
     18 #include "clang/Basic/SourceManager.h"
     19 #include "clang/Lex/ModuleMap.h"
     20 
     21 namespace clang {
     22 class HeaderMap;
     23 class HeaderSearch;
     24 class Module;
     25 
     26 /// DirectoryLookup - This class represents one entry in the search list that
     27 /// specifies the search order for directories in \#include directives.  It
     28 /// represents either a directory, a framework, or a headermap.
     29 ///
     30 class DirectoryLookup {
     31 public:
     32   enum LookupType_t {
     33     LT_NormalDir,
     34     LT_Framework,
     35     LT_HeaderMap
     36   };
     37 private:
     38   union DLU { // This union is discriminated by isHeaderMap.
     39     /// Dir - This is the actual directory that we're referring to for a normal
     40     /// directory or a framework.
     41     DirectoryEntryRef Dir;
     42 
     43     /// Map - This is the HeaderMap if this is a headermap lookup.
     44     ///
     45     const HeaderMap *Map;
     46 
     47     DLU(DirectoryEntryRef Dir) : Dir(Dir) {}
     48     DLU(const HeaderMap *Map) : Map(Map) {}
     49   } u;
     50 
     51   /// DirCharacteristic - The type of directory this is: this is an instance of
     52   /// SrcMgr::CharacteristicKind.
     53   unsigned DirCharacteristic : 2;
     54 
     55   /// LookupType - This indicates whether this DirectoryLookup object is a
     56   /// normal directory, a framework, or a headermap.
     57   unsigned LookupType : 2;
     58 
     59   /// Whether this is a header map used when building a framework.
     60   unsigned IsIndexHeaderMap : 1;
     61 
     62   /// Whether we've performed an exhaustive search for module maps
     63   /// within the subdirectories of this directory.
     64   unsigned SearchedAllModuleMaps : 1;
     65 
     66 public:
     67   /// This ctor *does not take ownership* of 'Dir'.
     68   DirectoryLookup(DirectoryEntryRef Dir, SrcMgr::CharacteristicKind DT,
     69                   bool isFramework)
     70       : u(Dir), DirCharacteristic(DT),
     71         LookupType(isFramework ? LT_Framework : LT_NormalDir),
     72         IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {}
     73 
     74   /// This ctor *does not take ownership* of 'Map'.
     75   DirectoryLookup(const HeaderMap *Map, SrcMgr::CharacteristicKind DT,
     76                   bool isIndexHeaderMap)
     77       : u(Map), DirCharacteristic(DT), LookupType(LT_HeaderMap),
     78         IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {}
     79 
     80   /// getLookupType - Return the kind of directory lookup that this is: either a
     81   /// normal directory, a framework path, or a HeaderMap.
     82   LookupType_t getLookupType() const { return (LookupType_t)LookupType; }
     83 
     84   /// getName - Return the directory or filename corresponding to this lookup
     85   /// object.
     86   StringRef getName() const;
     87 
     88   /// getDir - Return the directory that this entry refers to.
     89   ///
     90   const DirectoryEntry *getDir() const {
     91     return isNormalDir() ? &u.Dir.getDirEntry() : nullptr;
     92   }
     93 
     94   /// getFrameworkDir - Return the directory that this framework refers to.
     95   ///
     96   const DirectoryEntry *getFrameworkDir() const {
     97     return isFramework() ? &u.Dir.getDirEntry() : nullptr;
     98   }
     99 
    100   Optional<DirectoryEntryRef> getFrameworkDirRef() const {
    101     return isFramework() ? Optional<DirectoryEntryRef>(u.Dir) : None;
    102   }
    103 
    104   /// getHeaderMap - Return the directory that this entry refers to.
    105   ///
    106   const HeaderMap *getHeaderMap() const {
    107     return isHeaderMap() ? u.Map : nullptr;
    108   }
    109 
    110   /// isNormalDir - Return true if this is a normal directory, not a header map.
    111   bool isNormalDir() const { return getLookupType() == LT_NormalDir; }
    112 
    113   /// isFramework - True if this is a framework directory.
    114   ///
    115   bool isFramework() const { return getLookupType() == LT_Framework; }
    116 
    117   /// isHeaderMap - Return true if this is a header map, not a normal directory.
    118   bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; }
    119 
    120   /// Determine whether we have already searched this entire
    121   /// directory for module maps.
    122   bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; }
    123 
    124   /// Specify whether we have already searched all of the subdirectories
    125   /// for module maps.
    126   void setSearchedAllModuleMaps(bool SAMM) {
    127     SearchedAllModuleMaps = SAMM;
    128   }
    129 
    130   /// DirCharacteristic - The type of directory this is, one of the DirType enum
    131   /// values.
    132   SrcMgr::CharacteristicKind getDirCharacteristic() const {
    133     return (SrcMgr::CharacteristicKind)DirCharacteristic;
    134   }
    135 
    136   /// Whether this describes a system header directory.
    137   bool isSystemHeaderDirectory() const {
    138     return getDirCharacteristic() != SrcMgr::C_User;
    139   }
    140 
    141   /// Whether this header map is building a framework or not.
    142   bool isIndexHeaderMap() const {
    143     return isHeaderMap() && IsIndexHeaderMap;
    144   }
    145 
    146   /// LookupFile - Lookup the specified file in this search path, returning it
    147   /// if it exists or returning null if not.
    148   ///
    149   /// \param Filename The file to look up relative to the search paths.
    150   ///
    151   /// \param HS The header search instance to search with.
    152   ///
    153   /// \param IncludeLoc the source location of the #include or #import
    154   /// directive.
    155   ///
    156   /// \param SearchPath If not NULL, will be set to the search path relative
    157   /// to which the file was found.
    158   ///
    159   /// \param RelativePath If not NULL, will be set to the path relative to
    160   /// SearchPath at which the file was found. This only differs from the
    161   /// Filename for framework includes.
    162   ///
    163   /// \param RequestingModule The module in which the lookup was performed.
    164   ///
    165   /// \param SuggestedModule If non-null, and the file found is semantically
    166   /// part of a known module, this will be set to the module that should
    167   /// be imported instead of preprocessing/parsing the file found.
    168   ///
    169   /// \param [out] InUserSpecifiedSystemFramework If the file is found,
    170   /// set to true if the file is located in a framework that has been
    171   /// user-specified to be treated as a system framework.
    172   ///
    173   /// \param [out] IsFrameworkFound For a framework directory set to true if
    174   /// specified '.framework' directory is found.
    175   ///
    176   /// \param [out] MappedName if this is a headermap which maps the filename to
    177   /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this
    178   /// vector and point Filename to it.
    179   Optional<FileEntryRef>
    180   LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc,
    181              SmallVectorImpl<char> *SearchPath,
    182              SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
    183              ModuleMap::KnownHeader *SuggestedModule,
    184              bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound,
    185              bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName) const;
    186 
    187 private:
    188   Optional<FileEntryRef> DoFrameworkLookup(
    189       StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath,
    190       SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
    191       ModuleMap::KnownHeader *SuggestedModule,
    192       bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const;
    193 };
    194 
    195 }  // end namespace clang
    196 
    197 #endif
    198