Coverage Report

Created: 2024-01-17 10:31

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