xref: /freebsd/contrib/llvm-project/clang/include/clang/Lex/ModuleMapFile.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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