Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:56

0001 //===- InstallAPI/HeaderFile.h ----------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// Representations of a library's headers for InstallAPI.
0010 ///
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_CLANG_INSTALLAPI_HEADERFILE_H
0014 #define LLVM_CLANG_INSTALLAPI_HEADERFILE_H
0015 
0016 #include "clang/Basic/FileManager.h"
0017 #include "clang/Basic/LangStandard.h"
0018 #include "clang/InstallAPI/MachO.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include "llvm/Support/ErrorHandling.h"
0021 #include "llvm/Support/Regex.h"
0022 #include <optional>
0023 #include <string>
0024 
0025 namespace clang::installapi {
0026 enum class HeaderType {
0027   /// Represents declarations accessible to all clients.
0028   Public,
0029   /// Represents declarations accessible to a disclosed set of clients.
0030   Private,
0031   /// Represents declarations only accessible as implementation details to the
0032   /// input library.
0033   Project,
0034   /// Unset or unknown type.
0035   Unknown,
0036 };
0037 
0038 inline StringRef getName(const HeaderType T) {
0039   switch (T) {
0040   case HeaderType::Public:
0041     return "Public";
0042   case HeaderType::Private:
0043     return "Private";
0044   case HeaderType::Project:
0045     return "Project";
0046   case HeaderType::Unknown:
0047     return "Unknown";
0048   }
0049   llvm_unreachable("unexpected header type");
0050 }
0051 
0052 class HeaderFile {
0053   /// Full input path to header.
0054   std::string FullPath;
0055   /// Access level of header.
0056   HeaderType Type;
0057   /// Expected way header will be included by clients.
0058   std::string IncludeName;
0059   /// Supported language mode for header.
0060   std::optional<clang::Language> Language;
0061   /// Exclude header file from processing.
0062   bool Excluded{false};
0063   /// Add header file to processing.
0064   bool Extra{false};
0065   /// Specify that header file is the umbrella header for library.
0066   bool Umbrella{false};
0067 
0068 public:
0069   HeaderFile() = delete;
0070   HeaderFile(StringRef FullPath, HeaderType Type,
0071              StringRef IncludeName = StringRef(),
0072              std::optional<clang::Language> Language = std::nullopt)
0073       : FullPath(FullPath), Type(Type), IncludeName(IncludeName),
0074         Language(Language) {}
0075 
0076   static llvm::Regex getFrameworkIncludeRule();
0077 
0078   HeaderType getType() const { return Type; }
0079   StringRef getIncludeName() const { return IncludeName; }
0080   StringRef getPath() const { return FullPath; }
0081 
0082   void setExtra(bool V = true) { Extra = V; }
0083   void setExcluded(bool V = true) { Excluded = V; }
0084   void setUmbrellaHeader(bool V = true) { Umbrella = V; }
0085   bool isExtra() const { return Extra; }
0086   bool isExcluded() const { return Excluded; }
0087   bool isUmbrellaHeader() const { return Umbrella; }
0088 
0089   bool useIncludeName() const {
0090     return Type != HeaderType::Project && !IncludeName.empty();
0091   }
0092 
0093   bool operator==(const HeaderFile &Other) const {
0094     return std::tie(Type, FullPath, IncludeName, Language, Excluded, Extra,
0095                     Umbrella) == std::tie(Other.Type, Other.FullPath,
0096                                           Other.IncludeName, Other.Language,
0097                                           Other.Excluded, Other.Extra,
0098                                           Other.Umbrella);
0099   }
0100 
0101   bool operator<(const HeaderFile &Other) const {
0102     /// For parsing of headers based on ordering,
0103     /// group by type, then whether its an umbrella.
0104     /// Capture 'extra' headers last.
0105     /// This optimizes the chance of a sucessful parse for
0106     /// headers that violate IWYU.
0107     if (isExtra() && Other.isExtra())
0108       return std::tie(Type, Umbrella) < std::tie(Other.Type, Other.Umbrella);
0109 
0110     return std::tie(Type, Umbrella, Extra, FullPath) <
0111            std::tie(Other.Type, Other.Umbrella, Other.Extra, Other.FullPath);
0112   }
0113 };
0114 
0115 /// Glob that represents a pattern of header files to retreive.
0116 class HeaderGlob {
0117 private:
0118   std::string GlobString;
0119   llvm::Regex Rule;
0120   HeaderType Type;
0121   bool FoundMatch{false};
0122 
0123 public:
0124   HeaderGlob(StringRef GlobString, llvm::Regex &&, HeaderType Type);
0125 
0126   /// Create a header glob from string for the header access level.
0127   static llvm::Expected<std::unique_ptr<HeaderGlob>>
0128   create(StringRef GlobString, HeaderType Type);
0129 
0130   /// Query if provided header matches glob.
0131   bool match(const HeaderFile &Header);
0132 
0133   /// Query if a header was matched in the glob, used primarily for error
0134   /// reporting.
0135   bool didMatch() { return FoundMatch; }
0136 
0137   /// Provide back input glob string.
0138   StringRef str() { return GlobString; }
0139 };
0140 
0141 /// Assemble expected way header will be included by clients.
0142 /// As in what maps inside the brackets of `#include <IncludeName.h>`
0143 /// For example,
0144 /// "/System/Library/Frameworks/Foo.framework/Headers/Foo.h" returns
0145 /// "Foo/Foo.h"
0146 ///
0147 /// \param FullPath Path to the header file which includes the library
0148 /// structure.
0149 std::optional<std::string> createIncludeHeaderName(const StringRef FullPath);
0150 using HeaderSeq = std::vector<HeaderFile>;
0151 
0152 /// Determine if Path is a header file.
0153 /// It does not touch the file system.
0154 ///
0155 /// \param  Path File path to file.
0156 bool isHeaderFile(StringRef Path);
0157 
0158 /// Given input directory, collect all header files.
0159 ///
0160 /// \param FM FileManager for finding input files.
0161 /// \param Directory Path to directory file.
0162 llvm::Expected<PathSeq> enumerateFiles(clang::FileManager &FM,
0163                                        StringRef Directory);
0164 
0165 } // namespace clang::installapi
0166 
0167 #endif // LLVM_CLANG_INSTALLAPI_HEADERFILE_H