1 //===- ModuleMapFile.h - Parsing and representation -------------*- 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 #ifndef LLVM_CLANG_LEX_MODULEMAPFILE_H 10 #define LLVM_CLANG_LEX_MODULEMAPFILE_H 11 12 #include "clang/Basic/LLVM.h" 13 // TODO: Consider moving ModuleId to another header, parsing a modulemap file is 14 // intended to not depend on anything about the clang::Module class. 15 #include "clang/Basic/Module.h" 16 #include "clang/Basic/SourceLocation.h" 17 #include "llvm/ADT/StringRef.h" 18 19 #include <optional> 20 #include <variant> 21 22 namespace clang { 23 24 class DiagnosticsEngine; 25 class SourceManager; 26 27 namespace modulemap { 28 29 struct ExportDecl; 30 31 /// All declarations that can appear in a `module` declaration. 32 using Decl = 33 std::variant<struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, 34 struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, 35 struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, 36 struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl>; 37 38 struct RequiresFeature { 39 StringRef Feature; 40 SourceLocation Location; 41 bool RequiredState = true; /// False if preceded by '!'. 42 }; 43 44 struct RequiresDecl { 45 SourceLocation Location; 46 std::vector<RequiresFeature> Features; 47 }; 48 49 struct HeaderDecl { 50 StringRef Path; 51 SourceLocation Location; 52 SourceLocation PathLoc; 53 std::optional<int64_t> Size; 54 std::optional<int64_t> MTime; 55 LLVM_PREFERRED_TYPE(bool) 56 unsigned Private : 1; 57 LLVM_PREFERRED_TYPE(bool) 58 unsigned Textual : 1; 59 LLVM_PREFERRED_TYPE(bool) 60 unsigned Umbrella : 1; 61 LLVM_PREFERRED_TYPE(bool) 62 unsigned Excluded : 1; 63 }; 64 65 struct UmbrellaDirDecl { 66 StringRef Path; 67 SourceLocation Location; 68 }; 69 70 struct ModuleDecl { 71 ModuleId Id; 72 SourceLocation Location; /// Points to the first keyword in the decl. 73 ModuleAttributes Attrs; 74 std::vector<Decl> Decls; 75 76 LLVM_PREFERRED_TYPE(bool) 77 unsigned Explicit : 1; 78 LLVM_PREFERRED_TYPE(bool) 79 unsigned Framework : 1; 80 }; 81 82 struct ExcludeDecl { 83 SourceLocation Location; 84 StringRef Module; 85 }; 86 87 struct ExportDecl { 88 ModuleId Id; 89 SourceLocation Location; 90 bool Wildcard; /// True if the last element of the ModuleId is '*'. 91 }; 92 93 struct ExportAsDecl { 94 SourceLocation Location; 95 ModuleId Id; 96 }; 97 98 struct ExternModuleDecl { 99 SourceLocation Location; 100 ModuleId Id; 101 StringRef Path; 102 }; 103 104 struct UseDecl { 105 SourceLocation Location; 106 ModuleId Id; 107 }; 108 109 struct LinkDecl { 110 StringRef Library; 111 SourceLocation Location; 112 LLVM_PREFERRED_TYPE(bool) 113 unsigned Framework : 1; 114 }; 115 116 struct ConfigMacrosDecl { 117 std::vector<StringRef> Macros; 118 SourceLocation Location; 119 LLVM_PREFERRED_TYPE(bool) 120 unsigned Exhaustive : 1; 121 }; 122 123 struct ConflictDecl { 124 SourceLocation Location; 125 ModuleId Id; 126 StringRef Message; 127 }; 128 129 using TopLevelDecl = std::variant<ModuleDecl, ExternModuleDecl>; 130 131 /// Represents the parsed form of a module map file. 132 /// 133 /// This holds many reference types (StringRef, SourceLocation, etc.) whose 134 /// lifetimes are bound by the SourceManager and FileManager used. 135 struct ModuleMapFile { 136 /// The FileID used to parse this module map. This is always a local ID. 137 FileID ID; 138 139 /// The directory in which the module map was discovered. Declarations in 140 /// the module map are relative to this directory. 141 OptionalDirectoryEntryRef Dir; 142 143 /// Beginning of the file, used for moduleMapFileRead callback. 144 SourceLocation Start; 145 146 bool IsSystem; 147 std::vector<TopLevelDecl> Decls; 148 149 void dump(llvm::raw_ostream &out) const; 150 }; 151 152 /// Parse a module map file into an in memory representation. 153 /// 154 /// \param ID a valid local FileID. 155 /// \param Dir the directory in which this module map was found. 156 /// \param SM the SourceManager for \a ID. 157 /// \param Diags where to send the diagnostics. 158 /// \param IsSystem was this module map found in a system search path. 159 /// \param Offset optional offset into the buffer associated with \a ID. This is 160 /// used for handling `#pragma clang module build`. Set to the end 161 /// of the module map on return. 162 /// 163 /// \returns The parsed ModuleMapFile if successful, std::nullopt otherwise. 164 std::optional<ModuleMapFile> 165 parseModuleMap(FileID ID, clang::DirectoryEntryRef Dir, SourceManager &SM, 166 DiagnosticsEngine &Diags, bool IsSystem, unsigned *Offset); 167 168 } // namespace modulemap 169 } // namespace clang 170 171 #endif 172