Skip to content

Commit 12f19b1

Browse files
committed
[clang][modules] Separate parsing of modulemaps
This separates out parsing of modulemaps from updating the `clang::ModuleMap` information. Currently this has no effect other than slightly changing diagnostics. Upcoming changes will use this to allow searching for modules without fully processing modulemaps.
1 parent 4b825c7 commit 12f19b1

File tree

11 files changed

+1634
-1246
lines changed

11 files changed

+1634
-1246
lines changed

clang/include/clang/Basic/DiagnosticLexKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,8 @@ def warn_mmap_redundant_export_as : Warning<
914914
InGroup<PrivateModule>;
915915
def err_mmap_submodule_export_as : Error<
916916
"only top-level modules can be re-exported as public">;
917+
def err_mmap_qualified_export_as : Error<
918+
"a module can only be re-exported as another top-level module">;
917919

918920
def warn_quoted_include_in_framework_header : Warning<
919921
"double-quoted include \"%0\" in framework header, "

clang/include/clang/Basic/Module.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,30 @@ struct ASTFileSignature : std::array<uint8_t, 20> {
100100
}
101101
};
102102

103+
/// The set of attributes that can be attached to a module.
104+
struct ModuleAttributes {
105+
/// Whether this is a system module.
106+
LLVM_PREFERRED_TYPE(bool)
107+
unsigned IsSystem : 1;
108+
109+
/// Whether this is an extern "C" module.
110+
LLVM_PREFERRED_TYPE(bool)
111+
unsigned IsExternC : 1;
112+
113+
/// Whether this is an exhaustive set of configuration macros.
114+
LLVM_PREFERRED_TYPE(bool)
115+
unsigned IsExhaustive : 1;
116+
117+
/// Whether files in this module can only include non-modular headers
118+
/// and headers from used modules.
119+
LLVM_PREFERRED_TYPE(bool)
120+
unsigned NoUndeclaredIncludes : 1;
121+
122+
ModuleAttributes()
123+
: IsSystem(false), IsExternC(false), IsExhaustive(false),
124+
NoUndeclaredIncludes(false) {}
125+
};
126+
103127
/// Required to construct a Module.
104128
///
105129
/// This tag type is only constructible by ModuleMap, guaranteeing it ownership

clang/include/clang/Lex/ModuleMap.h

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -232,29 +232,7 @@ class ModuleMap {
232232

233233
llvm::DenseMap<Module *, unsigned> ModuleScopeIDs;
234234

235-
/// The set of attributes that can be attached to a module.
236-
struct Attributes {
237-
/// Whether this is a system module.
238-
LLVM_PREFERRED_TYPE(bool)
239-
unsigned IsSystem : 1;
240-
241-
/// Whether this is an extern "C" module.
242-
LLVM_PREFERRED_TYPE(bool)
243-
unsigned IsExternC : 1;
244-
245-
/// Whether this is an exhaustive set of configuration macros.
246-
LLVM_PREFERRED_TYPE(bool)
247-
unsigned IsExhaustive : 1;
248-
249-
/// Whether files in this module can only include non-modular headers
250-
/// and headers from used modules.
251-
LLVM_PREFERRED_TYPE(bool)
252-
unsigned NoUndeclaredIncludes : 1;
253-
254-
Attributes()
255-
: IsSystem(false), IsExternC(false), IsExhaustive(false),
256-
NoUndeclaredIncludes(false) {}
257-
};
235+
using Attributes = ModuleAttributes;
258236

259237
/// A directory for which framework modules can be inferred.
260238
struct InferredDirectory {
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
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+
using Decl =
30+
std::variant<struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl,
31+
struct ModuleDecl, struct ExcludeDecl, struct ExportDecl,
32+
struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl,
33+
struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl>;
34+
35+
struct RequiresFeature {
36+
SourceLocation Location;
37+
StringRef Feature;
38+
bool RequiredState = true;
39+
};
40+
41+
struct RequiresDecl {
42+
SourceLocation Location;
43+
std::vector<RequiresFeature> Features;
44+
};
45+
46+
struct HeaderDecl {
47+
SourceLocation Location;
48+
StringRef Path;
49+
SourceLocation PathLoc;
50+
std::optional<int64_t> Size;
51+
std::optional<int64_t> MTime;
52+
LLVM_PREFERRED_TYPE(bool)
53+
unsigned Private : 1;
54+
LLVM_PREFERRED_TYPE(bool)
55+
unsigned Textual : 1;
56+
LLVM_PREFERRED_TYPE(bool)
57+
unsigned Umbrella : 1;
58+
LLVM_PREFERRED_TYPE(bool)
59+
unsigned Excluded : 1;
60+
};
61+
62+
struct UmbrellaDirDecl {
63+
SourceLocation Location;
64+
StringRef Path;
65+
};
66+
67+
struct ModuleDecl {
68+
SourceLocation Location; /// Points to the first keyword in the decl.
69+
ModuleId Id;
70+
ModuleAttributes Attrs;
71+
std::vector<Decl> Decls;
72+
73+
LLVM_PREFERRED_TYPE(bool)
74+
unsigned Explicit : 1;
75+
LLVM_PREFERRED_TYPE(bool)
76+
unsigned Framework : 1;
77+
};
78+
79+
struct ExcludeDecl {
80+
SourceLocation Location;
81+
StringRef Module;
82+
};
83+
84+
struct ExportDecl {
85+
SourceLocation Location;
86+
ModuleId Id;
87+
bool Wildcard;
88+
};
89+
90+
struct ExportAsDecl {
91+
SourceLocation Location;
92+
ModuleId Id;
93+
};
94+
95+
struct ExternModuleDecl {
96+
SourceLocation Location;
97+
ModuleId Id;
98+
StringRef Path;
99+
};
100+
101+
struct UseDecl {
102+
SourceLocation Location;
103+
ModuleId Id;
104+
};
105+
106+
struct LinkDecl {
107+
SourceLocation Location;
108+
StringRef Library;
109+
LLVM_PREFERRED_TYPE(bool)
110+
unsigned Framework : 1;
111+
};
112+
113+
struct ConfigMacrosDecl {
114+
SourceLocation Location;
115+
std::vector<StringRef> Macros;
116+
LLVM_PREFERRED_TYPE(bool)
117+
unsigned Exhaustive : 1;
118+
};
119+
120+
struct ConflictDecl {
121+
SourceLocation Location;
122+
ModuleId Id;
123+
StringRef Message;
124+
};
125+
126+
using TopLevelDecl =
127+
std::variant<ModuleDecl, ExternModuleDecl>;
128+
129+
struct ModuleMapFile {
130+
std::vector<TopLevelDecl> Decls;
131+
};
132+
133+
std::optional<ModuleMapFile> parseModuleMap(FileEntryRef File,
134+
SourceManager &SM,
135+
DiagnosticsEngine &Diags,
136+
bool IsSystem, unsigned *Offset);
137+
void dumpModuleMapFile(ModuleMapFile &MMF, llvm::raw_ostream &out);
138+
139+
} // namespace modulemap
140+
} // namespace clang
141+
142+
#endif

clang/lib/Lex/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_clang_library(clangLex
1515
MacroArgs.cpp
1616
MacroInfo.cpp
1717
ModuleMap.cpp
18+
ModuleMapFile.cpp
1819
PPCaching.cpp
1920
PPCallbacks.cpp
2021
PPConditionalDirectiveRecord.cpp

0 commit comments

Comments
 (0)