Bug Summary

File:build/source/clang/lib/Lex/ModuleMap.cpp
Warning:line 497, column 9
Value stored to 'Excluded' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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