Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Lex/ModuleMap.cpp
35232 views
1
//===- ModuleMap.cpp - Describe the layout of modules ---------------------===//
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 ModuleMap implementation, which describes the layout
10
// of a module as it relates to headers.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/Lex/ModuleMap.h"
15
#include "clang/Basic/CharInfo.h"
16
#include "clang/Basic/Diagnostic.h"
17
#include "clang/Basic/FileManager.h"
18
#include "clang/Basic/LLVM.h"
19
#include "clang/Basic/LangOptions.h"
20
#include "clang/Basic/Module.h"
21
#include "clang/Basic/SourceLocation.h"
22
#include "clang/Basic/SourceManager.h"
23
#include "clang/Basic/TargetInfo.h"
24
#include "clang/Lex/HeaderSearch.h"
25
#include "clang/Lex/HeaderSearchOptions.h"
26
#include "clang/Lex/LexDiagnostic.h"
27
#include "clang/Lex/Lexer.h"
28
#include "clang/Lex/LiteralSupport.h"
29
#include "clang/Lex/Token.h"
30
#include "llvm/ADT/DenseMap.h"
31
#include "llvm/ADT/STLExtras.h"
32
#include "llvm/ADT/SmallPtrSet.h"
33
#include "llvm/ADT/SmallString.h"
34
#include "llvm/ADT/SmallVector.h"
35
#include "llvm/ADT/StringMap.h"
36
#include "llvm/ADT/StringRef.h"
37
#include "llvm/ADT/StringSwitch.h"
38
#include "llvm/Support/Allocator.h"
39
#include "llvm/Support/Compiler.h"
40
#include "llvm/Support/ErrorHandling.h"
41
#include "llvm/Support/MemoryBuffer.h"
42
#include "llvm/Support/Path.h"
43
#include "llvm/Support/VirtualFileSystem.h"
44
#include "llvm/Support/raw_ostream.h"
45
#include <algorithm>
46
#include <cassert>
47
#include <cstdint>
48
#include <cstring>
49
#include <optional>
50
#include <string>
51
#include <system_error>
52
#include <utility>
53
54
using namespace clang;
55
56
void ModuleMapCallbacks::anchor() {}
57
58
void ModuleMap::resolveLinkAsDependencies(Module *Mod) {
59
auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);
60
if (PendingLinkAs != PendingLinkAsModule.end()) {
61
for (auto &Name : PendingLinkAs->second) {
62
auto *M = findModule(Name.getKey());
63
if (M)
64
M->UseExportAsModuleLinkName = true;
65
}
66
}
67
}
68
69
void ModuleMap::addLinkAsDependency(Module *Mod) {
70
if (findModule(Mod->ExportAsModule))
71
Mod->UseExportAsModuleLinkName = true;
72
else
73
PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name);
74
}
75
76
Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) {
77
switch ((int)Role) {
78
case NormalHeader:
79
return Module::HK_Normal;
80
case PrivateHeader:
81
return Module::HK_Private;
82
case TextualHeader:
83
return Module::HK_Textual;
84
case PrivateHeader | TextualHeader:
85
return Module::HK_PrivateTextual;
86
case ExcludedHeader:
87
return Module::HK_Excluded;
88
}
89
llvm_unreachable("unknown header role");
90
}
91
92
ModuleMap::ModuleHeaderRole
93
ModuleMap::headerKindToRole(Module::HeaderKind Kind) {
94
switch ((int)Kind) {
95
case Module::HK_Normal:
96
return NormalHeader;
97
case Module::HK_Private:
98
return PrivateHeader;
99
case Module::HK_Textual:
100
return TextualHeader;
101
case Module::HK_PrivateTextual:
102
return ModuleHeaderRole(PrivateHeader | TextualHeader);
103
case Module::HK_Excluded:
104
return ExcludedHeader;
105
}
106
llvm_unreachable("unknown header kind");
107
}
108
109
bool ModuleMap::isModular(ModuleHeaderRole Role) {
110
return !(Role & (ModuleMap::TextualHeader | ModuleMap::ExcludedHeader));
111
}
112
113
Module::ExportDecl
114
ModuleMap::resolveExport(Module *Mod,
115
const Module::UnresolvedExportDecl &Unresolved,
116
bool Complain) const {
117
// We may have just a wildcard.
118
if (Unresolved.Id.empty()) {
119
assert(Unresolved.Wildcard && "Invalid unresolved export");
120
return Module::ExportDecl(nullptr, true);
121
}
122
123
// Resolve the module-id.
124
Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
125
if (!Context)
126
return {};
127
128
return Module::ExportDecl(Context, Unresolved.Wildcard);
129
}
130
131
Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
132
bool Complain) const {
133
// Find the starting module.
134
Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
135
if (!Context) {
136
if (Complain)
137
Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
138
<< Id[0].first << Mod->getFullModuleName();
139
140
return nullptr;
141
}
142
143
// Dig into the module path.
144
for (unsigned I = 1, N = Id.size(); I != N; ++I) {
145
Module *Sub = lookupModuleQualified(Id[I].first, Context);
146
if (!Sub) {
147
if (Complain)
148
Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
149
<< Id[I].first << Context->getFullModuleName()
150
<< SourceRange(Id[0].second, Id[I-1].second);
151
152
return nullptr;
153
}
154
155
Context = Sub;
156
}
157
158
return Context;
159
}
160
161
/// Append to \p Paths the set of paths needed to get to the
162
/// subframework in which the given module lives.
163
static void appendSubframeworkPaths(Module *Mod,
164
SmallVectorImpl<char> &Path) {
165
// Collect the framework names from the given module to the top-level module.
166
SmallVector<StringRef, 2> Paths;
167
for (; Mod; Mod = Mod->Parent) {
168
if (Mod->IsFramework)
169
Paths.push_back(Mod->Name);
170
}
171
172
if (Paths.empty())
173
return;
174
175
// Add Frameworks/Name.framework for each subframework.
176
for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))
177
llvm::sys::path::append(Path, "Frameworks", Framework + ".framework");
178
}
179
180
OptionalFileEntryRef ModuleMap::findHeader(
181
Module *M, const Module::UnresolvedHeaderDirective &Header,
182
SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) {
183
// Search for the header file within the module's home directory.
184
auto Directory = M->Directory;
185
SmallString<128> FullPathName(Directory->getName());
186
187
auto GetFile = [&](StringRef Filename) -> OptionalFileEntryRef {
188
auto File =
189
expectedToOptional(SourceMgr.getFileManager().getFileRef(Filename));
190
if (!File || (Header.Size && File->getSize() != *Header.Size) ||
191
(Header.ModTime && File->getModificationTime() != *Header.ModTime))
192
return std::nullopt;
193
return *File;
194
};
195
196
auto GetFrameworkFile = [&]() -> OptionalFileEntryRef {
197
unsigned FullPathLength = FullPathName.size();
198
appendSubframeworkPaths(M, RelativePathName);
199
unsigned RelativePathLength = RelativePathName.size();
200
201
// Check whether this file is in the public headers.
202
llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
203
llvm::sys::path::append(FullPathName, RelativePathName);
204
if (auto File = GetFile(FullPathName))
205
return File;
206
207
// Check whether this file is in the private headers.
208
// Ideally, private modules in the form 'FrameworkName.Private' should
209
// be defined as 'module FrameworkName.Private', and not as
210
// 'framework module FrameworkName.Private', since a 'Private.Framework'
211
// does not usually exist. However, since both are currently widely used
212
// for private modules, make sure we find the right path in both cases.
213
if (M->IsFramework && M->Name == "Private")
214
RelativePathName.clear();
215
else
216
RelativePathName.resize(RelativePathLength);
217
FullPathName.resize(FullPathLength);
218
llvm::sys::path::append(RelativePathName, "PrivateHeaders",
219
Header.FileName);
220
llvm::sys::path::append(FullPathName, RelativePathName);
221
return GetFile(FullPathName);
222
};
223
224
if (llvm::sys::path::is_absolute(Header.FileName)) {
225
RelativePathName.clear();
226
RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
227
return GetFile(Header.FileName);
228
}
229
230
if (M->isPartOfFramework())
231
return GetFrameworkFile();
232
233
// Lookup for normal headers.
234
llvm::sys::path::append(RelativePathName, Header.FileName);
235
llvm::sys::path::append(FullPathName, RelativePathName);
236
auto NormalHdrFile = GetFile(FullPathName);
237
238
if (!NormalHdrFile && Directory->getName().ends_with(".framework")) {
239
// The lack of 'framework' keyword in a module declaration it's a simple
240
// mistake we can diagnose when the header exists within the proper
241
// framework style path.
242
FullPathName.assign(Directory->getName());
243
RelativePathName.clear();
244
if (GetFrameworkFile()) {
245
Diags.Report(Header.FileNameLoc,
246
diag::warn_mmap_incomplete_framework_module_declaration)
247
<< Header.FileName << M->getFullModuleName();
248
NeedsFramework = true;
249
}
250
return std::nullopt;
251
}
252
253
return NormalHdrFile;
254
}
255
256
/// Determine whether the given file name is the name of a builtin
257
/// header, supplied by Clang to replace, override, or augment existing system
258
/// headers.
259
static bool isBuiltinHeaderName(StringRef FileName) {
260
return llvm::StringSwitch<bool>(FileName)
261
.Case("float.h", true)
262
.Case("iso646.h", true)
263
.Case("limits.h", true)
264
.Case("stdalign.h", true)
265
.Case("stdarg.h", true)
266
.Case("stdatomic.h", true)
267
.Case("stdbool.h", true)
268
.Case("stddef.h", true)
269
.Case("stdint.h", true)
270
.Case("tgmath.h", true)
271
.Case("unwind.h", true)
272
.Default(false);
273
}
274
275
/// Determine whether the given module name is the name of a builtin
276
/// module that is cyclic with a system module on some platforms.
277
static bool isBuiltInModuleName(StringRef ModuleName) {
278
return llvm::StringSwitch<bool>(ModuleName)
279
.Case("_Builtin_float", true)
280
.Case("_Builtin_inttypes", true)
281
.Case("_Builtin_iso646", true)
282
.Case("_Builtin_limits", true)
283
.Case("_Builtin_stdalign", true)
284
.Case("_Builtin_stdarg", true)
285
.Case("_Builtin_stdatomic", true)
286
.Case("_Builtin_stdbool", true)
287
.Case("_Builtin_stddef", true)
288
.Case("_Builtin_stdint", true)
289
.Case("_Builtin_stdnoreturn", true)
290
.Case("_Builtin_tgmath", true)
291
.Case("_Builtin_unwind", true)
292
.Default(false);
293
}
294
295
void ModuleMap::resolveHeader(Module *Mod,
296
const Module::UnresolvedHeaderDirective &Header,
297
bool &NeedsFramework) {
298
SmallString<128> RelativePathName;
299
if (OptionalFileEntryRef File =
300
findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
301
if (Header.IsUmbrella) {
302
const DirectoryEntry *UmbrellaDir = &File->getDir().getDirEntry();
303
if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
304
Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
305
<< UmbrellaMod->getFullModuleName();
306
else
307
// Record this umbrella header.
308
setUmbrellaHeaderAsWritten(Mod, *File, Header.FileName,
309
RelativePathName.str());
310
} else {
311
Module::Header H = {Header.FileName, std::string(RelativePathName),
312
*File};
313
addHeader(Mod, H, headerKindToRole(Header.Kind));
314
}
315
} else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) {
316
// There's a builtin header but no corresponding on-disk header. Assume
317
// this was supposed to modularize the builtin header alone.
318
} else if (Header.Kind == Module::HK_Excluded) {
319
// Ignore missing excluded header files. They're optional anyway.
320
} else {
321
// If we find a module that has a missing header, we mark this module as
322
// unavailable and store the header directive for displaying diagnostics.
323
Mod->MissingHeaders.push_back(Header);
324
// A missing header with stat information doesn't make the module
325
// unavailable; this keeps our behavior consistent as headers are lazily
326
// resolved. (Such a module still can't be built though, except from
327
// preprocessed source.)
328
if (!Header.Size && !Header.ModTime)
329
Mod->markUnavailable(/*Unimportable=*/false);
330
}
331
}
332
333
bool ModuleMap::resolveAsBuiltinHeader(
334
Module *Mod, const Module::UnresolvedHeaderDirective &Header) {
335
if (Header.Kind == Module::HK_Excluded ||
336
llvm::sys::path::is_absolute(Header.FileName) ||
337
Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
338
!BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
339
!LangOpts.BuiltinHeadersInSystemModules || !isBuiltinHeaderName(Header.FileName))
340
return false;
341
342
// This is a system module with a top-level header. This header
343
// may have a counterpart (or replacement) in the set of headers
344
// supplied by Clang. Find that builtin header.
345
SmallString<128> Path;
346
llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
347
auto File = SourceMgr.getFileManager().getOptionalFileRef(Path);
348
if (!File)
349
return false;
350
351
Module::Header H = {Header.FileName, Header.FileName, *File};
352
auto Role = headerKindToRole(Header.Kind);
353
addHeader(Mod, H, Role);
354
return true;
355
}
356
357
ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
358
const LangOptions &LangOpts, const TargetInfo *Target,
359
HeaderSearch &HeaderInfo)
360
: SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
361
HeaderInfo(HeaderInfo) {
362
MMapLangOpts.LineComment = true;
363
}
364
365
ModuleMap::~ModuleMap() {
366
for (auto &M : Modules)
367
delete M.getValue();
368
for (auto *M : ShadowModules)
369
delete M;
370
}
371
372
void ModuleMap::setTarget(const TargetInfo &Target) {
373
assert((!this->Target || this->Target == &Target) &&
374
"Improper target override");
375
this->Target = &Target;
376
}
377
378
/// "Sanitize" a filename so that it can be used as an identifier.
379
static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
380
SmallVectorImpl<char> &Buffer) {
381
if (Name.empty())
382
return Name;
383
384
if (!isValidAsciiIdentifier(Name)) {
385
// If we don't already have something with the form of an identifier,
386
// create a buffer with the sanitized name.
387
Buffer.clear();
388
if (isDigit(Name[0]))
389
Buffer.push_back('_');
390
Buffer.reserve(Buffer.size() + Name.size());
391
for (unsigned I = 0, N = Name.size(); I != N; ++I) {
392
if (isAsciiIdentifierContinue(Name[I]))
393
Buffer.push_back(Name[I]);
394
else
395
Buffer.push_back('_');
396
}
397
398
Name = StringRef(Buffer.data(), Buffer.size());
399
}
400
401
while (llvm::StringSwitch<bool>(Name)
402
#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
403
#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
404
#include "clang/Basic/TokenKinds.def"
405
.Default(false)) {
406
if (Name.data() != Buffer.data())
407
Buffer.append(Name.begin(), Name.end());
408
Buffer.push_back('_');
409
Name = StringRef(Buffer.data(), Buffer.size());
410
}
411
412
return Name;
413
}
414
415
bool ModuleMap::isBuiltinHeader(FileEntryRef File) {
416
return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
417
isBuiltinHeaderName(llvm::sys::path::filename(File.getName()));
418
}
419
420
bool ModuleMap::shouldImportRelativeToBuiltinIncludeDir(StringRef FileName,
421
Module *Module) const {
422
return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
423
Module->IsSystem && !Module->isPartOfFramework() &&
424
isBuiltinHeaderName(FileName);
425
}
426
427
ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(FileEntryRef File) {
428
resolveHeaderDirectives(File);
429
HeadersMap::iterator Known = Headers.find(File);
430
if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
431
Known == Headers.end() && ModuleMap::isBuiltinHeader(File)) {
432
HeaderInfo.loadTopLevelSystemModules();
433
return Headers.find(File);
434
}
435
return Known;
436
}
437
438
ModuleMap::KnownHeader ModuleMap::findHeaderInUmbrellaDirs(
439
FileEntryRef File, SmallVectorImpl<DirectoryEntryRef> &IntermediateDirs) {
440
if (UmbrellaDirs.empty())
441
return {};
442
443
OptionalDirectoryEntryRef Dir = File.getDir();
444
445
// Note: as an egregious but useful hack we use the real path here, because
446
// frameworks moving from top-level frameworks to embedded frameworks tend
447
// to be symlinked from the top-level location to the embedded location,
448
// and we need to resolve lookups as if we had found the embedded location.
449
StringRef DirName = SourceMgr.getFileManager().getCanonicalName(*Dir);
450
451
// Keep walking up the directory hierarchy, looking for a directory with
452
// an umbrella header.
453
do {
454
auto KnownDir = UmbrellaDirs.find(*Dir);
455
if (KnownDir != UmbrellaDirs.end())
456
return KnownHeader(KnownDir->second, NormalHeader);
457
458
IntermediateDirs.push_back(*Dir);
459
460
// Retrieve our parent path.
461
DirName = llvm::sys::path::parent_path(DirName);
462
if (DirName.empty())
463
break;
464
465
// Resolve the parent path to a directory entry.
466
Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
467
} while (Dir);
468
return {};
469
}
470
471
static bool violatesPrivateInclude(Module *RequestingModule,
472
const FileEntry *IncFileEnt,
473
ModuleMap::KnownHeader Header) {
474
#ifndef NDEBUG
475
if (Header.getRole() & ModuleMap::PrivateHeader) {
476
// Check for consistency between the module header role
477
// as obtained from the lookup and as obtained from the module.
478
// This check is not cheap, so enable it only for debugging.
479
bool IsPrivate = false;
480
SmallVectorImpl<Module::Header> *HeaderList[] = {
481
&Header.getModule()->Headers[Module::HK_Private],
482
&Header.getModule()->Headers[Module::HK_PrivateTextual]};
483
for (auto *Hs : HeaderList)
484
IsPrivate |= llvm::any_of(
485
*Hs, [&](const Module::Header &H) { return H.Entry == IncFileEnt; });
486
assert(IsPrivate && "inconsistent headers and roles");
487
}
488
#endif
489
return !Header.isAccessibleFrom(RequestingModule);
490
}
491
492
static Module *getTopLevelOrNull(Module *M) {
493
return M ? M->getTopLevelModule() : nullptr;
494
}
495
496
void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
497
bool RequestingModuleIsModuleInterface,
498
SourceLocation FilenameLoc,
499
StringRef Filename, FileEntryRef File) {
500
// No errors for indirect modules. This may be a bit of a problem for modules
501
// with no source files.
502
if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
503
return;
504
505
if (RequestingModule) {
506
resolveUses(RequestingModule, /*Complain=*/false);
507
resolveHeaderDirectives(RequestingModule, /*File=*/std::nullopt);
508
}
509
510
bool Excluded = false;
511
Module *Private = nullptr;
512
Module *NotUsed = nullptr;
513
514
HeadersMap::iterator Known = findKnownHeader(File);
515
if (Known != Headers.end()) {
516
for (const KnownHeader &Header : Known->second) {
517
// Excluded headers don't really belong to a module.
518
if (Header.getRole() == ModuleMap::ExcludedHeader) {
519
Excluded = true;
520
continue;
521
}
522
523
// Remember private headers for later printing of a diagnostic.
524
if (violatesPrivateInclude(RequestingModule, File, Header)) {
525
Private = Header.getModule();
526
continue;
527
}
528
529
// If uses need to be specified explicitly, we are only allowed to return
530
// modules that are explicitly used by the requesting module.
531
if (RequestingModule && LangOpts.ModulesDeclUse &&
532
!RequestingModule->directlyUses(Header.getModule())) {
533
NotUsed = Header.getModule();
534
continue;
535
}
536
537
// We have found a module that we can happily use.
538
return;
539
}
540
541
Excluded = true;
542
}
543
544
// We have found a header, but it is private.
545
if (Private) {
546
Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
547
<< Filename;
548
return;
549
}
550
551
// We have found a module, but we don't use it.
552
if (NotUsed) {
553
Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
554
<< RequestingModule->getTopLevelModule()->Name << Filename
555
<< NotUsed->Name;
556
return;
557
}
558
559
if (Excluded || isHeaderInUmbrellaDirs(File))
560
return;
561
562
// At this point, only non-modular includes remain.
563
564
if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
565
Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
566
<< RequestingModule->getTopLevelModule()->Name << Filename;
567
} else if (RequestingModule && RequestingModuleIsModuleInterface &&
568
LangOpts.isCompilingModule()) {
569
// Do not diagnose when we are not compiling a module.
570
diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
571
diag::warn_non_modular_include_in_framework_module :
572
diag::warn_non_modular_include_in_module;
573
Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
574
<< File.getName();
575
}
576
}
577
578
static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
579
const ModuleMap::KnownHeader &Old) {
580
// Prefer available modules.
581
// FIXME: Considering whether the module is available rather than merely
582
// importable is non-hermetic and can result in surprising behavior for
583
// prebuilt modules. Consider only checking for importability here.
584
if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
585
return true;
586
587
// Prefer a public header over a private header.
588
if ((New.getRole() & ModuleMap::PrivateHeader) !=
589
(Old.getRole() & ModuleMap::PrivateHeader))
590
return !(New.getRole() & ModuleMap::PrivateHeader);
591
592
// Prefer a non-textual header over a textual header.
593
if ((New.getRole() & ModuleMap::TextualHeader) !=
594
(Old.getRole() & ModuleMap::TextualHeader))
595
return !(New.getRole() & ModuleMap::TextualHeader);
596
597
// Prefer a non-excluded header over an excluded header.
598
if ((New.getRole() == ModuleMap::ExcludedHeader) !=
599
(Old.getRole() == ModuleMap::ExcludedHeader))
600
return New.getRole() != ModuleMap::ExcludedHeader;
601
602
// Don't have a reason to choose between these. Just keep the first one.
603
return false;
604
}
605
606
ModuleMap::KnownHeader ModuleMap::findModuleForHeader(FileEntryRef File,
607
bool AllowTextual,
608
bool AllowExcluded) {
609
auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
610
if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
611
return {};
612
return R;
613
};
614
615
HeadersMap::iterator Known = findKnownHeader(File);
616
if (Known != Headers.end()) {
617
ModuleMap::KnownHeader Result;
618
// Iterate over all modules that 'File' is part of to find the best fit.
619
for (KnownHeader &H : Known->second) {
620
// Cannot use a module if the header is excluded in it.
621
if (!AllowExcluded && H.getRole() == ModuleMap::ExcludedHeader)
622
continue;
623
// Prefer a header from the source module over all others.
624
if (H.getModule()->getTopLevelModule() == SourceModule)
625
return MakeResult(H);
626
if (!Result || isBetterKnownHeader(H, Result))
627
Result = H;
628
}
629
return MakeResult(Result);
630
}
631
632
return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
633
}
634
635
ModuleMap::KnownHeader
636
ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
637
assert(!Headers.count(File) && "already have a module for this header");
638
639
SmallVector<DirectoryEntryRef, 2> SkippedDirs;
640
KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
641
if (H) {
642
Module *Result = H.getModule();
643
644
// Search up the module stack until we find a module with an umbrella
645
// directory.
646
Module *UmbrellaModule = Result;
647
while (!UmbrellaModule->getEffectiveUmbrellaDir() && UmbrellaModule->Parent)
648
UmbrellaModule = UmbrellaModule->Parent;
649
650
if (UmbrellaModule->InferSubmodules) {
651
FileID UmbrellaModuleMap = getModuleMapFileIDForUniquing(UmbrellaModule);
652
653
// Infer submodules for each of the directories we found between
654
// the directory of the umbrella header and the directory where
655
// the actual header is located.
656
bool Explicit = UmbrellaModule->InferExplicitSubmodules;
657
658
for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
659
// Find or create the module that corresponds to this directory name.
660
SmallString<32> NameBuf;
661
StringRef Name = sanitizeFilenameAsIdentifier(
662
llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
663
Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
664
Explicit).first;
665
InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
666
Result->IsInferred = true;
667
668
// Associate the module and the directory.
669
UmbrellaDirs[SkippedDir] = Result;
670
671
// If inferred submodules export everything they import, add a
672
// wildcard to the set of exports.
673
if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
674
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
675
}
676
677
// Infer a submodule with the same name as this header file.
678
SmallString<32> NameBuf;
679
StringRef Name = sanitizeFilenameAsIdentifier(
680
llvm::sys::path::stem(File.getName()), NameBuf);
681
Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
682
Explicit).first;
683
InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
684
Result->IsInferred = true;
685
Result->addTopHeader(File);
686
687
// If inferred submodules export everything they import, add a
688
// wildcard to the set of exports.
689
if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
690
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
691
} else {
692
// Record each of the directories we stepped through as being part of
693
// the module we found, since the umbrella header covers them all.
694
for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
695
UmbrellaDirs[SkippedDirs[I]] = Result;
696
}
697
698
KnownHeader Header(Result, NormalHeader);
699
Headers[File].push_back(Header);
700
return Header;
701
}
702
703
return {};
704
}
705
706
ArrayRef<ModuleMap::KnownHeader>
707
ModuleMap::findAllModulesForHeader(FileEntryRef File) {
708
HeadersMap::iterator Known = findKnownHeader(File);
709
if (Known != Headers.end())
710
return Known->second;
711
712
if (findOrCreateModuleForHeaderInUmbrellaDir(File))
713
return Headers.find(File)->second;
714
715
return std::nullopt;
716
}
717
718
ArrayRef<ModuleMap::KnownHeader>
719
ModuleMap::findResolvedModulesForHeader(FileEntryRef File) const {
720
// FIXME: Is this necessary?
721
resolveHeaderDirectives(File);
722
auto It = Headers.find(File);
723
if (It == Headers.end())
724
return std::nullopt;
725
return It->second;
726
}
727
728
bool ModuleMap::isHeaderInUnavailableModule(FileEntryRef Header) const {
729
return isHeaderUnavailableInModule(Header, nullptr);
730
}
731
732
bool ModuleMap::isHeaderUnavailableInModule(
733
FileEntryRef Header, const Module *RequestingModule) const {
734
resolveHeaderDirectives(Header);
735
HeadersMap::const_iterator Known = Headers.find(Header);
736
if (Known != Headers.end()) {
737
for (SmallVectorImpl<KnownHeader>::const_iterator
738
I = Known->second.begin(),
739
E = Known->second.end();
740
I != E; ++I) {
741
742
if (I->getRole() == ModuleMap::ExcludedHeader)
743
continue;
744
745
if (I->isAvailable() &&
746
(!RequestingModule ||
747
I->getModule()->isSubModuleOf(RequestingModule))) {
748
// When no requesting module is available, the caller is looking if a
749
// header is part a module by only looking into the module map. This is
750
// done by warn_uncovered_module_header checks; don't consider textual
751
// headers part of it in this mode, otherwise we get misleading warnings
752
// that a umbrella header is not including a textual header.
753
if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
754
continue;
755
return false;
756
}
757
}
758
return true;
759
}
760
761
OptionalDirectoryEntryRef Dir = Header.getDir();
762
SmallVector<DirectoryEntryRef, 2> SkippedDirs;
763
StringRef DirName = Dir->getName();
764
765
auto IsUnavailable = [&](const Module *M) {
766
return !M->isAvailable() && (!RequestingModule ||
767
M->isSubModuleOf(RequestingModule));
768
};
769
770
// Keep walking up the directory hierarchy, looking for a directory with
771
// an umbrella header.
772
do {
773
auto KnownDir = UmbrellaDirs.find(*Dir);
774
if (KnownDir != UmbrellaDirs.end()) {
775
Module *Found = KnownDir->second;
776
if (IsUnavailable(Found))
777
return true;
778
779
// Search up the module stack until we find a module with an umbrella
780
// directory.
781
Module *UmbrellaModule = Found;
782
while (!UmbrellaModule->getEffectiveUmbrellaDir() &&
783
UmbrellaModule->Parent)
784
UmbrellaModule = UmbrellaModule->Parent;
785
786
if (UmbrellaModule->InferSubmodules) {
787
for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
788
// Find or create the module that corresponds to this directory name.
789
SmallString<32> NameBuf;
790
StringRef Name = sanitizeFilenameAsIdentifier(
791
llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
792
Found = lookupModuleQualified(Name, Found);
793
if (!Found)
794
return false;
795
if (IsUnavailable(Found))
796
return true;
797
}
798
799
// Infer a submodule with the same name as this header file.
800
SmallString<32> NameBuf;
801
StringRef Name = sanitizeFilenameAsIdentifier(
802
llvm::sys::path::stem(Header.getName()),
803
NameBuf);
804
Found = lookupModuleQualified(Name, Found);
805
if (!Found)
806
return false;
807
}
808
809
return IsUnavailable(Found);
810
}
811
812
SkippedDirs.push_back(*Dir);
813
814
// Retrieve our parent path.
815
DirName = llvm::sys::path::parent_path(DirName);
816
if (DirName.empty())
817
break;
818
819
// Resolve the parent path to a directory entry.
820
Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
821
} while (Dir);
822
823
return false;
824
}
825
826
Module *ModuleMap::findModule(StringRef Name) const {
827
llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
828
if (Known != Modules.end())
829
return Known->getValue();
830
831
return nullptr;
832
}
833
834
Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
835
Module *Context) const {
836
for(; Context; Context = Context->Parent) {
837
if (Module *Sub = lookupModuleQualified(Name, Context))
838
return Sub;
839
}
840
841
return findModule(Name);
842
}
843
844
Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
845
if (!Context)
846
return findModule(Name);
847
848
return Context->findSubmodule(Name);
849
}
850
851
std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
852
Module *Parent,
853
bool IsFramework,
854
bool IsExplicit) {
855
// Try to find an existing module with this name.
856
if (Module *Sub = lookupModuleQualified(Name, Parent))
857
return std::make_pair(Sub, false);
858
859
// Create a new module with this name.
860
Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
861
IsExplicit, NumCreatedModules++);
862
if (!Parent) {
863
if (LangOpts.CurrentModule == Name)
864
SourceModule = Result;
865
Modules[Name] = Result;
866
ModuleScopeIDs[Result] = CurrentModuleScopeID;
867
}
868
return std::make_pair(Result, true);
869
}
870
871
Module *ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc,
872
Module *Parent) {
873
auto *Result = new Module("<global>", Loc, Parent, /*IsFramework*/ false,
874
/*IsExplicit*/ true, NumCreatedModules++);
875
Result->Kind = Module::ExplicitGlobalModuleFragment;
876
// If the created module isn't owned by a parent, send it to PendingSubmodules
877
// to wait for its parent.
878
if (!Result->Parent)
879
PendingSubmodules.emplace_back(Result);
880
return Result;
881
}
882
883
Module *
884
ModuleMap::createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc,
885
Module *Parent) {
886
assert(Parent && "We should only create an implicit global module fragment "
887
"in a module purview");
888
// Note: Here the `IsExplicit` parameter refers to the semantics in clang
889
// modules. All the non-explicit submodules in clang modules will be exported
890
// too. Here we simplify the implementation by using the concept.
891
auto *Result =
892
new Module("<implicit global>", Loc, Parent, /*IsFramework=*/false,
893
/*IsExplicit=*/false, NumCreatedModules++);
894
Result->Kind = Module::ImplicitGlobalModuleFragment;
895
return Result;
896
}
897
898
Module *
899
ModuleMap::createPrivateModuleFragmentForInterfaceUnit(Module *Parent,
900
SourceLocation Loc) {
901
auto *Result =
902
new Module("<private>", Loc, Parent, /*IsFramework*/ false,
903
/*IsExplicit*/ true, NumCreatedModules++);
904
Result->Kind = Module::PrivateModuleFragment;
905
return Result;
906
}
907
908
Module *ModuleMap::createModuleUnitWithKind(SourceLocation Loc, StringRef Name,
909
Module::ModuleKind Kind) {
910
auto *Result =
911
new Module(Name, Loc, nullptr, /*IsFramework*/ false,
912
/*IsExplicit*/ false, NumCreatedModules++);
913
Result->Kind = Kind;
914
915
// Reparent any current global module fragment as a submodule of this module.
916
for (auto &Submodule : PendingSubmodules) {
917
Submodule->setParent(Result);
918
Submodule.release(); // now owned by parent
919
}
920
PendingSubmodules.clear();
921
return Result;
922
}
923
924
Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
925
StringRef Name) {
926
assert(LangOpts.CurrentModule == Name && "module name mismatch");
927
assert(!Modules[Name] && "redefining existing module");
928
929
auto *Result =
930
createModuleUnitWithKind(Loc, Name, Module::ModuleInterfaceUnit);
931
Modules[Name] = SourceModule = Result;
932
933
// Mark the main source file as being within the newly-created module so that
934
// declarations and macros are properly visibility-restricted to it.
935
auto MainFile = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());
936
assert(MainFile && "no input file for module interface");
937
Headers[*MainFile].push_back(KnownHeader(Result, PrivateHeader));
938
939
return Result;
940
}
941
942
Module *ModuleMap::createModuleForImplementationUnit(SourceLocation Loc,
943
StringRef Name) {
944
assert(LangOpts.CurrentModule == Name && "module name mismatch");
945
// The interface for this implementation must exist and be loaded.
946
assert(Modules[Name] && Modules[Name]->Kind == Module::ModuleInterfaceUnit &&
947
"creating implementation module without an interface");
948
949
// Create an entry in the modules map to own the implementation unit module.
950
// User module names must not start with a period (so that this cannot clash
951
// with any legal user-defined module name).
952
StringRef IName = ".ImplementationUnit";
953
assert(!Modules[IName] && "multiple implementation units?");
954
955
auto *Result =
956
createModuleUnitWithKind(Loc, Name, Module::ModuleImplementationUnit);
957
Modules[IName] = SourceModule = Result;
958
959
// Check that the main file is present.
960
assert(SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) &&
961
"no input file for module implementation");
962
963
return Result;
964
}
965
966
Module *ModuleMap::createHeaderUnit(SourceLocation Loc, StringRef Name,
967
Module::Header H) {
968
assert(LangOpts.CurrentModule == Name && "module name mismatch");
969
assert(!Modules[Name] && "redefining existing module");
970
971
auto *Result = new Module(Name, Loc, nullptr, /*IsFramework*/ false,
972
/*IsExplicit*/ false, NumCreatedModules++);
973
Result->Kind = Module::ModuleHeaderUnit;
974
Modules[Name] = SourceModule = Result;
975
addHeader(Result, H, NormalHeader);
976
return Result;
977
}
978
979
/// For a framework module, infer the framework against which we
980
/// should link.
981
static void inferFrameworkLink(Module *Mod) {
982
assert(Mod->IsFramework && "Can only infer linking for framework modules");
983
assert(!Mod->isSubFramework() &&
984
"Can only infer linking for top-level frameworks");
985
986
StringRef FrameworkName(Mod->Name);
987
FrameworkName.consume_back("_Private");
988
Mod->LinkLibraries.push_back(Module::LinkLibrary(FrameworkName.str(),
989
/*IsFramework=*/true));
990
}
991
992
Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
993
bool IsSystem, Module *Parent) {
994
Attributes Attrs;
995
Attrs.IsSystem = IsSystem;
996
return inferFrameworkModule(FrameworkDir, Attrs, Parent);
997
}
998
999
Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
1000
Attributes Attrs, Module *Parent) {
1001
// Note: as an egregious but useful hack we use the real path here, because
1002
// we might be looking at an embedded framework that symlinks out to a
1003
// top-level framework, and we need to infer as if we were naming the
1004
// top-level framework.
1005
StringRef FrameworkDirName =
1006
SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
1007
1008
// In case this is a case-insensitive filesystem, use the canonical
1009
// directory name as the ModuleName, since modules are case-sensitive.
1010
// FIXME: we should be able to give a fix-it hint for the correct spelling.
1011
SmallString<32> ModuleNameStorage;
1012
StringRef ModuleName = sanitizeFilenameAsIdentifier(
1013
llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
1014
1015
// Check whether we've already found this module.
1016
if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
1017
return Mod;
1018
1019
FileManager &FileMgr = SourceMgr.getFileManager();
1020
1021
// If the framework has a parent path from which we're allowed to infer
1022
// a framework module, do so.
1023
FileID ModuleMapFID;
1024
if (!Parent) {
1025
// Determine whether we're allowed to infer a module map.
1026
bool canInfer = false;
1027
if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1028
// Figure out the parent path.
1029
StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
1030
if (auto ParentDir = FileMgr.getOptionalDirectoryRef(Parent)) {
1031
// Check whether we have already looked into the parent directory
1032
// for a module map.
1033
llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1034
inferred = InferredDirectories.find(*ParentDir);
1035
if (inferred == InferredDirectories.end()) {
1036
// We haven't looked here before. Load a module map, if there is
1037
// one.
1038
bool IsFrameworkDir = Parent.ends_with(".framework");
1039
if (OptionalFileEntryRef ModMapFile =
1040
HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
1041
parseModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir);
1042
inferred = InferredDirectories.find(*ParentDir);
1043
}
1044
1045
if (inferred == InferredDirectories.end())
1046
inferred = InferredDirectories.insert(
1047
std::make_pair(*ParentDir, InferredDirectory())).first;
1048
}
1049
1050
if (inferred->second.InferModules) {
1051
// We're allowed to infer for this directory, but make sure it's okay
1052
// to infer this particular module.
1053
StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1054
canInfer =
1055
!llvm::is_contained(inferred->second.ExcludedModules, Name);
1056
1057
Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1058
Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1059
Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1060
Attrs.NoUndeclaredIncludes |=
1061
inferred->second.Attrs.NoUndeclaredIncludes;
1062
ModuleMapFID = inferred->second.ModuleMapFID;
1063
}
1064
}
1065
}
1066
1067
// If we're not allowed to infer a framework module, don't.
1068
if (!canInfer)
1069
return nullptr;
1070
} else {
1071
ModuleMapFID = getModuleMapFileIDForUniquing(Parent);
1072
}
1073
1074
// Look for an umbrella header.
1075
SmallString<128> UmbrellaName = FrameworkDir.getName();
1076
llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
1077
auto UmbrellaHeader = FileMgr.getOptionalFileRef(UmbrellaName);
1078
1079
// FIXME: If there's no umbrella header, we could probably scan the
1080
// framework to load *everything*. But, it's not clear that this is a good
1081
// idea.
1082
if (!UmbrellaHeader)
1083
return nullptr;
1084
1085
Module *Result = new Module(ModuleName, SourceLocation(), Parent,
1086
/*IsFramework=*/true, /*IsExplicit=*/false,
1087
NumCreatedModules++);
1088
InferredModuleAllowedBy[Result] = ModuleMapFID;
1089
Result->IsInferred = true;
1090
if (!Parent) {
1091
if (LangOpts.CurrentModule == ModuleName)
1092
SourceModule = Result;
1093
Modules[ModuleName] = Result;
1094
ModuleScopeIDs[Result] = CurrentModuleScopeID;
1095
}
1096
1097
Result->IsSystem |= Attrs.IsSystem;
1098
Result->IsExternC |= Attrs.IsExternC;
1099
Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1100
Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1101
Result->Directory = FrameworkDir;
1102
1103
// Chop off the first framework bit, as that is implied.
1104
StringRef RelativePath = UmbrellaName.str().substr(
1105
Result->getTopLevelModule()->Directory->getName().size());
1106
RelativePath = llvm::sys::path::relative_path(RelativePath);
1107
1108
// umbrella header "umbrella-header-name"
1109
setUmbrellaHeaderAsWritten(Result, *UmbrellaHeader, ModuleName + ".h",
1110
RelativePath);
1111
1112
// export *
1113
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
1114
1115
// module * { export * }
1116
Result->InferSubmodules = true;
1117
Result->InferExportWildcard = true;
1118
1119
// Look for subframeworks.
1120
std::error_code EC;
1121
SmallString<128> SubframeworksDirName = FrameworkDir.getName();
1122
llvm::sys::path::append(SubframeworksDirName, "Frameworks");
1123
llvm::sys::path::native(SubframeworksDirName);
1124
llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1125
for (llvm::vfs::directory_iterator
1126
Dir = FS.dir_begin(SubframeworksDirName, EC),
1127
DirEnd;
1128
Dir != DirEnd && !EC; Dir.increment(EC)) {
1129
if (!StringRef(Dir->path()).ends_with(".framework"))
1130
continue;
1131
1132
if (auto SubframeworkDir = FileMgr.getOptionalDirectoryRef(Dir->path())) {
1133
// Note: as an egregious but useful hack, we use the real path here and
1134
// check whether it is actually a subdirectory of the parent directory.
1135
// This will not be the case if the 'subframework' is actually a symlink
1136
// out to a top-level framework.
1137
StringRef SubframeworkDirName =
1138
FileMgr.getCanonicalName(*SubframeworkDir);
1139
bool FoundParent = false;
1140
do {
1141
// Get the parent directory name.
1142
SubframeworkDirName
1143
= llvm::sys::path::parent_path(SubframeworkDirName);
1144
if (SubframeworkDirName.empty())
1145
break;
1146
1147
if (auto SubDir = FileMgr.getDirectory(SubframeworkDirName)) {
1148
if (*SubDir == FrameworkDir) {
1149
FoundParent = true;
1150
break;
1151
}
1152
}
1153
} while (true);
1154
1155
if (!FoundParent)
1156
continue;
1157
1158
// FIXME: Do we want to warn about subframeworks without umbrella headers?
1159
inferFrameworkModule(*SubframeworkDir, Attrs, Result);
1160
}
1161
}
1162
1163
// If the module is a top-level framework, automatically link against the
1164
// framework.
1165
if (!Result->isSubFramework())
1166
inferFrameworkLink(Result);
1167
1168
return Result;
1169
}
1170
1171
Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
1172
Module *ShadowingModule) {
1173
1174
// Create a new module with this name.
1175
Module *Result =
1176
new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework,
1177
/*IsExplicit=*/false, NumCreatedModules++);
1178
Result->ShadowingModule = ShadowingModule;
1179
Result->markUnavailable(/*Unimportable*/true);
1180
ModuleScopeIDs[Result] = CurrentModuleScopeID;
1181
ShadowModules.push_back(Result);
1182
1183
return Result;
1184
}
1185
1186
void ModuleMap::setUmbrellaHeaderAsWritten(
1187
Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,
1188
const Twine &PathRelativeToRootModuleDirectory) {
1189
Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
1190
Mod->Umbrella = UmbrellaHeader;
1191
Mod->UmbrellaAsWritten = NameAsWritten.str();
1192
Mod->UmbrellaRelativeToRootModuleDirectory =
1193
PathRelativeToRootModuleDirectory.str();
1194
UmbrellaDirs[UmbrellaHeader.getDir()] = Mod;
1195
1196
// Notify callbacks that we just added a new header.
1197
for (const auto &Cb : Callbacks)
1198
Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
1199
}
1200
1201
void ModuleMap::setUmbrellaDirAsWritten(
1202
Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten,
1203
const Twine &PathRelativeToRootModuleDirectory) {
1204
Mod->Umbrella = UmbrellaDir;
1205
Mod->UmbrellaAsWritten = NameAsWritten.str();
1206
Mod->UmbrellaRelativeToRootModuleDirectory =
1207
PathRelativeToRootModuleDirectory.str();
1208
UmbrellaDirs[UmbrellaDir] = Mod;
1209
}
1210
1211
void ModuleMap::addUnresolvedHeader(Module *Mod,
1212
Module::UnresolvedHeaderDirective Header,
1213
bool &NeedsFramework) {
1214
// If there is a builtin counterpart to this file, add it now so it can
1215
// wrap the system header.
1216
if (resolveAsBuiltinHeader(Mod, Header)) {
1217
// If we have both a builtin and system version of the file, the
1218
// builtin version may want to inject macros into the system header, so
1219
// force the system header to be treated as a textual header in this
1220
// case.
1221
Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole(
1222
headerKindToRole(Header.Kind) | ModuleMap::TextualHeader));
1223
Header.HasBuiltinHeader = true;
1224
}
1225
1226
// If possible, don't stat the header until we need to. This requires the
1227
// user to have provided us with some stat information about the file.
1228
// FIXME: Add support for lazily stat'ing umbrella headers and excluded
1229
// headers.
1230
if ((Header.Size || Header.ModTime) && !Header.IsUmbrella &&
1231
Header.Kind != Module::HK_Excluded) {
1232
// We expect more variation in mtime than size, so if we're given both,
1233
// use the mtime as the key.
1234
if (Header.ModTime)
1235
LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
1236
else
1237
LazyHeadersBySize[*Header.Size].push_back(Mod);
1238
Mod->UnresolvedHeaders.push_back(Header);
1239
return;
1240
}
1241
1242
// We don't have stat information or can't defer looking this file up.
1243
// Perform the lookup now.
1244
resolveHeader(Mod, Header, NeedsFramework);
1245
}
1246
1247
void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const {
1248
auto BySize = LazyHeadersBySize.find(File->getSize());
1249
if (BySize != LazyHeadersBySize.end()) {
1250
for (auto *M : BySize->second)
1251
resolveHeaderDirectives(M, File);
1252
LazyHeadersBySize.erase(BySize);
1253
}
1254
1255
auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
1256
if (ByModTime != LazyHeadersByModTime.end()) {
1257
for (auto *M : ByModTime->second)
1258
resolveHeaderDirectives(M, File);
1259
LazyHeadersByModTime.erase(ByModTime);
1260
}
1261
}
1262
1263
void ModuleMap::resolveHeaderDirectives(
1264
Module *Mod, std::optional<const FileEntry *> File) const {
1265
bool NeedsFramework = false;
1266
SmallVector<Module::UnresolvedHeaderDirective, 1> NewHeaders;
1267
const auto Size = File ? (*File)->getSize() : 0;
1268
const auto ModTime = File ? (*File)->getModificationTime() : 0;
1269
1270
for (auto &Header : Mod->UnresolvedHeaders) {
1271
if (File && ((Header.ModTime && Header.ModTime != ModTime) ||
1272
(Header.Size && Header.Size != Size)))
1273
NewHeaders.push_back(Header);
1274
else
1275
// This operation is logically const; we're just changing how we represent
1276
// the header information for this file.
1277
const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework);
1278
}
1279
Mod->UnresolvedHeaders.swap(NewHeaders);
1280
}
1281
1282
void ModuleMap::addHeader(Module *Mod, Module::Header Header,
1283
ModuleHeaderRole Role, bool Imported) {
1284
KnownHeader KH(Mod, Role);
1285
1286
// Only add each header to the headers list once.
1287
// FIXME: Should we diagnose if a header is listed twice in the
1288
// same module definition?
1289
auto &HeaderList = Headers[Header.Entry];
1290
if (llvm::is_contained(HeaderList, KH))
1291
return;
1292
1293
HeaderList.push_back(KH);
1294
Mod->Headers[headerRoleToKind(Role)].push_back(Header);
1295
1296
bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts);
1297
if (!Imported || isCompilingModuleHeader) {
1298
// When we import HeaderFileInfo, the external source is expected to
1299
// set the isModuleHeader flag itself.
1300
HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
1301
isCompilingModuleHeader);
1302
}
1303
1304
// Notify callbacks that we just added a new header.
1305
for (const auto &Cb : Callbacks)
1306
Cb->moduleMapAddHeader(Header.Entry.getName());
1307
}
1308
1309
FileID ModuleMap::getContainingModuleMapFileID(const Module *Module) const {
1310
if (Module->DefinitionLoc.isInvalid())
1311
return {};
1312
1313
return SourceMgr.getFileID(Module->DefinitionLoc);
1314
}
1315
1316
OptionalFileEntryRef
1317
ModuleMap::getContainingModuleMapFile(const Module *Module) const {
1318
return SourceMgr.getFileEntryRefForID(getContainingModuleMapFileID(Module));
1319
}
1320
1321
FileID ModuleMap::getModuleMapFileIDForUniquing(const Module *M) const {
1322
if (M->IsInferred) {
1323
assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
1324
return InferredModuleAllowedBy.find(M)->second;
1325
}
1326
return getContainingModuleMapFileID(M);
1327
}
1328
1329
OptionalFileEntryRef
1330
ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
1331
return SourceMgr.getFileEntryRefForID(getModuleMapFileIDForUniquing(M));
1332
}
1333
1334
void ModuleMap::setInferredModuleAllowedBy(Module *M, FileID ModMapFID) {
1335
assert(M->IsInferred && "module not inferred");
1336
InferredModuleAllowedBy[M] = ModMapFID;
1337
}
1338
1339
std::error_code
1340
ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl<char> &Path) {
1341
StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
1342
1343
// Do not canonicalize within the framework; the module map parser expects
1344
// Modules/ not Versions/A/Modules.
1345
if (llvm::sys::path::filename(Dir) == "Modules") {
1346
StringRef Parent = llvm::sys::path::parent_path(Dir);
1347
if (Parent.ends_with(".framework"))
1348
Dir = Parent;
1349
}
1350
1351
FileManager &FM = SourceMgr.getFileManager();
1352
auto DirEntry = FM.getDirectoryRef(Dir.empty() ? "." : Dir);
1353
if (!DirEntry)
1354
return llvm::errorToErrorCode(DirEntry.takeError());
1355
1356
// Canonicalize the directory.
1357
StringRef CanonicalDir = FM.getCanonicalName(*DirEntry);
1358
if (CanonicalDir != Dir)
1359
llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
1360
1361
// In theory, the filename component should also be canonicalized if it
1362
// on a case-insensitive filesystem. However, the extra canonicalization is
1363
// expensive and if clang looked up the filename it will always be lowercase.
1364
1365
// Remove ., remove redundant separators, and switch to native separators.
1366
// This is needed for separators between CanonicalDir and the filename.
1367
llvm::sys::path::remove_dots(Path);
1368
1369
return std::error_code();
1370
}
1371
1372
void ModuleMap::addAdditionalModuleMapFile(const Module *M,
1373
FileEntryRef ModuleMap) {
1374
AdditionalModMaps[M].insert(ModuleMap);
1375
}
1376
1377
LLVM_DUMP_METHOD void ModuleMap::dump() {
1378
llvm::errs() << "Modules:";
1379
for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1380
MEnd = Modules.end();
1381
M != MEnd; ++M)
1382
M->getValue()->print(llvm::errs(), 2);
1383
1384
llvm::errs() << "Headers:";
1385
for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1386
H != HEnd; ++H) {
1387
llvm::errs() << " \"" << H->first.getName() << "\" -> ";
1388
for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
1389
E = H->second.end();
1390
I != E; ++I) {
1391
if (I != H->second.begin())
1392
llvm::errs() << ",";
1393
llvm::errs() << I->getModule()->getFullModuleName();
1394
}
1395
llvm::errs() << "\n";
1396
}
1397
}
1398
1399
bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
1400
auto Unresolved = std::move(Mod->UnresolvedExports);
1401
Mod->UnresolvedExports.clear();
1402
for (auto &UE : Unresolved) {
1403
Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
1404
if (Export.getPointer() || Export.getInt())
1405
Mod->Exports.push_back(Export);
1406
else
1407
Mod->UnresolvedExports.push_back(UE);
1408
}
1409
return !Mod->UnresolvedExports.empty();
1410
}
1411
1412
bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
1413
auto *Top = Mod->getTopLevelModule();
1414
auto Unresolved = std::move(Top->UnresolvedDirectUses);
1415
Top->UnresolvedDirectUses.clear();
1416
for (auto &UDU : Unresolved) {
1417
Module *DirectUse = resolveModuleId(UDU, Top, Complain);
1418
if (DirectUse)
1419
Top->DirectUses.push_back(DirectUse);
1420
else
1421
Top->UnresolvedDirectUses.push_back(UDU);
1422
}
1423
return !Top->UnresolvedDirectUses.empty();
1424
}
1425
1426
bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
1427
auto Unresolved = std::move(Mod->UnresolvedConflicts);
1428
Mod->UnresolvedConflicts.clear();
1429
for (auto &UC : Unresolved) {
1430
if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1431
Module::Conflict Conflict;
1432
Conflict.Other = OtherMod;
1433
Conflict.Message = UC.Message;
1434
Mod->Conflicts.push_back(Conflict);
1435
} else
1436
Mod->UnresolvedConflicts.push_back(UC);
1437
}
1438
return !Mod->UnresolvedConflicts.empty();
1439
}
1440
1441
//----------------------------------------------------------------------------//
1442
// Module map file parser
1443
//----------------------------------------------------------------------------//
1444
1445
namespace clang {
1446
1447
/// A token in a module map file.
1448
struct MMToken {
1449
enum TokenKind {
1450
Comma,
1451
ConfigMacros,
1452
Conflict,
1453
EndOfFile,
1454
HeaderKeyword,
1455
Identifier,
1456
Exclaim,
1457
ExcludeKeyword,
1458
ExplicitKeyword,
1459
ExportKeyword,
1460
ExportAsKeyword,
1461
ExternKeyword,
1462
FrameworkKeyword,
1463
LinkKeyword,
1464
ModuleKeyword,
1465
Period,
1466
PrivateKeyword,
1467
UmbrellaKeyword,
1468
UseKeyword,
1469
RequiresKeyword,
1470
Star,
1471
StringLiteral,
1472
IntegerLiteral,
1473
TextualKeyword,
1474
LBrace,
1475
RBrace,
1476
LSquare,
1477
RSquare
1478
} Kind;
1479
1480
SourceLocation::UIntTy Location;
1481
unsigned StringLength;
1482
union {
1483
// If Kind != IntegerLiteral.
1484
const char *StringData;
1485
1486
// If Kind == IntegerLiteral.
1487
uint64_t IntegerValue;
1488
};
1489
1490
void clear() {
1491
Kind = EndOfFile;
1492
Location = 0;
1493
StringLength = 0;
1494
StringData = nullptr;
1495
}
1496
1497
bool is(TokenKind K) const { return Kind == K; }
1498
1499
SourceLocation getLocation() const {
1500
return SourceLocation::getFromRawEncoding(Location);
1501
}
1502
1503
uint64_t getInteger() const {
1504
return Kind == IntegerLiteral ? IntegerValue : 0;
1505
}
1506
1507
StringRef getString() const {
1508
return Kind == IntegerLiteral ? StringRef()
1509
: StringRef(StringData, StringLength);
1510
}
1511
};
1512
1513
class ModuleMapParser {
1514
Lexer &L;
1515
SourceManager &SourceMgr;
1516
1517
/// Default target information, used only for string literal
1518
/// parsing.
1519
const TargetInfo *Target;
1520
1521
DiagnosticsEngine &Diags;
1522
ModuleMap &Map;
1523
1524
/// The current module map file.
1525
FileID ModuleMapFID;
1526
1527
/// Source location of most recent parsed module declaration
1528
SourceLocation CurrModuleDeclLoc;
1529
1530
/// The directory that file names in this module map file should
1531
/// be resolved relative to.
1532
DirectoryEntryRef Directory;
1533
1534
/// Whether this module map is in a system header directory.
1535
bool IsSystem;
1536
1537
/// Whether an error occurred.
1538
bool HadError = false;
1539
1540
/// Stores string data for the various string literals referenced
1541
/// during parsing.
1542
llvm::BumpPtrAllocator StringData;
1543
1544
/// The current token.
1545
MMToken Tok;
1546
1547
/// The active module.
1548
Module *ActiveModule = nullptr;
1549
1550
/// Whether a module uses the 'requires excluded' hack to mark its
1551
/// contents as 'textual'.
1552
///
1553
/// On older Darwin SDK versions, 'requires excluded' is used to mark the
1554
/// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1555
/// non-modular headers. For backwards compatibility, we continue to
1556
/// support this idiom for just these modules, and map the headers to
1557
/// 'textual' to match the original intent.
1558
llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1559
1560
/// Consume the current token and return its location.
1561
SourceLocation consumeToken();
1562
1563
/// Skip tokens until we reach the a token with the given kind
1564
/// (or the end of the file).
1565
void skipUntil(MMToken::TokenKind K);
1566
1567
bool parseModuleId(ModuleId &Id);
1568
void parseModuleDecl();
1569
void parseExternModuleDecl();
1570
void parseRequiresDecl();
1571
void parseHeaderDecl(MMToken::TokenKind, SourceLocation LeadingLoc);
1572
void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
1573
void parseExportDecl();
1574
void parseExportAsDecl();
1575
void parseUseDecl();
1576
void parseLinkDecl();
1577
void parseConfigMacros();
1578
void parseConflict();
1579
void parseInferredModuleDecl(bool Framework, bool Explicit);
1580
1581
/// Private modules are canonicalized as Foo_Private. Clang provides extra
1582
/// module map search logic to find the appropriate private module when PCH
1583
/// is used with implicit module maps. Warn when private modules are written
1584
/// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1585
void diagnosePrivateModules(SourceLocation ExplicitLoc,
1586
SourceLocation FrameworkLoc);
1587
1588
using Attributes = ModuleMap::Attributes;
1589
1590
bool parseOptionalAttributes(Attributes &Attrs);
1591
1592
public:
1593
ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
1594
const TargetInfo *Target, DiagnosticsEngine &Diags,
1595
ModuleMap &Map, FileID ModuleMapFID,
1596
DirectoryEntryRef Directory, bool IsSystem)
1597
: L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1598
ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {
1599
Tok.clear();
1600
consumeToken();
1601
}
1602
1603
bool parseModuleMapFile();
1604
1605
bool terminatedByDirective() { return false; }
1606
SourceLocation getLocation() { return Tok.getLocation(); }
1607
};
1608
1609
} // namespace clang
1610
1611
SourceLocation ModuleMapParser::consumeToken() {
1612
SourceLocation Result = Tok.getLocation();
1613
1614
retry:
1615
Tok.clear();
1616
Token LToken;
1617
L.LexFromRawLexer(LToken);
1618
Tok.Location = LToken.getLocation().getRawEncoding();
1619
switch (LToken.getKind()) {
1620
case tok::raw_identifier: {
1621
StringRef RI = LToken.getRawIdentifier();
1622
Tok.StringData = RI.data();
1623
Tok.StringLength = RI.size();
1624
Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1625
.Case("config_macros", MMToken::ConfigMacros)
1626
.Case("conflict", MMToken::Conflict)
1627
.Case("exclude", MMToken::ExcludeKeyword)
1628
.Case("explicit", MMToken::ExplicitKeyword)
1629
.Case("export", MMToken::ExportKeyword)
1630
.Case("export_as", MMToken::ExportAsKeyword)
1631
.Case("extern", MMToken::ExternKeyword)
1632
.Case("framework", MMToken::FrameworkKeyword)
1633
.Case("header", MMToken::HeaderKeyword)
1634
.Case("link", MMToken::LinkKeyword)
1635
.Case("module", MMToken::ModuleKeyword)
1636
.Case("private", MMToken::PrivateKeyword)
1637
.Case("requires", MMToken::RequiresKeyword)
1638
.Case("textual", MMToken::TextualKeyword)
1639
.Case("umbrella", MMToken::UmbrellaKeyword)
1640
.Case("use", MMToken::UseKeyword)
1641
.Default(MMToken::Identifier);
1642
break;
1643
}
1644
1645
case tok::comma:
1646
Tok.Kind = MMToken::Comma;
1647
break;
1648
1649
case tok::eof:
1650
Tok.Kind = MMToken::EndOfFile;
1651
break;
1652
1653
case tok::l_brace:
1654
Tok.Kind = MMToken::LBrace;
1655
break;
1656
1657
case tok::l_square:
1658
Tok.Kind = MMToken::LSquare;
1659
break;
1660
1661
case tok::period:
1662
Tok.Kind = MMToken::Period;
1663
break;
1664
1665
case tok::r_brace:
1666
Tok.Kind = MMToken::RBrace;
1667
break;
1668
1669
case tok::r_square:
1670
Tok.Kind = MMToken::RSquare;
1671
break;
1672
1673
case tok::star:
1674
Tok.Kind = MMToken::Star;
1675
break;
1676
1677
case tok::exclaim:
1678
Tok.Kind = MMToken::Exclaim;
1679
break;
1680
1681
case tok::string_literal: {
1682
if (LToken.hasUDSuffix()) {
1683
Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1684
HadError = true;
1685
goto retry;
1686
}
1687
1688
// Parse the string literal.
1689
LangOptions LangOpts;
1690
StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
1691
if (StringLiteral.hadError)
1692
goto retry;
1693
1694
// Copy the string literal into our string data allocator.
1695
unsigned Length = StringLiteral.GetStringLength();
1696
char *Saved = StringData.Allocate<char>(Length + 1);
1697
memcpy(Saved, StringLiteral.GetString().data(), Length);
1698
Saved[Length] = 0;
1699
1700
// Form the token.
1701
Tok.Kind = MMToken::StringLiteral;
1702
Tok.StringData = Saved;
1703
Tok.StringLength = Length;
1704
break;
1705
}
1706
1707
case tok::numeric_constant: {
1708
// We don't support any suffixes or other complications.
1709
SmallString<32> SpellingBuffer;
1710
SpellingBuffer.resize(LToken.getLength() + 1);
1711
const char *Start = SpellingBuffer.data();
1712
unsigned Length =
1713
Lexer::getSpelling(LToken, Start, SourceMgr, Map.LangOpts);
1714
uint64_t Value;
1715
if (StringRef(Start, Length).getAsInteger(0, Value)) {
1716
Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
1717
HadError = true;
1718
goto retry;
1719
}
1720
1721
Tok.Kind = MMToken::IntegerLiteral;
1722
Tok.IntegerValue = Value;
1723
break;
1724
}
1725
1726
case tok::comment:
1727
goto retry;
1728
1729
case tok::hash:
1730
// A module map can be terminated prematurely by
1731
// #pragma clang module contents
1732
// When building the module, we'll treat the rest of the file as the
1733
// contents of the module.
1734
{
1735
auto NextIsIdent = [&](StringRef Str) -> bool {
1736
L.LexFromRawLexer(LToken);
1737
return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
1738
LToken.getRawIdentifier() == Str;
1739
};
1740
if (NextIsIdent("pragma") && NextIsIdent("clang") &&
1741
NextIsIdent("module") && NextIsIdent("contents")) {
1742
Tok.Kind = MMToken::EndOfFile;
1743
break;
1744
}
1745
}
1746
[[fallthrough]];
1747
1748
default:
1749
Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
1750
HadError = true;
1751
goto retry;
1752
}
1753
1754
return Result;
1755
}
1756
1757
void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1758
unsigned braceDepth = 0;
1759
unsigned squareDepth = 0;
1760
do {
1761
switch (Tok.Kind) {
1762
case MMToken::EndOfFile:
1763
return;
1764
1765
case MMToken::LBrace:
1766
if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1767
return;
1768
1769
++braceDepth;
1770
break;
1771
1772
case MMToken::LSquare:
1773
if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1774
return;
1775
1776
++squareDepth;
1777
break;
1778
1779
case MMToken::RBrace:
1780
if (braceDepth > 0)
1781
--braceDepth;
1782
else if (Tok.is(K))
1783
return;
1784
break;
1785
1786
case MMToken::RSquare:
1787
if (squareDepth > 0)
1788
--squareDepth;
1789
else if (Tok.is(K))
1790
return;
1791
break;
1792
1793
default:
1794
if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1795
return;
1796
break;
1797
}
1798
1799
consumeToken();
1800
} while (true);
1801
}
1802
1803
/// Parse a module-id.
1804
///
1805
/// module-id:
1806
/// identifier
1807
/// identifier '.' module-id
1808
///
1809
/// \returns true if an error occurred, false otherwise.
1810
bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1811
Id.clear();
1812
do {
1813
if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
1814
Id.push_back(
1815
std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
1816
consumeToken();
1817
} else {
1818
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1819
return true;
1820
}
1821
1822
if (!Tok.is(MMToken::Period))
1823
break;
1824
1825
consumeToken();
1826
} while (true);
1827
1828
return false;
1829
}
1830
1831
namespace {
1832
1833
/// Enumerates the known attributes.
1834
enum AttributeKind {
1835
/// An unknown attribute.
1836
AT_unknown,
1837
1838
/// The 'system' attribute.
1839
AT_system,
1840
1841
/// The 'extern_c' attribute.
1842
AT_extern_c,
1843
1844
/// The 'exhaustive' attribute.
1845
AT_exhaustive,
1846
1847
/// The 'no_undeclared_includes' attribute.
1848
AT_no_undeclared_includes
1849
};
1850
1851
} // namespace
1852
1853
/// Private modules are canonicalized as Foo_Private. Clang provides extra
1854
/// module map search logic to find the appropriate private module when PCH
1855
/// is used with implicit module maps. Warn when private modules are written
1856
/// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1857
void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc,
1858
SourceLocation FrameworkLoc) {
1859
auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1860
const Module *M, SourceRange ReplLoc) {
1861
auto D = Diags.Report(ActiveModule->DefinitionLoc,
1862
diag::note_mmap_rename_top_level_private_module);
1863
D << BadName << M->Name;
1864
D << FixItHint::CreateReplacement(ReplLoc, Canonical);
1865
};
1866
1867
for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1868
auto const *M = E->getValue();
1869
if (M->Directory != ActiveModule->Directory)
1870
continue;
1871
1872
SmallString<128> FullName(ActiveModule->getFullModuleName());
1873
if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private"))
1874
continue;
1875
SmallString<128> FixedPrivModDecl;
1876
SmallString<128> Canonical(M->Name);
1877
Canonical.append("_Private");
1878
1879
// Foo.Private -> Foo_Private
1880
if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
1881
M->Name == ActiveModule->Parent->Name) {
1882
Diags.Report(ActiveModule->DefinitionLoc,
1883
diag::warn_mmap_mismatched_private_submodule)
1884
<< FullName;
1885
1886
SourceLocation FixItInitBegin = CurrModuleDeclLoc;
1887
if (FrameworkLoc.isValid())
1888
FixItInitBegin = FrameworkLoc;
1889
if (ExplicitLoc.isValid())
1890
FixItInitBegin = ExplicitLoc;
1891
1892
if (FrameworkLoc.isValid() || ActiveModule->Parent->IsFramework)
1893
FixedPrivModDecl.append("framework ");
1894
FixedPrivModDecl.append("module ");
1895
FixedPrivModDecl.append(Canonical);
1896
1897
GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1898
SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1899
continue;
1900
}
1901
1902
// FooPrivate and whatnots -> Foo_Private
1903
if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1904
ActiveModule->Name != Canonical) {
1905
Diags.Report(ActiveModule->DefinitionLoc,
1906
diag::warn_mmap_mismatched_private_module_name)
1907
<< ActiveModule->Name;
1908
GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1909
SourceRange(ActiveModule->DefinitionLoc));
1910
}
1911
}
1912
}
1913
1914
/// Parse a module declaration.
1915
///
1916
/// module-declaration:
1917
/// 'extern' 'module' module-id string-literal
1918
/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1919
/// { module-member* }
1920
///
1921
/// module-member:
1922
/// requires-declaration
1923
/// header-declaration
1924
/// submodule-declaration
1925
/// export-declaration
1926
/// export-as-declaration
1927
/// link-declaration
1928
///
1929
/// submodule-declaration:
1930
/// module-declaration
1931
/// inferred-submodule-declaration
1932
void ModuleMapParser::parseModuleDecl() {
1933
assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1934
Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1935
if (Tok.is(MMToken::ExternKeyword)) {
1936
parseExternModuleDecl();
1937
return;
1938
}
1939
1940
// Parse 'explicit' or 'framework' keyword, if present.
1941
SourceLocation ExplicitLoc;
1942
SourceLocation FrameworkLoc;
1943
bool Explicit = false;
1944
bool Framework = false;
1945
1946
// Parse 'explicit' keyword, if present.
1947
if (Tok.is(MMToken::ExplicitKeyword)) {
1948
ExplicitLoc = consumeToken();
1949
Explicit = true;
1950
}
1951
1952
// Parse 'framework' keyword, if present.
1953
if (Tok.is(MMToken::FrameworkKeyword)) {
1954
FrameworkLoc = consumeToken();
1955
Framework = true;
1956
}
1957
1958
// Parse 'module' keyword.
1959
if (!Tok.is(MMToken::ModuleKeyword)) {
1960
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1961
consumeToken();
1962
HadError = true;
1963
return;
1964
}
1965
CurrModuleDeclLoc = consumeToken(); // 'module' keyword
1966
1967
// If we have a wildcard for the module name, this is an inferred submodule.
1968
// Parse it.
1969
if (Tok.is(MMToken::Star))
1970
return parseInferredModuleDecl(Framework, Explicit);
1971
1972
// Parse the module name.
1973
ModuleId Id;
1974
if (parseModuleId(Id)) {
1975
HadError = true;
1976
return;
1977
}
1978
1979
if (ActiveModule) {
1980
if (Id.size() > 1) {
1981
Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1982
<< SourceRange(Id.front().second, Id.back().second);
1983
1984
HadError = true;
1985
return;
1986
}
1987
} else if (Id.size() == 1 && Explicit) {
1988
// Top-level modules can't be explicit.
1989
Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1990
Explicit = false;
1991
ExplicitLoc = SourceLocation();
1992
HadError = true;
1993
}
1994
1995
Module *PreviousActiveModule = ActiveModule;
1996
if (Id.size() > 1) {
1997
// This module map defines a submodule. Go find the module of which it
1998
// is a submodule.
1999
ActiveModule = nullptr;
2000
const Module *TopLevelModule = nullptr;
2001
for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
2002
if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
2003
if (I == 0)
2004
TopLevelModule = Next;
2005
ActiveModule = Next;
2006
continue;
2007
}
2008
2009
Diags.Report(Id[I].second, diag::err_mmap_missing_parent_module)
2010
<< Id[I].first << (ActiveModule != nullptr)
2011
<< (ActiveModule
2012
? ActiveModule->getTopLevelModule()->getFullModuleName()
2013
: "");
2014
HadError = true;
2015
}
2016
2017
if (TopLevelModule &&
2018
ModuleMapFID != Map.getContainingModuleMapFileID(TopLevelModule)) {
2019
assert(ModuleMapFID !=
2020
Map.getModuleMapFileIDForUniquing(TopLevelModule) &&
2021
"submodule defined in same file as 'module *' that allowed its "
2022
"top-level module");
2023
Map.addAdditionalModuleMapFile(
2024
TopLevelModule, *SourceMgr.getFileEntryRefForID(ModuleMapFID));
2025
}
2026
}
2027
2028
StringRef ModuleName = Id.back().first;
2029
SourceLocation ModuleNameLoc = Id.back().second;
2030
2031
// Parse the optional attribute list.
2032
Attributes Attrs;
2033
if (parseOptionalAttributes(Attrs))
2034
return;
2035
2036
// Parse the opening brace.
2037
if (!Tok.is(MMToken::LBrace)) {
2038
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
2039
<< ModuleName;
2040
HadError = true;
2041
return;
2042
}
2043
SourceLocation LBraceLoc = consumeToken();
2044
2045
// Determine whether this (sub)module has already been defined.
2046
Module *ShadowingModule = nullptr;
2047
if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
2048
// We might see a (re)definition of a module that we already have a
2049
// definition for in four cases:
2050
// - If we loaded one definition from an AST file and we've just found a
2051
// corresponding definition in a module map file, or
2052
bool LoadedFromASTFile = Existing->IsFromModuleFile;
2053
// - If we previously inferred this module from different module map file.
2054
bool Inferred = Existing->IsInferred;
2055
// - If we're building a framework that vends a module map, we might've
2056
// previously seen the one in intermediate products and now the system
2057
// one.
2058
// FIXME: If we're parsing module map file that looks like this:
2059
// framework module FW { ... }
2060
// module FW.Sub { ... }
2061
// We can't check the framework qualifier, since it's not attached to
2062
// the definition of Sub. Checking that qualifier on \c Existing is
2063
// not correct either, since we might've previously seen:
2064
// module FW { ... }
2065
// module FW.Sub { ... }
2066
// We should enforce consistency of redefinitions so that we can rely
2067
// that \c Existing is part of a framework iff the redefinition of FW
2068
// we have just skipped had it too. Once we do that, stop checking
2069
// the local framework qualifier and only rely on \c Existing.
2070
bool PartOfFramework = Framework || Existing->isPartOfFramework();
2071
// - If we're building a (preprocessed) module and we've just loaded the
2072
// module map file from which it was created.
2073
bool ParsedAsMainInput =
2074
Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
2075
Map.LangOpts.CurrentModule == ModuleName &&
2076
SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
2077
SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
2078
if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) {
2079
ActiveModule = PreviousActiveModule;
2080
// Skip the module definition.
2081
skipUntil(MMToken::RBrace);
2082
if (Tok.is(MMToken::RBrace))
2083
consumeToken();
2084
else {
2085
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2086
Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2087
HadError = true;
2088
}
2089
return;
2090
}
2091
2092
if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
2093
ShadowingModule = Existing;
2094
} else {
2095
// This is not a shawdowed module decl, it is an illegal redefinition.
2096
Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
2097
<< ModuleName;
2098
Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
2099
2100
// Skip the module definition.
2101
skipUntil(MMToken::RBrace);
2102
if (Tok.is(MMToken::RBrace))
2103
consumeToken();
2104
2105
HadError = true;
2106
return;
2107
}
2108
}
2109
2110
// Start defining this module.
2111
if (ShadowingModule) {
2112
ActiveModule =
2113
Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
2114
} else {
2115
ActiveModule =
2116
Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
2117
.first;
2118
}
2119
2120
ActiveModule->DefinitionLoc = ModuleNameLoc;
2121
if (Attrs.IsSystem || IsSystem)
2122
ActiveModule->IsSystem = true;
2123
if (Attrs.IsExternC)
2124
ActiveModule->IsExternC = true;
2125
if (Attrs.NoUndeclaredIncludes)
2126
ActiveModule->NoUndeclaredIncludes = true;
2127
ActiveModule->Directory = Directory;
2128
2129
StringRef MapFileName(
2130
SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());
2131
if (MapFileName.ends_with("module.private.modulemap") ||
2132
MapFileName.ends_with("module_private.map")) {
2133
ActiveModule->ModuleMapIsPrivate = true;
2134
}
2135
2136
// Private modules named as FooPrivate, Foo.Private or similar are likely a
2137
// user error; provide warnings, notes and fixits to direct users to use
2138
// Foo_Private instead.
2139
SourceLocation StartLoc =
2140
SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
2141
if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
2142
!Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
2143
StartLoc) &&
2144
!Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
2145
StartLoc) &&
2146
ActiveModule->ModuleMapIsPrivate)
2147
diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
2148
2149
bool Done = false;
2150
do {
2151
switch (Tok.Kind) {
2152
case MMToken::EndOfFile:
2153
case MMToken::RBrace:
2154
Done = true;
2155
break;
2156
2157
case MMToken::ConfigMacros:
2158
parseConfigMacros();
2159
break;
2160
2161
case MMToken::Conflict:
2162
parseConflict();
2163
break;
2164
2165
case MMToken::ExplicitKeyword:
2166
case MMToken::ExternKeyword:
2167
case MMToken::FrameworkKeyword:
2168
case MMToken::ModuleKeyword:
2169
parseModuleDecl();
2170
break;
2171
2172
case MMToken::ExportKeyword:
2173
parseExportDecl();
2174
break;
2175
2176
case MMToken::ExportAsKeyword:
2177
parseExportAsDecl();
2178
break;
2179
2180
case MMToken::UseKeyword:
2181
parseUseDecl();
2182
break;
2183
2184
case MMToken::RequiresKeyword:
2185
parseRequiresDecl();
2186
break;
2187
2188
case MMToken::TextualKeyword:
2189
parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
2190
break;
2191
2192
case MMToken::UmbrellaKeyword: {
2193
SourceLocation UmbrellaLoc = consumeToken();
2194
if (Tok.is(MMToken::HeaderKeyword))
2195
parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
2196
else
2197
parseUmbrellaDirDecl(UmbrellaLoc);
2198
break;
2199
}
2200
2201
case MMToken::ExcludeKeyword:
2202
parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
2203
break;
2204
2205
case MMToken::PrivateKeyword:
2206
parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
2207
break;
2208
2209
case MMToken::HeaderKeyword:
2210
parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
2211
break;
2212
2213
case MMToken::LinkKeyword:
2214
parseLinkDecl();
2215
break;
2216
2217
default:
2218
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
2219
consumeToken();
2220
break;
2221
}
2222
} while (!Done);
2223
2224
if (Tok.is(MMToken::RBrace))
2225
consumeToken();
2226
else {
2227
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2228
Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2229
HadError = true;
2230
}
2231
2232
// If the active module is a top-level framework, and there are no link
2233
// libraries, automatically link against the framework.
2234
if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
2235
ActiveModule->LinkLibraries.empty())
2236
inferFrameworkLink(ActiveModule);
2237
2238
// If the module meets all requirements but is still unavailable, mark the
2239
// whole tree as unavailable to prevent it from building.
2240
if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
2241
ActiveModule->Parent) {
2242
ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
2243
ActiveModule->getTopLevelModule()->MissingHeaders.append(
2244
ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
2245
}
2246
2247
// We're done parsing this module. Pop back to the previous module.
2248
ActiveModule = PreviousActiveModule;
2249
}
2250
2251
/// Parse an extern module declaration.
2252
///
2253
/// extern module-declaration:
2254
/// 'extern' 'module' module-id string-literal
2255
void ModuleMapParser::parseExternModuleDecl() {
2256
assert(Tok.is(MMToken::ExternKeyword));
2257
SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
2258
2259
// Parse 'module' keyword.
2260
if (!Tok.is(MMToken::ModuleKeyword)) {
2261
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2262
consumeToken();
2263
HadError = true;
2264
return;
2265
}
2266
consumeToken(); // 'module' keyword
2267
2268
// Parse the module name.
2269
ModuleId Id;
2270
if (parseModuleId(Id)) {
2271
HadError = true;
2272
return;
2273
}
2274
2275
// Parse the referenced module map file name.
2276
if (!Tok.is(MMToken::StringLiteral)) {
2277
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
2278
HadError = true;
2279
return;
2280
}
2281
std::string FileName = std::string(Tok.getString());
2282
consumeToken(); // filename
2283
2284
StringRef FileNameRef = FileName;
2285
SmallString<128> ModuleMapFileName;
2286
if (llvm::sys::path::is_relative(FileNameRef)) {
2287
ModuleMapFileName += Directory.getName();
2288
llvm::sys::path::append(ModuleMapFileName, FileName);
2289
FileNameRef = ModuleMapFileName;
2290
}
2291
if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))
2292
Map.parseModuleMapFile(
2293
*File, IsSystem,
2294
Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
2295
? Directory
2296
: File->getDir(),
2297
FileID(), nullptr, ExternLoc);
2298
}
2299
2300
/// Whether to add the requirement \p Feature to the module \p M.
2301
///
2302
/// This preserves backwards compatibility for two hacks in the Darwin system
2303
/// module map files:
2304
///
2305
/// 1. The use of 'requires excluded' to make headers non-modular, which
2306
/// should really be mapped to 'textual' now that we have this feature. We
2307
/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
2308
/// true. Later, this bit will be used to map all the headers inside this
2309
/// module to 'textual'.
2310
///
2311
/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
2312
///
2313
/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
2314
/// was never correct and causes issues now that we check it, so drop it.
2315
static bool shouldAddRequirement(Module *M, StringRef Feature,
2316
bool &IsRequiresExcludedHack) {
2317
if (Feature == "excluded" &&
2318
(M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
2319
M->fullModuleNameIs({"Tcl", "Private"}))) {
2320
IsRequiresExcludedHack = true;
2321
return false;
2322
} else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
2323
return false;
2324
}
2325
2326
return true;
2327
}
2328
2329
/// Parse a requires declaration.
2330
///
2331
/// requires-declaration:
2332
/// 'requires' feature-list
2333
///
2334
/// feature-list:
2335
/// feature ',' feature-list
2336
/// feature
2337
///
2338
/// feature:
2339
/// '!'[opt] identifier
2340
void ModuleMapParser::parseRequiresDecl() {
2341
assert(Tok.is(MMToken::RequiresKeyword));
2342
2343
// Parse 'requires' keyword.
2344
consumeToken();
2345
2346
// Parse the feature-list.
2347
do {
2348
bool RequiredState = true;
2349
if (Tok.is(MMToken::Exclaim)) {
2350
RequiredState = false;
2351
consumeToken();
2352
}
2353
2354
if (!Tok.is(MMToken::Identifier)) {
2355
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
2356
HadError = true;
2357
return;
2358
}
2359
2360
// Consume the feature name.
2361
std::string Feature = std::string(Tok.getString());
2362
consumeToken();
2363
2364
bool IsRequiresExcludedHack = false;
2365
bool ShouldAddRequirement =
2366
shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
2367
2368
if (IsRequiresExcludedHack)
2369
UsesRequiresExcludedHack.insert(ActiveModule);
2370
2371
if (ShouldAddRequirement) {
2372
// Add this feature.
2373
ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
2374
*Map.Target);
2375
}
2376
2377
if (!Tok.is(MMToken::Comma))
2378
break;
2379
2380
// Consume the comma.
2381
consumeToken();
2382
} while (true);
2383
}
2384
2385
/// Parse a header declaration.
2386
///
2387
/// header-declaration:
2388
/// 'textual'[opt] 'header' string-literal
2389
/// 'private' 'textual'[opt] 'header' string-literal
2390
/// 'exclude' 'header' string-literal
2391
/// 'umbrella' 'header' string-literal
2392
///
2393
/// FIXME: Support 'private textual header'.
2394
void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
2395
SourceLocation LeadingLoc) {
2396
// We've already consumed the first token.
2397
ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
2398
2399
if (LeadingToken == MMToken::PrivateKeyword) {
2400
Role = ModuleMap::PrivateHeader;
2401
// 'private' may optionally be followed by 'textual'.
2402
if (Tok.is(MMToken::TextualKeyword)) {
2403
LeadingToken = Tok.Kind;
2404
consumeToken();
2405
}
2406
} else if (LeadingToken == MMToken::ExcludeKeyword) {
2407
Role = ModuleMap::ExcludedHeader;
2408
}
2409
2410
if (LeadingToken == MMToken::TextualKeyword)
2411
Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
2412
2413
if (UsesRequiresExcludedHack.count(ActiveModule)) {
2414
// Mark this header 'textual' (see doc comment for
2415
// Module::UsesRequiresExcludedHack).
2416
Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
2417
}
2418
2419
if (LeadingToken != MMToken::HeaderKeyword) {
2420
if (!Tok.is(MMToken::HeaderKeyword)) {
2421
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2422
<< (LeadingToken == MMToken::PrivateKeyword ? "private" :
2423
LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
2424
LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
2425
return;
2426
}
2427
consumeToken();
2428
}
2429
2430
// Parse the header name.
2431
if (!Tok.is(MMToken::StringLiteral)) {
2432
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2433
<< "header";
2434
HadError = true;
2435
return;
2436
}
2437
Module::UnresolvedHeaderDirective Header;
2438
Header.FileName = std::string(Tok.getString());
2439
Header.FileNameLoc = consumeToken();
2440
Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
2441
Header.Kind = Map.headerRoleToKind(Role);
2442
2443
// Check whether we already have an umbrella.
2444
if (Header.IsUmbrella &&
2445
!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
2446
Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
2447
<< ActiveModule->getFullModuleName();
2448
HadError = true;
2449
return;
2450
}
2451
2452
// If we were given stat information, parse it so we can skip looking for
2453
// the file.
2454
if (Tok.is(MMToken::LBrace)) {
2455
SourceLocation LBraceLoc = consumeToken();
2456
2457
while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) {
2458
enum Attribute { Size, ModTime, Unknown };
2459
StringRef Str = Tok.getString();
2460
SourceLocation Loc = consumeToken();
2461
switch (llvm::StringSwitch<Attribute>(Str)
2462
.Case("size", Size)
2463
.Case("mtime", ModTime)
2464
.Default(Unknown)) {
2465
case Size:
2466
if (Header.Size)
2467
Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2468
if (!Tok.is(MMToken::IntegerLiteral)) {
2469
Diags.Report(Tok.getLocation(),
2470
diag::err_mmap_invalid_header_attribute_value) << Str;
2471
skipUntil(MMToken::RBrace);
2472
break;
2473
}
2474
Header.Size = Tok.getInteger();
2475
consumeToken();
2476
break;
2477
2478
case ModTime:
2479
if (Header.ModTime)
2480
Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2481
if (!Tok.is(MMToken::IntegerLiteral)) {
2482
Diags.Report(Tok.getLocation(),
2483
diag::err_mmap_invalid_header_attribute_value) << Str;
2484
skipUntil(MMToken::RBrace);
2485
break;
2486
}
2487
Header.ModTime = Tok.getInteger();
2488
consumeToken();
2489
break;
2490
2491
case Unknown:
2492
Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
2493
skipUntil(MMToken::RBrace);
2494
break;
2495
}
2496
}
2497
2498
if (Tok.is(MMToken::RBrace))
2499
consumeToken();
2500
else {
2501
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2502
Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2503
HadError = true;
2504
}
2505
}
2506
2507
bool NeedsFramework = false;
2508
// Don't add headers to the builtin modules if the builtin headers belong to
2509
// the system modules, with the exception of __stddef_max_align_t.h which
2510
// always had its own module.
2511
if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
2512
!isBuiltInModuleName(ActiveModule->getTopLevelModuleName()) ||
2513
ActiveModule->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}))
2514
Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2515
2516
if (NeedsFramework)
2517
Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2518
<< ActiveModule->getFullModuleName()
2519
<< FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module");
2520
}
2521
2522
static bool compareModuleHeaders(const Module::Header &A,
2523
const Module::Header &B) {
2524
return A.NameAsWritten < B.NameAsWritten;
2525
}
2526
2527
/// Parse an umbrella directory declaration.
2528
///
2529
/// umbrella-dir-declaration:
2530
/// umbrella string-literal
2531
void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
2532
// Parse the directory name.
2533
if (!Tok.is(MMToken::StringLiteral)) {
2534
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2535
<< "umbrella";
2536
HadError = true;
2537
return;
2538
}
2539
2540
std::string DirName = std::string(Tok.getString());
2541
std::string DirNameAsWritten = DirName;
2542
SourceLocation DirNameLoc = consumeToken();
2543
2544
// Check whether we already have an umbrella.
2545
if (!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
2546
Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2547
<< ActiveModule->getFullModuleName();
2548
HadError = true;
2549
return;
2550
}
2551
2552
// Look for this file.
2553
OptionalDirectoryEntryRef Dir;
2554
if (llvm::sys::path::is_absolute(DirName)) {
2555
Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
2556
} else {
2557
SmallString<128> PathName;
2558
PathName = Directory.getName();
2559
llvm::sys::path::append(PathName, DirName);
2560
Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName);
2561
}
2562
2563
if (!Dir) {
2564
Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2565
<< DirName;
2566
return;
2567
}
2568
2569
if (UsesRequiresExcludedHack.count(ActiveModule)) {
2570
// Mark this header 'textual' (see doc comment for
2571
// ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
2572
// directory is relatively expensive, in practice this only applies to the
2573
// uncommonly used Tcl module on Darwin platforms.
2574
std::error_code EC;
2575
SmallVector<Module::Header, 6> Headers;
2576
llvm::vfs::FileSystem &FS =
2577
SourceMgr.getFileManager().getVirtualFileSystem();
2578
for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
2579
I != E && !EC; I.increment(EC)) {
2580
if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) {
2581
Module::Header Header = {"", std::string(I->path()), *FE};
2582
Headers.push_back(std::move(Header));
2583
}
2584
}
2585
2586
// Sort header paths so that the pcm doesn't depend on iteration order.
2587
std::stable_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
2588
2589
for (auto &Header : Headers)
2590
Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
2591
return;
2592
}
2593
2594
if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2595
Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2596
<< OwningModule->getFullModuleName();
2597
HadError = true;
2598
return;
2599
}
2600
2601
// Record this umbrella directory.
2602
Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName);
2603
}
2604
2605
/// Parse a module export declaration.
2606
///
2607
/// export-declaration:
2608
/// 'export' wildcard-module-id
2609
///
2610
/// wildcard-module-id:
2611
/// identifier
2612
/// '*'
2613
/// identifier '.' wildcard-module-id
2614
void ModuleMapParser::parseExportDecl() {
2615
assert(Tok.is(MMToken::ExportKeyword));
2616
SourceLocation ExportLoc = consumeToken();
2617
2618
// Parse the module-id with an optional wildcard at the end.
2619
ModuleId ParsedModuleId;
2620
bool Wildcard = false;
2621
do {
2622
// FIXME: Support string-literal module names here.
2623
if (Tok.is(MMToken::Identifier)) {
2624
ParsedModuleId.push_back(
2625
std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
2626
consumeToken();
2627
2628
if (Tok.is(MMToken::Period)) {
2629
consumeToken();
2630
continue;
2631
}
2632
2633
break;
2634
}
2635
2636
if(Tok.is(MMToken::Star)) {
2637
Wildcard = true;
2638
consumeToken();
2639
break;
2640
}
2641
2642
Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
2643
HadError = true;
2644
return;
2645
} while (true);
2646
2647
Module::UnresolvedExportDecl Unresolved = {
2648
ExportLoc, ParsedModuleId, Wildcard
2649
};
2650
ActiveModule->UnresolvedExports.push_back(Unresolved);
2651
}
2652
2653
/// Parse a module export_as declaration.
2654
///
2655
/// export-as-declaration:
2656
/// 'export_as' identifier
2657
void ModuleMapParser::parseExportAsDecl() {
2658
assert(Tok.is(MMToken::ExportAsKeyword));
2659
consumeToken();
2660
2661
if (!Tok.is(MMToken::Identifier)) {
2662
Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
2663
HadError = true;
2664
return;
2665
}
2666
2667
if (ActiveModule->Parent) {
2668
Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);
2669
consumeToken();
2670
return;
2671
}
2672
2673
if (!ActiveModule->ExportAsModule.empty()) {
2674
if (ActiveModule->ExportAsModule == Tok.getString()) {
2675
Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as)
2676
<< ActiveModule->Name << Tok.getString();
2677
} else {
2678
Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as)
2679
<< ActiveModule->Name << ActiveModule->ExportAsModule
2680
<< Tok.getString();
2681
}
2682
}
2683
2684
ActiveModule->ExportAsModule = std::string(Tok.getString());
2685
Map.addLinkAsDependency(ActiveModule);
2686
2687
consumeToken();
2688
}
2689
2690
/// Parse a module use declaration.
2691
///
2692
/// use-declaration:
2693
/// 'use' wildcard-module-id
2694
void ModuleMapParser::parseUseDecl() {
2695
assert(Tok.is(MMToken::UseKeyword));
2696
auto KWLoc = consumeToken();
2697
// Parse the module-id.
2698
ModuleId ParsedModuleId;
2699
parseModuleId(ParsedModuleId);
2700
2701
if (ActiveModule->Parent)
2702
Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2703
else
2704
ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
2705
}
2706
2707
/// Parse a link declaration.
2708
///
2709
/// module-declaration:
2710
/// 'link' 'framework'[opt] string-literal
2711
void ModuleMapParser::parseLinkDecl() {
2712
assert(Tok.is(MMToken::LinkKeyword));
2713
SourceLocation LinkLoc = consumeToken();
2714
2715
// Parse the optional 'framework' keyword.
2716
bool IsFramework = false;
2717
if (Tok.is(MMToken::FrameworkKeyword)) {
2718
consumeToken();
2719
IsFramework = true;
2720
}
2721
2722
// Parse the library name
2723
if (!Tok.is(MMToken::StringLiteral)) {
2724
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2725
<< IsFramework << SourceRange(LinkLoc);
2726
HadError = true;
2727
return;
2728
}
2729
2730
std::string LibraryName = std::string(Tok.getString());
2731
consumeToken();
2732
ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2733
IsFramework));
2734
}
2735
2736
/// Parse a configuration macro declaration.
2737
///
2738
/// module-declaration:
2739
/// 'config_macros' attributes[opt] config-macro-list?
2740
///
2741
/// config-macro-list:
2742
/// identifier (',' identifier)?
2743
void ModuleMapParser::parseConfigMacros() {
2744
assert(Tok.is(MMToken::ConfigMacros));
2745
SourceLocation ConfigMacrosLoc = consumeToken();
2746
2747
// Only top-level modules can have configuration macros.
2748
if (ActiveModule->Parent) {
2749
Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2750
}
2751
2752
// Parse the optional attributes.
2753
Attributes Attrs;
2754
if (parseOptionalAttributes(Attrs))
2755
return;
2756
2757
if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2758
ActiveModule->ConfigMacrosExhaustive = true;
2759
}
2760
2761
// If we don't have an identifier, we're done.
2762
// FIXME: Support macros with the same name as a keyword here.
2763
if (!Tok.is(MMToken::Identifier))
2764
return;
2765
2766
// Consume the first identifier.
2767
if (!ActiveModule->Parent) {
2768
ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2769
}
2770
consumeToken();
2771
2772
do {
2773
// If there's a comma, consume it.
2774
if (!Tok.is(MMToken::Comma))
2775
break;
2776
consumeToken();
2777
2778
// We expect to see a macro name here.
2779
// FIXME: Support macros with the same name as a keyword here.
2780
if (!Tok.is(MMToken::Identifier)) {
2781
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2782
break;
2783
}
2784
2785
// Consume the macro name.
2786
if (!ActiveModule->Parent) {
2787
ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2788
}
2789
consumeToken();
2790
} while (true);
2791
}
2792
2793
/// Format a module-id into a string.
2794
static std::string formatModuleId(const ModuleId &Id) {
2795
std::string result;
2796
{
2797
llvm::raw_string_ostream OS(result);
2798
2799
for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2800
if (I)
2801
OS << ".";
2802
OS << Id[I].first;
2803
}
2804
}
2805
2806
return result;
2807
}
2808
2809
/// Parse a conflict declaration.
2810
///
2811
/// module-declaration:
2812
/// 'conflict' module-id ',' string-literal
2813
void ModuleMapParser::parseConflict() {
2814
assert(Tok.is(MMToken::Conflict));
2815
SourceLocation ConflictLoc = consumeToken();
2816
Module::UnresolvedConflict Conflict;
2817
2818
// Parse the module-id.
2819
if (parseModuleId(Conflict.Id))
2820
return;
2821
2822
// Parse the ','.
2823
if (!Tok.is(MMToken::Comma)) {
2824
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2825
<< SourceRange(ConflictLoc);
2826
return;
2827
}
2828
consumeToken();
2829
2830
// Parse the message.
2831
if (!Tok.is(MMToken::StringLiteral)) {
2832
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2833
<< formatModuleId(Conflict.Id);
2834
return;
2835
}
2836
Conflict.Message = Tok.getString().str();
2837
consumeToken();
2838
2839
// Add this unresolved conflict.
2840
ActiveModule->UnresolvedConflicts.push_back(Conflict);
2841
}
2842
2843
/// Parse an inferred module declaration (wildcard modules).
2844
///
2845
/// module-declaration:
2846
/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2847
/// { inferred-module-member* }
2848
///
2849
/// inferred-module-member:
2850
/// 'export' '*'
2851
/// 'exclude' identifier
2852
void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
2853
assert(Tok.is(MMToken::Star));
2854
SourceLocation StarLoc = consumeToken();
2855
bool Failed = false;
2856
2857
// Inferred modules must be submodules.
2858
if (!ActiveModule && !Framework) {
2859
Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2860
Failed = true;
2861
}
2862
2863
if (ActiveModule) {
2864
// Inferred modules must have umbrella directories.
2865
if (!Failed && ActiveModule->IsAvailable &&
2866
!ActiveModule->getEffectiveUmbrellaDir()) {
2867
Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2868
Failed = true;
2869
}
2870
2871
// Check for redefinition of an inferred module.
2872
if (!Failed && ActiveModule->InferSubmodules) {
2873
Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2874
if (ActiveModule->InferredSubmoduleLoc.isValid())
2875
Diags.Report(ActiveModule->InferredSubmoduleLoc,
2876
diag::note_mmap_prev_definition);
2877
Failed = true;
2878
}
2879
2880
// Check for the 'framework' keyword, which is not permitted here.
2881
if (Framework) {
2882
Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2883
Framework = false;
2884
}
2885
} else if (Explicit) {
2886
Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2887
Explicit = false;
2888
}
2889
2890
// If there were any problems with this inferred submodule, skip its body.
2891
if (Failed) {
2892
if (Tok.is(MMToken::LBrace)) {
2893
consumeToken();
2894
skipUntil(MMToken::RBrace);
2895
if (Tok.is(MMToken::RBrace))
2896
consumeToken();
2897
}
2898
HadError = true;
2899
return;
2900
}
2901
2902
// Parse optional attributes.
2903
Attributes Attrs;
2904
if (parseOptionalAttributes(Attrs))
2905
return;
2906
2907
if (ActiveModule) {
2908
// Note that we have an inferred submodule.
2909
ActiveModule->InferSubmodules = true;
2910
ActiveModule->InferredSubmoduleLoc = StarLoc;
2911
ActiveModule->InferExplicitSubmodules = Explicit;
2912
} else {
2913
// We'll be inferring framework modules for this directory.
2914
Map.InferredDirectories[Directory].InferModules = true;
2915
Map.InferredDirectories[Directory].Attrs = Attrs;
2916
Map.InferredDirectories[Directory].ModuleMapFID = ModuleMapFID;
2917
// FIXME: Handle the 'framework' keyword.
2918
}
2919
2920
// Parse the opening brace.
2921
if (!Tok.is(MMToken::LBrace)) {
2922
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2923
HadError = true;
2924
return;
2925
}
2926
SourceLocation LBraceLoc = consumeToken();
2927
2928
// Parse the body of the inferred submodule.
2929
bool Done = false;
2930
do {
2931
switch (Tok.Kind) {
2932
case MMToken::EndOfFile:
2933
case MMToken::RBrace:
2934
Done = true;
2935
break;
2936
2937
case MMToken::ExcludeKeyword:
2938
if (ActiveModule) {
2939
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2940
<< (ActiveModule != nullptr);
2941
consumeToken();
2942
break;
2943
}
2944
2945
consumeToken();
2946
// FIXME: Support string-literal module names here.
2947
if (!Tok.is(MMToken::Identifier)) {
2948
Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2949
break;
2950
}
2951
2952
Map.InferredDirectories[Directory].ExcludedModules.push_back(
2953
std::string(Tok.getString()));
2954
consumeToken();
2955
break;
2956
2957
case MMToken::ExportKeyword:
2958
if (!ActiveModule) {
2959
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2960
<< (ActiveModule != nullptr);
2961
consumeToken();
2962
break;
2963
}
2964
2965
consumeToken();
2966
if (Tok.is(MMToken::Star))
2967
ActiveModule->InferExportWildcard = true;
2968
else
2969
Diags.Report(Tok.getLocation(),
2970
diag::err_mmap_expected_export_wildcard);
2971
consumeToken();
2972
break;
2973
2974
case MMToken::ExplicitKeyword:
2975
case MMToken::ModuleKeyword:
2976
case MMToken::HeaderKeyword:
2977
case MMToken::PrivateKeyword:
2978
case MMToken::UmbrellaKeyword:
2979
default:
2980
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2981
<< (ActiveModule != nullptr);
2982
consumeToken();
2983
break;
2984
}
2985
} while (!Done);
2986
2987
if (Tok.is(MMToken::RBrace))
2988
consumeToken();
2989
else {
2990
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2991
Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2992
HadError = true;
2993
}
2994
}
2995
2996
/// Parse optional attributes.
2997
///
2998
/// attributes:
2999
/// attribute attributes
3000
/// attribute
3001
///
3002
/// attribute:
3003
/// [ identifier ]
3004
///
3005
/// \param Attrs Will be filled in with the parsed attributes.
3006
///
3007
/// \returns true if an error occurred, false otherwise.
3008
bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
3009
bool HadError = false;
3010
3011
while (Tok.is(MMToken::LSquare)) {
3012
// Consume the '['.
3013
SourceLocation LSquareLoc = consumeToken();
3014
3015
// Check whether we have an attribute name here.
3016
if (!Tok.is(MMToken::Identifier)) {
3017
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
3018
skipUntil(MMToken::RSquare);
3019
if (Tok.is(MMToken::RSquare))
3020
consumeToken();
3021
HadError = true;
3022
}
3023
3024
// Decode the attribute name.
3025
AttributeKind Attribute
3026
= llvm::StringSwitch<AttributeKind>(Tok.getString())
3027
.Case("exhaustive", AT_exhaustive)
3028
.Case("extern_c", AT_extern_c)
3029
.Case("no_undeclared_includes", AT_no_undeclared_includes)
3030
.Case("system", AT_system)
3031
.Default(AT_unknown);
3032
switch (Attribute) {
3033
case AT_unknown:
3034
Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
3035
<< Tok.getString();
3036
break;
3037
3038
case AT_system:
3039
Attrs.IsSystem = true;
3040
break;
3041
3042
case AT_extern_c:
3043
Attrs.IsExternC = true;
3044
break;
3045
3046
case AT_exhaustive:
3047
Attrs.IsExhaustive = true;
3048
break;
3049
3050
case AT_no_undeclared_includes:
3051
Attrs.NoUndeclaredIncludes = true;
3052
break;
3053
}
3054
consumeToken();
3055
3056
// Consume the ']'.
3057
if (!Tok.is(MMToken::RSquare)) {
3058
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
3059
Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
3060
skipUntil(MMToken::RSquare);
3061
HadError = true;
3062
}
3063
3064
if (Tok.is(MMToken::RSquare))
3065
consumeToken();
3066
}
3067
3068
return HadError;
3069
}
3070
3071
/// Parse a module map file.
3072
///
3073
/// module-map-file:
3074
/// module-declaration*
3075
bool ModuleMapParser::parseModuleMapFile() {
3076
do {
3077
switch (Tok.Kind) {
3078
case MMToken::EndOfFile:
3079
return HadError;
3080
3081
case MMToken::ExplicitKeyword:
3082
case MMToken::ExternKeyword:
3083
case MMToken::ModuleKeyword:
3084
case MMToken::FrameworkKeyword:
3085
parseModuleDecl();
3086
break;
3087
3088
case MMToken::Comma:
3089
case MMToken::ConfigMacros:
3090
case MMToken::Conflict:
3091
case MMToken::Exclaim:
3092
case MMToken::ExcludeKeyword:
3093
case MMToken::ExportKeyword:
3094
case MMToken::ExportAsKeyword:
3095
case MMToken::HeaderKeyword:
3096
case MMToken::Identifier:
3097
case MMToken::LBrace:
3098
case MMToken::LinkKeyword:
3099
case MMToken::LSquare:
3100
case MMToken::Period:
3101
case MMToken::PrivateKeyword:
3102
case MMToken::RBrace:
3103
case MMToken::RSquare:
3104
case MMToken::RequiresKeyword:
3105
case MMToken::Star:
3106
case MMToken::StringLiteral:
3107
case MMToken::IntegerLiteral:
3108
case MMToken::TextualKeyword:
3109
case MMToken::UmbrellaKeyword:
3110
case MMToken::UseKeyword:
3111
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
3112
HadError = true;
3113
consumeToken();
3114
break;
3115
}
3116
} while (true);
3117
}
3118
3119
bool ModuleMap::parseModuleMapFile(FileEntryRef File, bool IsSystem,
3120
DirectoryEntryRef Dir, FileID ID,
3121
unsigned *Offset,
3122
SourceLocation ExternModuleLoc) {
3123
assert(Target && "Missing target information");
3124
llvm::DenseMap<const FileEntry *, bool>::iterator Known
3125
= ParsedModuleMap.find(File);
3126
if (Known != ParsedModuleMap.end())
3127
return Known->second;
3128
3129
// If the module map file wasn't already entered, do so now.
3130
if (ID.isInvalid()) {
3131
auto FileCharacter =
3132
IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
3133
ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
3134
}
3135
3136
assert(Target && "Missing target information");
3137
std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
3138
if (!Buffer)
3139
return ParsedModuleMap[File] = true;
3140
assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
3141
"invalid buffer offset");
3142
3143
// Parse this module map file.
3144
Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
3145
Buffer->getBufferStart(),
3146
Buffer->getBufferStart() + (Offset ? *Offset : 0),
3147
Buffer->getBufferEnd());
3148
SourceLocation Start = L.getSourceLocation();
3149
ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, ID, Dir, IsSystem);
3150
bool Result = Parser.parseModuleMapFile();
3151
ParsedModuleMap[File] = Result;
3152
3153
if (Offset) {
3154
auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation());
3155
assert(Loc.first == ID && "stopped in a different file?");
3156
*Offset = Loc.second;
3157
}
3158
3159
// Notify callbacks that we parsed it.
3160
for (const auto &Cb : Callbacks)
3161
Cb->moduleMapFileRead(Start, File, IsSystem);
3162
3163
return Result;
3164
}
3165
3166