Bug Summary

File:build/source/clang/lib/Lex/ModuleMap.cpp
Warning:line 2847, column 7
Value stored to 'Framework' 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/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-17/lib/clang/17 -D CLANG_REPOSITORY_STRING="++20230510111145+7df43bdb42ae-1~exp1~20230510111303.1288" -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/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/source/= -source-date-epoch 1683717183 -O2 -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/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -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-05-10-133810-16478-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;
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, bool AllowCreation) {
687 HeadersMap::iterator Known = findKnownHeader(File);
688 if (Known != Headers.end())
689 return Known->second;
690
691 if (AllowCreation && 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::createModuleUnitWithKind(SourceLocation Loc, StringRef Name,
892 Module::ModuleKind Kind) {
893 auto *Result =
894 new Module(Name, Loc, nullptr, /*IsFramework*/ false,
895 /*IsExplicit*/ false, NumCreatedModules++);
896 Result->Kind = Kind;
897
898 // Reparent any current global module fragment as a submodule of this module.
899 for (auto &Submodule : PendingSubmodules) {
900 Submodule->setParent(Result);
901 Submodule.release(); // now owned by parent
902 }
903 PendingSubmodules.clear();
904 return Result;
905}
906
907Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
908 StringRef Name) {
909 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", 909, __extension__ __PRETTY_FUNCTION__
))
;
910 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", 910, __extension__ __PRETTY_FUNCTION__
))
;
911
912 auto *Result =
913 createModuleUnitWithKind(Loc, Name, Module::ModuleInterfaceUnit);
914 Modules[Name] = SourceModule = Result;
915
916 // Mark the main source file as being within the newly-created module so that
917 // declarations and macros are properly visibility-restricted to it.
918 auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
919 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", 919, __extension__ __PRETTY_FUNCTION__
))
;
920 Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
921
922 return Result;
923}
924
925Module *ModuleMap::createModuleForImplementationUnit(SourceLocation Loc,
926 StringRef Name) {
927 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", 927, __extension__ __PRETTY_FUNCTION__
))
;
928 // The interface for this implementation must exist and be loaded.
929 assert(Modules[Name] && Modules[Name]->Kind == Module::ModuleInterfaceUnit &&(static_cast <bool> (Modules[Name] && Modules[Name
]->Kind == Module::ModuleInterfaceUnit && "creating implementation module without an interface"
) ? void (0) : __assert_fail ("Modules[Name] && Modules[Name]->Kind == Module::ModuleInterfaceUnit && \"creating implementation module without an interface\""
, "clang/lib/Lex/ModuleMap.cpp", 930, __extension__ __PRETTY_FUNCTION__
))
930 "creating implementation module without an interface")(static_cast <bool> (Modules[Name] && Modules[Name
]->Kind == Module::ModuleInterfaceUnit && "creating implementation module without an interface"
) ? void (0) : __assert_fail ("Modules[Name] && Modules[Name]->Kind == Module::ModuleInterfaceUnit && \"creating implementation module without an interface\""
, "clang/lib/Lex/ModuleMap.cpp", 930, __extension__ __PRETTY_FUNCTION__
))
;
931
932 // Create an entry in the modules map to own the implementation unit module.
933 // User module names must not start with a period (so that this cannot clash
934 // with any legal user-defined module name).
935 StringRef IName = ".ImplementationUnit";
936 assert(!Modules[IName] && "multiple implementation units?")(static_cast <bool> (!Modules[IName] && "multiple implementation units?"
) ? void (0) : __assert_fail ("!Modules[IName] && \"multiple implementation units?\""
, "clang/lib/Lex/ModuleMap.cpp", 936, __extension__ __PRETTY_FUNCTION__
))
;
937
938 auto *Result =
939 createModuleUnitWithKind(Loc, Name, Module::ModuleImplementationUnit);
940 Modules[IName] = SourceModule = Result;
941
942 // Check that the main file is present.
943 assert(SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) &&(static_cast <bool> (SourceMgr.getFileEntryForID(SourceMgr
.getMainFileID()) && "no input file for module implementation"
) ? void (0) : __assert_fail ("SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) && \"no input file for module implementation\""
, "clang/lib/Lex/ModuleMap.cpp", 944, __extension__ __PRETTY_FUNCTION__
))
944 "no input file for module implementation")(static_cast <bool> (SourceMgr.getFileEntryForID(SourceMgr
.getMainFileID()) && "no input file for module implementation"
) ? void (0) : __assert_fail ("SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) && \"no input file for module implementation\""
, "clang/lib/Lex/ModuleMap.cpp", 944, __extension__ __PRETTY_FUNCTION__
))
;
945
946 return Result;
947}
948
949Module *ModuleMap::createHeaderUnit(SourceLocation Loc, StringRef Name,
950 Module::Header H) {
951 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", 951, __extension__ __PRETTY_FUNCTION__
))
;
952 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", 952, __extension__ __PRETTY_FUNCTION__
))
;
953
954 auto *Result = new Module(Name, Loc, nullptr, /*IsFramework*/ false,
955 /*IsExplicit*/ false, NumCreatedModules++);
956 Result->Kind = Module::ModuleHeaderUnit;
957 Modules[Name] = SourceModule = Result;
958 addHeader(Result, H, NormalHeader);
959 return Result;
960}
961
962/// For a framework module, infer the framework against which we
963/// should link.
964static void inferFrameworkLink(Module *Mod) {
965 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", 965, __extension__ __PRETTY_FUNCTION__
))
;
966 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", 967, __extension__ __PRETTY_FUNCTION__
))
967 "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", 967, __extension__ __PRETTY_FUNCTION__
))
;
968
969 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
970 /*IsFramework=*/true));
971}
972
973Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
974 bool IsSystem, Module *Parent) {
975 Attributes Attrs;
976 Attrs.IsSystem = IsSystem;
977 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
978}
979
980Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
981 Attributes Attrs, Module *Parent) {
982 // Note: as an egregious but useful hack we use the real path here, because
983 // we might be looking at an embedded framework that symlinks out to a
984 // top-level framework, and we need to infer as if we were naming the
985 // top-level framework.
986 StringRef FrameworkDirName =
987 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
988
989 // In case this is a case-insensitive filesystem, use the canonical
990 // directory name as the ModuleName, since modules are case-sensitive.
991 // FIXME: we should be able to give a fix-it hint for the correct spelling.
992 SmallString<32> ModuleNameStorage;
993 StringRef ModuleName = sanitizeFilenameAsIdentifier(
994 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
995
996 // Check whether we've already found this module.
997 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
998 return Mod;
999
1000 FileManager &FileMgr = SourceMgr.getFileManager();
1001
1002 // If the framework has a parent path from which we're allowed to infer
1003 // a framework module, do so.
1004 const FileEntry *ModuleMapFile = nullptr;
1005 if (!Parent) {
1006 // Determine whether we're allowed to infer a module map.
1007 bool canInfer = false;
1008 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1009 // Figure out the parent path.
1010 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
1011 if (auto ParentDir = FileMgr.getDirectory(Parent)) {
1012 // Check whether we have already looked into the parent directory
1013 // for a module map.
1014 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1015 inferred = InferredDirectories.find(*ParentDir);
1016 if (inferred == InferredDirectories.end()) {
1017 // We haven't looked here before. Load a module map, if there is
1018 // one.
1019 bool IsFrameworkDir = Parent.endswith(".framework");
1020 if (const FileEntry *ModMapFile =
1021 HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
1022 parseModuleMapFile(ModMapFile, Attrs.IsSystem, *ParentDir);
1023 inferred = InferredDirectories.find(*ParentDir);
1024 }
1025
1026 if (inferred == InferredDirectories.end())
1027 inferred = InferredDirectories.insert(
1028 std::make_pair(*ParentDir, InferredDirectory())).first;
1029 }
1030
1031 if (inferred->second.InferModules) {
1032 // We're allowed to infer for this directory, but make sure it's okay
1033 // to infer this particular module.
1034 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1035 canInfer =
1036 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1037
1038 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1039 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1040 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1041 Attrs.NoUndeclaredIncludes |=
1042 inferred->second.Attrs.NoUndeclaredIncludes;
1043 ModuleMapFile = inferred->second.ModuleMapFile;
1044 }
1045 }
1046 }
1047
1048 // If we're not allowed to infer a framework module, don't.
1049 if (!canInfer)
1050 return nullptr;
1051 } else {
1052 OptionalFileEntryRefDegradesToFileEntryPtr ModuleMapRef =
1053 getModuleMapFileForUniquing(Parent);
1054 ModuleMapFile = ModuleMapRef;
1055 }
1056
1057 // Look for an umbrella header.
1058 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
1059 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
1060 auto UmbrellaHeader = FileMgr.getOptionalFileRef(UmbrellaName);
1061
1062 // FIXME: If there's no umbrella header, we could probably scan the
1063 // framework to load *everything*. But, it's not clear that this is a good
1064 // idea.
1065 if (!UmbrellaHeader)
1066 return nullptr;
1067
1068 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
1069 /*IsFramework=*/true, /*IsExplicit=*/false,
1070 NumCreatedModules++);
1071 InferredModuleAllowedBy[Result] = ModuleMapFile;
1072 Result->IsInferred = true;
1073 if (!Parent) {
1074 if (LangOpts.CurrentModule == ModuleName)
1075 SourceModule = Result;
1076 Modules[ModuleName] = Result;
1077 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1078 }
1079
1080 Result->IsSystem |= Attrs.IsSystem;
1081 Result->IsExternC |= Attrs.IsExternC;
1082 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1083 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1084 Result->Directory = FrameworkDir;
1085
1086 // Chop off the first framework bit, as that is implied.
1087 StringRef RelativePath = UmbrellaName.str().substr(
1088 Result->getTopLevelModule()->Directory->getName().size());
1089 RelativePath = llvm::sys::path::relative_path(RelativePath);
1090
1091 // umbrella header "umbrella-header-name"
1092 setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h", RelativePath);
1093
1094 // export *
1095 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
1096
1097 // module * { export * }
1098 Result->InferSubmodules = true;
1099 Result->InferExportWildcard = true;
1100
1101 // Look for subframeworks.
1102 std::error_code EC;
1103 SmallString<128> SubframeworksDirName
1104 = StringRef(FrameworkDir->getName());
1105 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
1106 llvm::sys::path::native(SubframeworksDirName);
1107 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1108 for (llvm::vfs::directory_iterator
1109 Dir = FS.dir_begin(SubframeworksDirName, EC),
1110 DirEnd;
1111 Dir != DirEnd && !EC; Dir.increment(EC)) {
1112 if (!StringRef(Dir->path()).endswith(".framework"))
1113 continue;
1114
1115 if (auto SubframeworkDir =
1116 FileMgr.getDirectory(Dir->path())) {
1117 // Note: as an egregious but useful hack, we use the real path here and
1118 // check whether it is actually a subdirectory of the parent directory.
1119 // This will not be the case if the 'subframework' is actually a symlink
1120 // out to a top-level framework.
1121 StringRef SubframeworkDirName =
1122 FileMgr.getCanonicalName(*SubframeworkDir);
1123 bool FoundParent = false;
1124 do {
1125 // Get the parent directory name.
1126 SubframeworkDirName
1127 = llvm::sys::path::parent_path(SubframeworkDirName);
1128 if (SubframeworkDirName.empty())
1129 break;
1130
1131 if (auto SubDir = FileMgr.getDirectory(SubframeworkDirName)) {
1132 if (*SubDir == FrameworkDir) {
1133 FoundParent = true;
1134 break;
1135 }
1136 }
1137 } while (true);
1138
1139 if (!FoundParent)
1140 continue;
1141
1142 // FIXME: Do we want to warn about subframeworks without umbrella headers?
1143 inferFrameworkModule(*SubframeworkDir, Attrs, Result);
1144 }
1145 }
1146
1147 // If the module is a top-level framework, automatically link against the
1148 // framework.
1149 if (!Result->isSubFramework())
1150 inferFrameworkLink(Result);
1151
1152 return Result;
1153}
1154
1155Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
1156 Module *ShadowingModule) {
1157
1158 // Create a new module with this name.
1159 Module *Result =
1160 new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework,
1161 /*IsExplicit=*/false, NumCreatedModules++);
1162 Result->ShadowingModule = ShadowingModule;
1163 Result->markUnavailable(/*Unimportable*/true);
1164 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1165 ShadowModules.push_back(Result);
1166
1167 return Result;
1168}
1169
1170void ModuleMap::setUmbrellaHeader(
1171 Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,
1172 const Twine &PathRelativeToRootModuleDirectory) {
1173 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
1174 Mod->Umbrella = &UmbrellaHeader.getMapEntry();
1175 Mod->UmbrellaAsWritten = NameAsWritten.str();
1176 Mod->UmbrellaRelativeToRootModuleDirectory =
1177 PathRelativeToRootModuleDirectory.str();
1178 UmbrellaDirs[UmbrellaHeader.getDir()] = Mod;
1179
1180 // Notify callbacks that we just added a new header.
1181 for (const auto &Cb : Callbacks)
1182 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
1183}
1184
1185void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
1186 const Twine &NameAsWritten,
1187 const Twine &PathRelativeToRootModuleDirectory) {
1188 Mod->Umbrella = UmbrellaDir;
1189 Mod->UmbrellaAsWritten = NameAsWritten.str();
1190 Mod->UmbrellaRelativeToRootModuleDirectory =
1191 PathRelativeToRootModuleDirectory.str();
1192 UmbrellaDirs[UmbrellaDir] = Mod;
1193}
1194
1195void ModuleMap::addUnresolvedHeader(Module *Mod,
1196 Module::UnresolvedHeaderDirective Header,
1197 bool &NeedsFramework) {
1198 // If there is a builtin counterpart to this file, add it now so it can
1199 // wrap the system header.
1200 if (resolveAsBuiltinHeader(Mod, Header)) {
1201 // If we have both a builtin and system version of the file, the
1202 // builtin version may want to inject macros into the system header, so
1203 // force the system header to be treated as a textual header in this
1204 // case.
1205 Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole(
1206 headerKindToRole(Header.Kind) | ModuleMap::TextualHeader));
1207 Header.HasBuiltinHeader = true;
1208 }
1209
1210 // If possible, don't stat the header until we need to. This requires the
1211 // user to have provided us with some stat information about the file.
1212 // FIXME: Add support for lazily stat'ing umbrella headers and excluded
1213 // headers.
1214 if ((Header.Size || Header.ModTime) && !Header.IsUmbrella &&
1215 Header.Kind != Module::HK_Excluded) {
1216 // We expect more variation in mtime than size, so if we're given both,
1217 // use the mtime as the key.
1218 if (Header.ModTime)
1219 LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
1220 else
1221 LazyHeadersBySize[*Header.Size].push_back(Mod);
1222 Mod->UnresolvedHeaders.push_back(Header);
1223 return;
1224 }
1225
1226 // We don't have stat information or can't defer looking this file up.
1227 // Perform the lookup now.
1228 resolveHeader(Mod, Header, NeedsFramework);
1229}
1230
1231void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const {
1232 auto BySize = LazyHeadersBySize.find(File->getSize());
1233 if (BySize != LazyHeadersBySize.end()) {
1234 for (auto *M : BySize->second)
1235 resolveHeaderDirectives(M, File);
1236 LazyHeadersBySize.erase(BySize);
1237 }
1238
1239 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
1240 if (ByModTime != LazyHeadersByModTime.end()) {
1241 for (auto *M : ByModTime->second)
1242 resolveHeaderDirectives(M, File);
1243 LazyHeadersByModTime.erase(ByModTime);
1244 }
1245}
1246
1247void ModuleMap::resolveHeaderDirectives(
1248 Module *Mod, std::optional<const FileEntry *> File) const {
1249 bool NeedsFramework = false;
1250 SmallVector<Module::UnresolvedHeaderDirective, 1> NewHeaders;
1251 const auto Size = File ? (*File)->getSize() : 0;
1252 const auto ModTime = File ? (*File)->getModificationTime() : 0;
1253
1254 for (auto &Header : Mod->UnresolvedHeaders) {
1255 if (File && ((Header.ModTime && Header.ModTime != ModTime) ||
1256 (Header.Size && Header.Size != Size)))
1257 NewHeaders.push_back(Header);
1258 else
1259 // This operation is logically const; we're just changing how we represent
1260 // the header information for this file.
1261 const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework);
1262 }
1263 Mod->UnresolvedHeaders.swap(NewHeaders);
1264}
1265
1266void ModuleMap::addHeader(Module *Mod, Module::Header Header,
1267 ModuleHeaderRole Role, bool Imported) {
1268 KnownHeader KH(Mod, Role);
1269
1270 // Only add each header to the headers list once.
1271 // FIXME: Should we diagnose if a header is listed twice in the
1272 // same module definition?
1273 auto &HeaderList = Headers[Header.Entry];
1274 if (llvm::is_contained(HeaderList, KH))
1275 return;
1276
1277 HeaderList.push_back(KH);
1278 Mod->Headers[headerRoleToKind(Role)].push_back(Header);
1279
1280 bool isCompilingModuleHeader =
1281 LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
1282 if (!Imported || isCompilingModuleHeader) {
1283 // When we import HeaderFileInfo, the external source is expected to
1284 // set the isModuleHeader flag itself.
1285 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
1286 isCompilingModuleHeader);
1287 }
1288
1289 // Notify callbacks that we just added a new header.
1290 for (const auto &Cb : Callbacks)
1291 Cb->moduleMapAddHeader(Header.Entry->getName());
1292}
1293
1294OptionalFileEntryRef
1295ModuleMap::getContainingModuleMapFile(const Module *Module) const {
1296 if (Module->DefinitionLoc.isInvalid())
1297 return std::nullopt;
1298
1299 return SourceMgr.getFileEntryRefForID(
1300 SourceMgr.getFileID(Module->DefinitionLoc));
1301}
1302
1303OptionalFileEntryRef
1304ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
1305 if (M->IsInferred) {
1306 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", 1306, __extension__ __PRETTY_FUNCTION__
))
;
1307 // FIXME: Update InferredModuleAllowedBy to use FileEntryRef.
1308 return InferredModuleAllowedBy.find(M)->second->getLastRef();
1309 }
1310 return getContainingModuleMapFile(M);
1311}
1312
1313void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
1314 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", 1314, __extension__ __PRETTY_FUNCTION__
))
;
1315 InferredModuleAllowedBy[M] = ModMap;
1316}
1317
1318std::error_code
1319ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl<char> &Path) {
1320 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
1321
1322 // Do not canonicalize within the framework; the module map parser expects
1323 // Modules/ not Versions/A/Modules.
1324 if (llvm::sys::path::filename(Dir) == "Modules") {
1325 StringRef Parent = llvm::sys::path::parent_path(Dir);
1326 if (Parent.endswith(".framework"))
1327 Dir = Parent;
1328 }
1329
1330 FileManager &FM = SourceMgr.getFileManager();
1331 auto DirEntry = FM.getDirectory(Dir.empty() ? "." : Dir);
1332 if (!DirEntry)
1333 return DirEntry.getError();
1334
1335 // Canonicalize the directory.
1336 StringRef CanonicalDir = FM.getCanonicalName(*DirEntry);
1337 if (CanonicalDir != Dir) {
1338 auto CanonicalDirEntry = FM.getDirectory(CanonicalDir);
1339 // Only use the canonicalized path if it resolves to the same entry as the
1340 // original. This is not true if there's a VFS overlay on top of a FS where
1341 // the directory is a symlink. The overlay would not remap the target path
1342 // of the symlink to the same directory entry in that case.
1343 if (CanonicalDirEntry && *CanonicalDirEntry == *DirEntry) {
1344 bool Done = llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
1345 (void)Done;
1346 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", 1346, __extension__ __PRETTY_FUNCTION__
))
;
1347 }
1348 }
1349
1350 // In theory, the filename component should also be canonicalized if it
1351 // on a case-insensitive filesystem. However, the extra canonicalization is
1352 // expensive and if clang looked up the filename it will always be lowercase.
1353
1354 // Remove ., remove redundant separators, and switch to native separators.
1355 // This is needed for separators between CanonicalDir and the filename.
1356 llvm::sys::path::remove_dots(Path);
1357
1358 return std::error_code();
1359}
1360
1361void ModuleMap::addAdditionalModuleMapFile(const Module *M,
1362 const FileEntry *ModuleMap) {
1363 AdditionalModMaps[M].insert(ModuleMap);
1364}
1365
1366LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void ModuleMap::dump() {
1367 llvm::errs() << "Modules:";
1368 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1369 MEnd = Modules.end();
1370 M != MEnd; ++M)
1371 M->getValue()->print(llvm::errs(), 2);
1372
1373 llvm::errs() << "Headers:";
1374 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1375 H != HEnd; ++H) {
1376 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
1377 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
1378 E = H->second.end();
1379 I != E; ++I) {
1380 if (I != H->second.begin())
1381 llvm::errs() << ",";
1382 llvm::errs() << I->getModule()->getFullModuleName();
1383 }
1384 llvm::errs() << "\n";
1385 }
1386}
1387
1388bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
1389 auto Unresolved = std::move(Mod->UnresolvedExports);
1390 Mod->UnresolvedExports.clear();
1391 for (auto &UE : Unresolved) {
1392 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
1393 if (Export.getPointer() || Export.getInt())
1394 Mod->Exports.push_back(Export);
1395 else
1396 Mod->UnresolvedExports.push_back(UE);
1397 }
1398 return !Mod->UnresolvedExports.empty();
1399}
1400
1401bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
1402 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
1403 Mod->UnresolvedDirectUses.clear();
1404 for (auto &UDU : Unresolved) {
1405 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
1406 if (DirectUse)
1407 Mod->DirectUses.push_back(DirectUse);
1408 else
1409 Mod->UnresolvedDirectUses.push_back(UDU);
1410 }
1411 return !Mod->UnresolvedDirectUses.empty();
1412}
1413
1414bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
1415 auto Unresolved = std::move(Mod->UnresolvedConflicts);
1416 Mod->UnresolvedConflicts.clear();
1417 for (auto &UC : Unresolved) {
1418 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1419 Module::Conflict Conflict;
1420 Conflict.Other = OtherMod;
1421 Conflict.Message = UC.Message;
1422 Mod->Conflicts.push_back(Conflict);
1423 } else
1424 Mod->UnresolvedConflicts.push_back(UC);
1425 }
1426 return !Mod->UnresolvedConflicts.empty();
1427}
1428
1429//----------------------------------------------------------------------------//
1430// Module map file parser
1431//----------------------------------------------------------------------------//
1432
1433namespace clang {
1434
1435 /// A token in a module map file.
1436 struct MMToken {
1437 enum TokenKind {
1438 Comma,
1439 ConfigMacros,
1440 Conflict,
1441 EndOfFile,
1442 HeaderKeyword,
1443 Identifier,
1444 Exclaim,
1445 ExcludeKeyword,
1446 ExplicitKeyword,
1447 ExportKeyword,
1448 ExportAsKeyword,
1449 ExternKeyword,
1450 FrameworkKeyword,
1451 LinkKeyword,
1452 ModuleKeyword,
1453 Period,
1454 PrivateKeyword,
1455 UmbrellaKeyword,
1456 UseKeyword,
1457 RequiresKeyword,
1458 Star,
1459 StringLiteral,
1460 IntegerLiteral,
1461 TextualKeyword,
1462 LBrace,
1463 RBrace,
1464 LSquare,
1465 RSquare
1466 } Kind;
1467
1468 SourceLocation::UIntTy Location;
1469 unsigned StringLength;
1470 union {
1471 // If Kind != IntegerLiteral.
1472 const char *StringData;
1473
1474 // If Kind == IntegerLiteral.
1475 uint64_t IntegerValue;
1476 };
1477
1478 void clear() {
1479 Kind = EndOfFile;
1480 Location = 0;
1481 StringLength = 0;
1482 StringData = nullptr;
1483 }
1484
1485 bool is(TokenKind K) const { return Kind == K; }
1486
1487 SourceLocation getLocation() const {
1488 return SourceLocation::getFromRawEncoding(Location);
1489 }
1490
1491 uint64_t getInteger() const {
1492 return Kind == IntegerLiteral ? IntegerValue : 0;
1493 }
1494
1495 StringRef getString() const {
1496 return Kind == IntegerLiteral ? StringRef()
1497 : StringRef(StringData, StringLength);
1498 }
1499 };
1500
1501 class ModuleMapParser {
1502 Lexer &L;
1503 SourceManager &SourceMgr;
1504
1505 /// Default target information, used only for string literal
1506 /// parsing.
1507 const TargetInfo *Target;
1508
1509 DiagnosticsEngine &Diags;
1510 ModuleMap &Map;
1511
1512 /// The current module map file.
1513 const FileEntry *ModuleMapFile;
1514
1515 /// Source location of most recent parsed module declaration
1516 SourceLocation CurrModuleDeclLoc;
1517
1518 /// The directory that file names in this module map file should
1519 /// be resolved relative to.
1520 const DirectoryEntry *Directory;
1521
1522 /// Whether this module map is in a system header directory.
1523 bool IsSystem;
1524
1525 /// Whether an error occurred.
1526 bool HadError = false;
1527
1528 /// Stores string data for the various string literals referenced
1529 /// during parsing.
1530 llvm::BumpPtrAllocator StringData;
1531
1532 /// The current token.
1533 MMToken Tok;
1534
1535 /// The active module.
1536 Module *ActiveModule = nullptr;
1537
1538 /// Whether a module uses the 'requires excluded' hack to mark its
1539 /// contents as 'textual'.
1540 ///
1541 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1542 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1543 /// non-modular headers. For backwards compatibility, we continue to
1544 /// support this idiom for just these modules, and map the headers to
1545 /// 'textual' to match the original intent.
1546 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1547
1548 /// Consume the current token and return its location.
1549 SourceLocation consumeToken();
1550
1551 /// Skip tokens until we reach the a token with the given kind
1552 /// (or the end of the file).
1553 void skipUntil(MMToken::TokenKind K);
1554
1555 using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>;
1556
1557 bool parseModuleId(ModuleId &Id);
1558 void parseModuleDecl();
1559 void parseExternModuleDecl();
1560 void parseRequiresDecl();
1561 void parseHeaderDecl(MMToken::TokenKind, SourceLocation LeadingLoc);
1562 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
1563 void parseExportDecl();
1564 void parseExportAsDecl();
1565 void parseUseDecl();
1566 void parseLinkDecl();
1567 void parseConfigMacros();
1568 void parseConflict();
1569 void parseInferredModuleDecl(bool Framework, bool Explicit);
1570
1571 /// Private modules are canonicalized as Foo_Private. Clang provides extra
1572 /// module map search logic to find the appropriate private module when PCH
1573 /// is used with implicit module maps. Warn when private modules are written
1574 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1575 void diagnosePrivateModules(SourceLocation ExplicitLoc,
1576 SourceLocation FrameworkLoc);
1577
1578 using Attributes = ModuleMap::Attributes;
1579
1580 bool parseOptionalAttributes(Attributes &Attrs);
1581
1582 public:
1583 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
1584 const TargetInfo *Target, DiagnosticsEngine &Diags,
1585 ModuleMap &Map, const FileEntry *ModuleMapFile,
1586 const DirectoryEntry *Directory, bool IsSystem)
1587 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1588 ModuleMapFile(ModuleMapFile), Directory(Directory),
1589 IsSystem(IsSystem) {
1590 Tok.clear();
1591 consumeToken();
1592 }
1593
1594 bool parseModuleMapFile();
1595
1596 bool terminatedByDirective() { return false; }
1597 SourceLocation getLocation() { return Tok.getLocation(); }
1598 };
1599
1600} // namespace clang
1601
1602SourceLocation ModuleMapParser::consumeToken() {
1603 SourceLocation Result = Tok.getLocation();
1604
1605retry:
1606 Tok.clear();
1607 Token LToken;
1608 L.LexFromRawLexer(LToken);
1609 Tok.Location = LToken.getLocation().getRawEncoding();
1610 switch (LToken.getKind()) {
1611 case tok::raw_identifier: {
1612 StringRef RI = LToken.getRawIdentifier();
1613 Tok.StringData = RI.data();
1614 Tok.StringLength = RI.size();
1615 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1616 .Case("config_macros", MMToken::ConfigMacros)
1617 .Case("conflict", MMToken::Conflict)
1618 .Case("exclude", MMToken::ExcludeKeyword)
1619 .Case("explicit", MMToken::ExplicitKeyword)
1620 .Case("export", MMToken::ExportKeyword)
1621 .Case("export_as", MMToken::ExportAsKeyword)
1622 .Case("extern", MMToken::ExternKeyword)
1623 .Case("framework", MMToken::FrameworkKeyword)
1624 .Case("header", MMToken::HeaderKeyword)
1625 .Case("link", MMToken::LinkKeyword)
1626 .Case("module", MMToken::ModuleKeyword)
1627 .Case("private", MMToken::PrivateKeyword)
1628 .Case("requires", MMToken::RequiresKeyword)
1629 .Case("textual", MMToken::TextualKeyword)
1630 .Case("umbrella", MMToken::UmbrellaKeyword)
1631 .Case("use", MMToken::UseKeyword)
1632 .Default(MMToken::Identifier);
1633 break;
1634 }
1635
1636 case tok::comma:
1637 Tok.Kind = MMToken::Comma;
1638 break;
1639
1640 case tok::eof:
1641 Tok.Kind = MMToken::EndOfFile;
1642 break;
1643
1644 case tok::l_brace:
1645 Tok.Kind = MMToken::LBrace;
1646 break;
1647
1648 case tok::l_square:
1649 Tok.Kind = MMToken::LSquare;
1650 break;
1651
1652 case tok::period:
1653 Tok.Kind = MMToken::Period;
1654 break;
1655
1656 case tok::r_brace:
1657 Tok.Kind = MMToken::RBrace;
1658 break;
1659
1660 case tok::r_square:
1661 Tok.Kind = MMToken::RSquare;
1662 break;
1663
1664 case tok::star:
1665 Tok.Kind = MMToken::Star;
1666 break;
1667
1668 case tok::exclaim:
1669 Tok.Kind = MMToken::Exclaim;
1670 break;
1671
1672 case tok::string_literal: {
1673 if (LToken.hasUDSuffix()) {
1674 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1675 HadError = true;
1676 goto retry;
1677 }
1678
1679 // Parse the string literal.
1680 LangOptions LangOpts;
1681 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
1682 if (StringLiteral.hadError)
1683 goto retry;
1684
1685 // Copy the string literal into our string data allocator.
1686 unsigned Length = StringLiteral.GetStringLength();
1687 char *Saved = StringData.Allocate<char>(Length + 1);
1688 memcpy(Saved, StringLiteral.GetString().data(), Length);
1689 Saved[Length] = 0;
1690
1691 // Form the token.
1692 Tok.Kind = MMToken::StringLiteral;
1693 Tok.StringData = Saved;
1694 Tok.StringLength = Length;
1695 break;
1696 }
1697
1698 case tok::numeric_constant: {
1699 // We don't support any suffixes or other complications.
1700 SmallString<32> SpellingBuffer;
1701 SpellingBuffer.resize(LToken.getLength() + 1);
1702 const char *Start = SpellingBuffer.data();
1703 unsigned Length =
1704 Lexer::getSpelling(LToken, Start, SourceMgr, Map.LangOpts);
1705 uint64_t Value;
1706 if (StringRef(Start, Length).getAsInteger(0, Value)) {
1707 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
1708 HadError = true;
1709 goto retry;
1710 }
1711
1712 Tok.Kind = MMToken::IntegerLiteral;
1713 Tok.IntegerValue = Value;
1714 break;
1715 }
1716
1717 case tok::comment:
1718 goto retry;
1719
1720 case tok::hash:
1721 // A module map can be terminated prematurely by
1722 // #pragma clang module contents
1723 // When building the module, we'll treat the rest of the file as the
1724 // contents of the module.
1725 {
1726 auto NextIsIdent = [&](StringRef Str) -> bool {
1727 L.LexFromRawLexer(LToken);
1728 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
1729 LToken.getRawIdentifier() == Str;
1730 };
1731 if (NextIsIdent("pragma") && NextIsIdent("clang") &&
1732 NextIsIdent("module") && NextIsIdent("contents")) {
1733 Tok.Kind = MMToken::EndOfFile;
1734 break;
1735 }
1736 }
1737 [[fallthrough]];
1738
1739 default:
1740 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
1741 HadError = true;
1742 goto retry;
1743 }
1744
1745 return Result;
1746}
1747
1748void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1749 unsigned braceDepth = 0;
1750 unsigned squareDepth = 0;
1751 do {
1752 switch (Tok.Kind) {
1753 case MMToken::EndOfFile:
1754 return;
1755
1756 case MMToken::LBrace:
1757 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1758 return;
1759
1760 ++braceDepth;
1761 break;
1762
1763 case MMToken::LSquare:
1764 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1765 return;
1766
1767 ++squareDepth;
1768 break;
1769
1770 case MMToken::RBrace:
1771 if (braceDepth > 0)
1772 --braceDepth;
1773 else if (Tok.is(K))
1774 return;
1775 break;
1776
1777 case MMToken::RSquare:
1778 if (squareDepth > 0)
1779 --squareDepth;
1780 else if (Tok.is(K))
1781 return;
1782 break;
1783
1784 default:
1785 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1786 return;
1787 break;
1788 }
1789
1790 consumeToken();
1791 } while (true);
1792}
1793
1794/// Parse a module-id.
1795///
1796/// module-id:
1797/// identifier
1798/// identifier '.' module-id
1799///
1800/// \returns true if an error occurred, false otherwise.
1801bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1802 Id.clear();
1803 do {
1804 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
1805 Id.push_back(
1806 std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
1807 consumeToken();
1808 } else {
1809 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1810 return true;
1811 }
1812
1813 if (!Tok.is(MMToken::Period))
1814 break;
1815
1816 consumeToken();
1817 } while (true);
1818
1819 return false;
1820}
1821
1822namespace {
1823
1824 /// Enumerates the known attributes.
1825 enum AttributeKind {
1826 /// An unknown attribute.
1827 AT_unknown,
1828
1829 /// The 'system' attribute.
1830 AT_system,
1831
1832 /// The 'extern_c' attribute.
1833 AT_extern_c,
1834
1835 /// The 'exhaustive' attribute.
1836 AT_exhaustive,
1837
1838 /// The 'no_undeclared_includes' attribute.
1839 AT_no_undeclared_includes
1840 };
1841
1842} // namespace
1843
1844/// Private modules are canonicalized as Foo_Private. Clang provides extra
1845/// module map search logic to find the appropriate private module when PCH
1846/// is used with implicit module maps. Warn when private modules are written
1847/// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1848void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc,
1849 SourceLocation FrameworkLoc) {
1850 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1851 const Module *M, SourceRange ReplLoc) {
1852 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1853 diag::note_mmap_rename_top_level_private_module);
1854 D << BadName << M->Name;
1855 D << FixItHint::CreateReplacement(ReplLoc, Canonical);
1856 };
1857
1858 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1859 auto const *M = E->getValue();
1860 if (M->Directory != ActiveModule->Directory)
1861 continue;
1862
1863 SmallString<128> FullName(ActiveModule->getFullModuleName());
1864 if (!FullName.startswith(M->Name) && !FullName.endswith("Private"))
1865 continue;
1866 SmallString<128> FixedPrivModDecl;
1867 SmallString<128> Canonical(M->Name);
1868 Canonical.append("_Private");
1869
1870 // Foo.Private -> Foo_Private
1871 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
1872 M->Name == ActiveModule->Parent->Name) {
1873 Diags.Report(ActiveModule->DefinitionLoc,
1874 diag::warn_mmap_mismatched_private_submodule)
1875 << FullName;
1876
1877 SourceLocation FixItInitBegin = CurrModuleDeclLoc;
1878 if (FrameworkLoc.isValid())
1879 FixItInitBegin = FrameworkLoc;
1880 if (ExplicitLoc.isValid())
1881 FixItInitBegin = ExplicitLoc;
1882
1883 if (FrameworkLoc.isValid() || ActiveModule->Parent->IsFramework)
1884 FixedPrivModDecl.append("framework ");
1885 FixedPrivModDecl.append("module ");
1886 FixedPrivModDecl.append(Canonical);
1887
1888 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1889 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1890 continue;
1891 }
1892
1893 // FooPrivate and whatnots -> Foo_Private
1894 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1895 ActiveModule->Name != Canonical) {
1896 Diags.Report(ActiveModule->DefinitionLoc,
1897 diag::warn_mmap_mismatched_private_module_name)
1898 << ActiveModule->Name;
1899 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1900 SourceRange(ActiveModule->DefinitionLoc));
1901 }
1902 }
1903}
1904
1905/// Parse a module declaration.
1906///
1907/// module-declaration:
1908/// 'extern' 'module' module-id string-literal
1909/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1910/// { module-member* }
1911///
1912/// module-member:
1913/// requires-declaration
1914/// header-declaration
1915/// submodule-declaration
1916/// export-declaration
1917/// export-as-declaration
1918/// link-declaration
1919///
1920/// submodule-declaration:
1921/// module-declaration
1922/// inferred-submodule-declaration
1923void ModuleMapParser::parseModuleDecl() {
1924 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", 1925, __extension__ __PRETTY_FUNCTION__
))
1925 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", 1925, __extension__ __PRETTY_FUNCTION__
))
;
1926 if (Tok.is(MMToken::ExternKeyword)) {
1927 parseExternModuleDecl();
1928 return;
1929 }
1930
1931 // Parse 'explicit' or 'framework' keyword, if present.
1932 SourceLocation ExplicitLoc;
1933 SourceLocation FrameworkLoc;
1934 bool Explicit = false;
1935 bool Framework = false;
1936
1937 // Parse 'explicit' keyword, if present.
1938 if (Tok.is(MMToken::ExplicitKeyword)) {
1939 ExplicitLoc = consumeToken();
1940 Explicit = true;
1941 }
1942
1943 // Parse 'framework' keyword, if present.
1944 if (Tok.is(MMToken::FrameworkKeyword)) {
1945 FrameworkLoc = consumeToken();
1946 Framework = true;
1947 }
1948
1949 // Parse 'module' keyword.
1950 if (!Tok.is(MMToken::ModuleKeyword)) {
1951 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1952 consumeToken();
1953 HadError = true;
1954 return;
1955 }
1956 CurrModuleDeclLoc = consumeToken(); // 'module' keyword
1957
1958 // If we have a wildcard for the module name, this is an inferred submodule.
1959 // Parse it.
1960 if (Tok.is(MMToken::Star))
1961 return parseInferredModuleDecl(Framework, Explicit);
1962
1963 // Parse the module name.
1964 ModuleId Id;
1965 if (parseModuleId(Id)) {
1966 HadError = true;
1967 return;
1968 }
1969
1970 if (ActiveModule) {
1971 if (Id.size() > 1) {
1972 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1973 << SourceRange(Id.front().second, Id.back().second);
1974
1975 HadError = true;
1976 return;
1977 }
1978 } else if (Id.size() == 1 && Explicit) {
1979 // Top-level modules can't be explicit.
1980 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1981 Explicit = false;
1982 ExplicitLoc = SourceLocation();
1983 HadError = true;
1984 }
1985
1986 Module *PreviousActiveModule = ActiveModule;
1987 if (Id.size() > 1) {
1988 // This module map defines a submodule. Go find the module of which it
1989 // is a submodule.
1990 ActiveModule = nullptr;
1991 const Module *TopLevelModule = nullptr;
1992 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1993 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1994 if (I == 0)
1995 TopLevelModule = Next;
1996 ActiveModule = Next;
1997 continue;
1998 }
1999
2000 Diags.Report(Id[I].second, diag::err_mmap_missing_parent_module)
2001 << Id[I].first << (ActiveModule != nullptr)
2002 << (ActiveModule
2003 ? ActiveModule->getTopLevelModule()->getFullModuleName()
2004 : "");
2005 HadError = true;
2006 }
2007
2008 if (TopLevelModule &&
2009 ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
2010 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", 2012, __extension__ __PRETTY_FUNCTION__
))
2011 "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", 2012, __extension__ __PRETTY_FUNCTION__
))
2012 "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", 2012, __extension__ __PRETTY_FUNCTION__
))
;
2013 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
2014 }
2015 }
2016
2017 StringRef ModuleName = Id.back().first;
2018 SourceLocation ModuleNameLoc = Id.back().second;
2019
2020 // Parse the optional attribute list.
2021 Attributes Attrs;
2022 if (parseOptionalAttributes(Attrs))
2023 return;
2024
2025 // Parse the opening brace.
2026 if (!Tok.is(MMToken::LBrace)) {
2027 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
2028 << ModuleName;
2029 HadError = true;
2030 return;
2031 }
2032 SourceLocation LBraceLoc = consumeToken();
2033
2034 // Determine whether this (sub)module has already been defined.
2035 Module *ShadowingModule = nullptr;
2036 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
2037 // We might see a (re)definition of a module that we already have a
2038 // definition for in two cases:
2039 // - If we loaded one definition from an AST file and we've just found a
2040 // corresponding definition in a module map file, or
2041 bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid();
2042 // - If we're building a (preprocessed) module and we've just loaded the
2043 // module map file from which it was created.
2044 bool ParsedAsMainInput =
2045 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
2046 Map.LangOpts.CurrentModule == ModuleName &&
2047 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
2048 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
2049 if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
2050 // Skip the module definition.
2051 skipUntil(MMToken::RBrace);
2052 if (Tok.is(MMToken::RBrace))
2053 consumeToken();
2054 else {
2055 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2056 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2057 HadError = true;
2058 }
2059 return;
2060 }
2061
2062 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
2063 ShadowingModule = Existing;
2064 } else {
2065 // This is not a shawdowed module decl, it is an illegal redefinition.
2066 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
2067 << ModuleName;
2068 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
2069
2070 // Skip the module definition.
2071 skipUntil(MMToken::RBrace);
2072 if (Tok.is(MMToken::RBrace))
2073 consumeToken();
2074
2075 HadError = true;
2076 return;
2077 }
2078 }
2079
2080 // Start defining this module.
2081 if (ShadowingModule) {
2082 ActiveModule =
2083 Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
2084 } else {
2085 ActiveModule =
2086 Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
2087 .first;
2088 }
2089
2090 ActiveModule->DefinitionLoc = ModuleNameLoc;
2091 if (Attrs.IsSystem || IsSystem)
2092 ActiveModule->IsSystem = true;
2093 if (Attrs.IsExternC)
2094 ActiveModule->IsExternC = true;
2095 if (Attrs.NoUndeclaredIncludes)
2096 ActiveModule->NoUndeclaredIncludes = true;
2097 ActiveModule->Directory = Directory;
2098
2099 StringRef MapFileName(ModuleMapFile->getName());
2100 if (MapFileName.endswith("module.private.modulemap") ||
2101 MapFileName.endswith("module_private.map")) {
2102 ActiveModule->ModuleMapIsPrivate = true;
2103 }
2104
2105 // Private modules named as FooPrivate, Foo.Private or similar are likely a
2106 // user error; provide warnings, notes and fixits to direct users to use
2107 // Foo_Private instead.
2108 SourceLocation StartLoc =
2109 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
2110 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
2111 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
2112 StartLoc) &&
2113 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
2114 StartLoc) &&
2115 ActiveModule->ModuleMapIsPrivate)
2116 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
2117
2118 bool Done = false;
2119 do {
2120 switch (Tok.Kind) {
2121 case MMToken::EndOfFile:
2122 case MMToken::RBrace:
2123 Done = true;
2124 break;
2125
2126 case MMToken::ConfigMacros:
2127 parseConfigMacros();
2128 break;
2129
2130 case MMToken::Conflict:
2131 parseConflict();
2132 break;
2133
2134 case MMToken::ExplicitKeyword:
2135 case MMToken::ExternKeyword:
2136 case MMToken::FrameworkKeyword:
2137 case MMToken::ModuleKeyword:
2138 parseModuleDecl();
2139 break;
2140
2141 case MMToken::ExportKeyword:
2142 parseExportDecl();
2143 break;
2144
2145 case MMToken::ExportAsKeyword:
2146 parseExportAsDecl();
2147 break;
2148
2149 case MMToken::UseKeyword:
2150 parseUseDecl();
2151 break;
2152
2153 case MMToken::RequiresKeyword:
2154 parseRequiresDecl();
2155 break;
2156
2157 case MMToken::TextualKeyword:
2158 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
2159 break;
2160
2161 case MMToken::UmbrellaKeyword: {
2162 SourceLocation UmbrellaLoc = consumeToken();
2163 if (Tok.is(MMToken::HeaderKeyword))
2164 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
2165 else
2166 parseUmbrellaDirDecl(UmbrellaLoc);
2167 break;
2168 }
2169
2170 case MMToken::ExcludeKeyword:
2171 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
2172 break;
2173
2174 case MMToken::PrivateKeyword:
2175 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
2176 break;
2177
2178 case MMToken::HeaderKeyword:
2179 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
2180 break;
2181
2182 case MMToken::LinkKeyword:
2183 parseLinkDecl();
2184 break;
2185
2186 default:
2187 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
2188 consumeToken();
2189 break;
2190 }
2191 } while (!Done);
2192
2193 if (Tok.is(MMToken::RBrace))
2194 consumeToken();
2195 else {
2196 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2197 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2198 HadError = true;
2199 }
2200
2201 // If the active module is a top-level framework, and there are no link
2202 // libraries, automatically link against the framework.
2203 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
2204 ActiveModule->LinkLibraries.empty())
2205 inferFrameworkLink(ActiveModule);
2206
2207 // If the module meets all requirements but is still unavailable, mark the
2208 // whole tree as unavailable to prevent it from building.
2209 if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
2210 ActiveModule->Parent) {
2211 ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
2212 ActiveModule->getTopLevelModule()->MissingHeaders.append(
2213 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
2214 }
2215
2216 // We're done parsing this module. Pop back to the previous module.
2217 ActiveModule = PreviousActiveModule;
2218}
2219
2220/// Parse an extern module declaration.
2221///
2222/// extern module-declaration:
2223/// 'extern' 'module' module-id string-literal
2224void ModuleMapParser::parseExternModuleDecl() {
2225 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"
, 2225, __extension__ __PRETTY_FUNCTION__))
;
2226 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
2227
2228 // Parse 'module' keyword.
2229 if (!Tok.is(MMToken::ModuleKeyword)) {
2230 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2231 consumeToken();
2232 HadError = true;
2233 return;
2234 }
2235 consumeToken(); // 'module' keyword
2236
2237 // Parse the module name.
2238 ModuleId Id;
2239 if (parseModuleId(Id)) {
2240 HadError = true;
2241 return;
2242 }
2243
2244 // Parse the referenced module map file name.
2245 if (!Tok.is(MMToken::StringLiteral)) {
2246 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
2247 HadError = true;
2248 return;
2249 }
2250 std::string FileName = std::string(Tok.getString());
2251 consumeToken(); // filename
2252
2253 StringRef FileNameRef = FileName;
2254 SmallString<128> ModuleMapFileName;
2255 if (llvm::sys::path::is_relative(FileNameRef)) {
2256 ModuleMapFileName += Directory->getName();
2257 llvm::sys::path::append(ModuleMapFileName, FileName);
2258 FileNameRef = ModuleMapFileName;
2259 }
2260 if (auto File = SourceMgr.getFileManager().getFile(FileNameRef))
2261 Map.parseModuleMapFile(
2262 *File, IsSystem,
2263 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
2264 ? Directory
2265 : (*File)->getDir(),
2266 FileID(), nullptr, ExternLoc);
2267}
2268
2269/// Whether to add the requirement \p Feature to the module \p M.
2270///
2271/// This preserves backwards compatibility for two hacks in the Darwin system
2272/// module map files:
2273///
2274/// 1. The use of 'requires excluded' to make headers non-modular, which
2275/// should really be mapped to 'textual' now that we have this feature. We
2276/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
2277/// true. Later, this bit will be used to map all the headers inside this
2278/// module to 'textual'.
2279///
2280/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
2281///
2282/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
2283/// was never correct and causes issues now that we check it, so drop it.
2284static bool shouldAddRequirement(Module *M, StringRef Feature,
2285 bool &IsRequiresExcludedHack) {
2286 if (Feature == "excluded" &&
2287 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
2288 M->fullModuleNameIs({"Tcl", "Private"}))) {
2289 IsRequiresExcludedHack = true;
2290 return false;
2291 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
2292 return false;
2293 }
2294
2295 return true;
2296}
2297
2298/// Parse a requires declaration.
2299///
2300/// requires-declaration:
2301/// 'requires' feature-list
2302///
2303/// feature-list:
2304/// feature ',' feature-list
2305/// feature
2306///
2307/// feature:
2308/// '!'[opt] identifier
2309void ModuleMapParser::parseRequiresDecl() {
2310 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", 2310, __extension__ __PRETTY_FUNCTION__
))
;
2311
2312 // Parse 'requires' keyword.
2313 consumeToken();
2314
2315 // Parse the feature-list.
2316 do {
2317 bool RequiredState = true;
2318 if (Tok.is(MMToken::Exclaim)) {
2319 RequiredState = false;
2320 consumeToken();
2321 }
2322
2323 if (!Tok.is(MMToken::Identifier)) {
2324 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
2325 HadError = true;
2326 return;
2327 }
2328
2329 // Consume the feature name.
2330 std::string Feature = std::string(Tok.getString());
2331 consumeToken();
2332
2333 bool IsRequiresExcludedHack = false;
2334 bool ShouldAddRequirement =
2335 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
2336
2337 if (IsRequiresExcludedHack)
2338 UsesRequiresExcludedHack.insert(ActiveModule);
2339
2340 if (ShouldAddRequirement) {
2341 // Add this feature.
2342 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
2343 *Map.Target);
2344 }
2345
2346 if (!Tok.is(MMToken::Comma))
2347 break;
2348
2349 // Consume the comma.
2350 consumeToken();
2351 } while (true);
2352}
2353
2354/// Parse a header declaration.
2355///
2356/// header-declaration:
2357/// 'textual'[opt] 'header' string-literal
2358/// 'private' 'textual'[opt] 'header' string-literal
2359/// 'exclude' 'header' string-literal
2360/// 'umbrella' 'header' string-literal
2361///
2362/// FIXME: Support 'private textual header'.
2363void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
2364 SourceLocation LeadingLoc) {
2365 // We've already consumed the first token.
2366 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
2367
2368 if (LeadingToken == MMToken::PrivateKeyword) {
2369 Role = ModuleMap::PrivateHeader;
2370 // 'private' may optionally be followed by 'textual'.
2371 if (Tok.is(MMToken::TextualKeyword)) {
2372 LeadingToken = Tok.Kind;
2373 consumeToken();
2374 }
2375 } else if (LeadingToken == MMToken::ExcludeKeyword) {
2376 Role = ModuleMap::ExcludedHeader;
2377 }
2378
2379 if (LeadingToken == MMToken::TextualKeyword)
2380 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
2381
2382 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2383 // Mark this header 'textual' (see doc comment for
2384 // Module::UsesRequiresExcludedHack).
2385 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
2386 }
2387
2388 if (LeadingToken != MMToken::HeaderKeyword) {
2389 if (!Tok.is(MMToken::HeaderKeyword)) {
2390 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2391 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
2392 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
2393 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
2394 return;
2395 }
2396 consumeToken();
2397 }
2398
2399 // Parse the header name.
2400 if (!Tok.is(MMToken::StringLiteral)) {
2401 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2402 << "header";
2403 HadError = true;
2404 return;
2405 }
2406 Module::UnresolvedHeaderDirective Header;
2407 Header.FileName = std::string(Tok.getString());
2408 Header.FileNameLoc = consumeToken();
2409 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
2410 Header.Kind = Map.headerRoleToKind(Role);
2411
2412 // Check whether we already have an umbrella.
2413 if (Header.IsUmbrella && ActiveModule->Umbrella) {
2414 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
2415 << ActiveModule->getFullModuleName();
2416 HadError = true;
2417 return;
2418 }
2419
2420 // If we were given stat information, parse it so we can skip looking for
2421 // the file.
2422 if (Tok.is(MMToken::LBrace)) {
2423 SourceLocation LBraceLoc = consumeToken();
2424
2425 while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) {
2426 enum Attribute { Size, ModTime, Unknown };
2427 StringRef Str = Tok.getString();
2428 SourceLocation Loc = consumeToken();
2429 switch (llvm::StringSwitch<Attribute>(Str)
2430 .Case("size", Size)
2431 .Case("mtime", ModTime)
2432 .Default(Unknown)) {
2433 case Size:
2434 if (Header.Size)
2435 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2436 if (!Tok.is(MMToken::IntegerLiteral)) {
2437 Diags.Report(Tok.getLocation(),
2438 diag::err_mmap_invalid_header_attribute_value) << Str;
2439 skipUntil(MMToken::RBrace);
2440 break;
2441 }
2442 Header.Size = Tok.getInteger();
2443 consumeToken();
2444 break;
2445
2446 case ModTime:
2447 if (Header.ModTime)
2448 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2449 if (!Tok.is(MMToken::IntegerLiteral)) {
2450 Diags.Report(Tok.getLocation(),
2451 diag::err_mmap_invalid_header_attribute_value) << Str;
2452 skipUntil(MMToken::RBrace);
2453 break;
2454 }
2455 Header.ModTime = Tok.getInteger();
2456 consumeToken();
2457 break;
2458
2459 case Unknown:
2460 Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
2461 skipUntil(MMToken::RBrace);
2462 break;
2463 }
2464 }
2465
2466 if (Tok.is(MMToken::RBrace))
2467 consumeToken();
2468 else {
2469 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2470 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2471 HadError = true;
2472 }
2473 }
2474
2475 bool NeedsFramework = false;
2476 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2477
2478 if (NeedsFramework && ActiveModule)
2479 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2480 << ActiveModule->getFullModuleName()
2481 << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module");
2482}
2483
2484static int compareModuleHeaders(const Module::Header *A,
2485 const Module::Header *B) {
2486 return A->NameAsWritten.compare(B->NameAsWritten);
2487}
2488
2489/// Parse an umbrella directory declaration.
2490///
2491/// umbrella-dir-declaration:
2492/// umbrella string-literal
2493void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
2494 // Parse the directory name.
2495 if (!Tok.is(MMToken::StringLiteral)) {
2496 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2497 << "umbrella";
2498 HadError = true;
2499 return;
2500 }
2501
2502 std::string DirName = std::string(Tok.getString());
2503 std::string DirNameAsWritten = DirName;
2504 SourceLocation DirNameLoc = consumeToken();
2505
2506 // Check whether we already have an umbrella.
2507 if (ActiveModule->Umbrella) {
2508 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2509 << ActiveModule->getFullModuleName();
2510 HadError = true;
2511 return;
2512 }
2513
2514 // Look for this file.
2515 const DirectoryEntry *Dir = nullptr;
2516 if (llvm::sys::path::is_absolute(DirName)) {
2517 if (auto D = SourceMgr.getFileManager().getDirectory(DirName))
2518 Dir = *D;
2519 } else {
2520 SmallString<128> PathName;
2521 PathName = Directory->getName();
2522 llvm::sys::path::append(PathName, DirName);
2523 if (auto D = SourceMgr.getFileManager().getDirectory(PathName))
2524 Dir = *D;
2525 }
2526
2527 if (!Dir) {
2528 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2529 << DirName;
2530 return;
2531 }
2532
2533 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2534 // Mark this header 'textual' (see doc comment for
2535 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
2536 // directory is relatively expensive, in practice this only applies to the
2537 // uncommonly used Tcl module on Darwin platforms.
2538 std::error_code EC;
2539 SmallVector<Module::Header, 6> Headers;
2540 llvm::vfs::FileSystem &FS =
2541 SourceMgr.getFileManager().getVirtualFileSystem();
2542 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
2543 I != E && !EC; I.increment(EC)) {
2544 if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) {
2545 Module::Header Header = {"", std::string(I->path()), FE};
2546 Headers.push_back(std::move(Header));
2547 }
2548 }
2549
2550 // Sort header paths so that the pcm doesn't depend on iteration order.
2551 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
2552
2553 for (auto &Header : Headers)
2554 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
2555 return;
2556 }
2557
2558 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
2559 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2560 << OwningModule->getFullModuleName();
2561 HadError = true;
2562 return;
2563 }
2564
2565 // Record this umbrella directory.
2566 Map.setUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName);
2567}
2568
2569/// Parse a module export declaration.
2570///
2571/// export-declaration:
2572/// 'export' wildcard-module-id
2573///
2574/// wildcard-module-id:
2575/// identifier
2576/// '*'
2577/// identifier '.' wildcard-module-id
2578void ModuleMapParser::parseExportDecl() {
2579 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"
, 2579, __extension__ __PRETTY_FUNCTION__))
;
2580 SourceLocation ExportLoc = consumeToken();
2581
2582 // Parse the module-id with an optional wildcard at the end.
2583 ModuleId ParsedModuleId;
2584 bool Wildcard = false;
2585 do {
2586 // FIXME: Support string-literal module names here.
2587 if (Tok.is(MMToken::Identifier)) {
2588 ParsedModuleId.push_back(
2589 std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
2590 consumeToken();
2591
2592 if (Tok.is(MMToken::Period)) {
2593 consumeToken();
2594 continue;
2595 }
2596
2597 break;
2598 }
2599
2600 if(Tok.is(MMToken::Star)) {
2601 Wildcard = true;
2602 consumeToken();
2603 break;
2604 }
2605
2606 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
2607 HadError = true;
2608 return;
2609 } while (true);
2610
2611 Module::UnresolvedExportDecl Unresolved = {
2612 ExportLoc, ParsedModuleId, Wildcard
2613 };
2614 ActiveModule->UnresolvedExports.push_back(Unresolved);
2615}
2616
2617/// Parse a module export_as declaration.
2618///
2619/// export-as-declaration:
2620/// 'export_as' identifier
2621void ModuleMapParser::parseExportAsDecl() {
2622 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", 2622, __extension__ __PRETTY_FUNCTION__
))
;
2623 consumeToken();
2624
2625 if (!Tok.is(MMToken::Identifier)) {
2626 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
2627 HadError = true;
2628 return;
2629 }
2630
2631 if (ActiveModule->Parent) {
2632 Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);
2633 consumeToken();
2634 return;
2635 }
2636
2637 if (!ActiveModule->ExportAsModule.empty()) {
2638 if (ActiveModule->ExportAsModule == Tok.getString()) {
2639 Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as)
2640 << ActiveModule->Name << Tok.getString();
2641 } else {
2642 Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as)
2643 << ActiveModule->Name << ActiveModule->ExportAsModule
2644 << Tok.getString();
2645 }
2646 }
2647
2648 ActiveModule->ExportAsModule = std::string(Tok.getString());
2649 Map.addLinkAsDependency(ActiveModule);
2650
2651 consumeToken();
2652}
2653
2654/// Parse a module use declaration.
2655///
2656/// use-declaration:
2657/// 'use' wildcard-module-id
2658void ModuleMapParser::parseUseDecl() {
2659 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"
, 2659, __extension__ __PRETTY_FUNCTION__))
;
2660 auto KWLoc = consumeToken();
2661 // Parse the module-id.
2662 ModuleId ParsedModuleId;
2663 parseModuleId(ParsedModuleId);
2664
2665 if (ActiveModule->Parent)
2666 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2667 else
2668 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
2669}
2670
2671/// Parse a link declaration.
2672///
2673/// module-declaration:
2674/// 'link' 'framework'[opt] string-literal
2675void ModuleMapParser::parseLinkDecl() {
2676 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"
, 2676, __extension__ __PRETTY_FUNCTION__))
;
2677 SourceLocation LinkLoc = consumeToken();
2678
2679 // Parse the optional 'framework' keyword.
2680 bool IsFramework = false;
2681 if (Tok.is(MMToken::FrameworkKeyword)) {
2682 consumeToken();
2683 IsFramework = true;
2684 }
2685
2686 // Parse the library name
2687 if (!Tok.is(MMToken::StringLiteral)) {
2688 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2689 << IsFramework << SourceRange(LinkLoc);
2690 HadError = true;
2691 return;
2692 }
2693
2694 std::string LibraryName = std::string(Tok.getString());
2695 consumeToken();
2696 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2697 IsFramework));
2698}
2699
2700/// Parse a configuration macro declaration.
2701///
2702/// module-declaration:
2703/// 'config_macros' attributes[opt] config-macro-list?
2704///
2705/// config-macro-list:
2706/// identifier (',' identifier)?
2707void ModuleMapParser::parseConfigMacros() {
2708 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"
, 2708, __extension__ __PRETTY_FUNCTION__))
;
2709 SourceLocation ConfigMacrosLoc = consumeToken();
2710
2711 // Only top-level modules can have configuration macros.
2712 if (ActiveModule->Parent) {
2713 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2714 }
2715
2716 // Parse the optional attributes.
2717 Attributes Attrs;
2718 if (parseOptionalAttributes(Attrs))
2719 return;
2720
2721 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2722 ActiveModule->ConfigMacrosExhaustive = true;
2723 }
2724
2725 // If we don't have an identifier, we're done.
2726 // FIXME: Support macros with the same name as a keyword here.
2727 if (!Tok.is(MMToken::Identifier))
2728 return;
2729
2730 // Consume the first identifier.
2731 if (!ActiveModule->Parent) {
2732 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2733 }
2734 consumeToken();
2735
2736 do {
2737 // If there's a comma, consume it.
2738 if (!Tok.is(MMToken::Comma))
2739 break;
2740 consumeToken();
2741
2742 // We expect to see a macro name here.
2743 // FIXME: Support macros with the same name as a keyword here.
2744 if (!Tok.is(MMToken::Identifier)) {
2745 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2746 break;
2747 }
2748
2749 // Consume the macro name.
2750 if (!ActiveModule->Parent) {
2751 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2752 }
2753 consumeToken();
2754 } while (true);
2755}
2756
2757/// Format a module-id into a string.
2758static std::string formatModuleId(const ModuleId &Id) {
2759 std::string result;
2760 {
2761 llvm::raw_string_ostream OS(result);
2762
2763 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2764 if (I)
2765 OS << ".";
2766 OS << Id[I].first;
2767 }
2768 }
2769
2770 return result;
2771}
2772
2773/// Parse a conflict declaration.
2774///
2775/// module-declaration:
2776/// 'conflict' module-id ',' string-literal
2777void ModuleMapParser::parseConflict() {
2778 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"
, 2778, __extension__ __PRETTY_FUNCTION__))
;
2779 SourceLocation ConflictLoc = consumeToken();
2780 Module::UnresolvedConflict Conflict;
2781
2782 // Parse the module-id.
2783 if (parseModuleId(Conflict.Id))
2784 return;
2785
2786 // Parse the ','.
2787 if (!Tok.is(MMToken::Comma)) {
2788 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2789 << SourceRange(ConflictLoc);
2790 return;
2791 }
2792 consumeToken();
2793
2794 // Parse the message.
2795 if (!Tok.is(MMToken::StringLiteral)) {
2796 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2797 << formatModuleId(Conflict.Id);
2798 return;
2799 }
2800 Conflict.Message = Tok.getString().str();
2801 consumeToken();
2802
2803 // Add this unresolved conflict.
2804 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2805}
2806
2807/// Parse an inferred module declaration (wildcard modules).
2808///
2809/// module-declaration:
2810/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2811/// { inferred-module-member* }
2812///
2813/// inferred-module-member:
2814/// 'export' '*'
2815/// 'exclude' identifier
2816void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
2817 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"
, 2817, __extension__ __PRETTY_FUNCTION__))
;
2818 SourceLocation StarLoc = consumeToken();
2819 bool Failed = false;
2820
2821 // Inferred modules must be submodules.
2822 if (!ActiveModule && !Framework) {
2823 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2824 Failed = true;
2825 }
2826
2827 if (ActiveModule) {
2828 // Inferred modules must have umbrella directories.
2829 if (!Failed && ActiveModule->IsAvailable &&
2830 !ActiveModule->getUmbrellaDir()) {
2831 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2832 Failed = true;
2833 }
2834
2835 // Check for redefinition of an inferred module.
2836 if (!Failed && ActiveModule->InferSubmodules) {
2837 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2838 if (ActiveModule->InferredSubmoduleLoc.isValid())
2839 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2840 diag::note_mmap_prev_definition);
2841 Failed = true;
2842 }
2843
2844 // Check for the 'framework' keyword, which is not permitted here.
2845 if (Framework) {
2846 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2847 Framework = false;
Value stored to 'Framework' is never read
2848 }
2849 } else if (Explicit) {
2850 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2851 Explicit = false;
2852 }
2853
2854 // If there were any problems with this inferred submodule, skip its body.
2855 if (Failed) {
2856 if (Tok.is(MMToken::LBrace)) {
2857 consumeToken();
2858 skipUntil(MMToken::RBrace);
2859 if (Tok.is(MMToken::RBrace))
2860 consumeToken();
2861 }
2862 HadError = true;
2863 return;
2864 }
2865
2866 // Parse optional attributes.
2867 Attributes Attrs;
2868 if (parseOptionalAttributes(Attrs))
2869 return;
2870
2871 if (ActiveModule) {
2872 // Note that we have an inferred submodule.
2873 ActiveModule->InferSubmodules = true;
2874 ActiveModule->InferredSubmoduleLoc = StarLoc;
2875 ActiveModule->InferExplicitSubmodules = Explicit;
2876 } else {
2877 // We'll be inferring framework modules for this directory.
2878 Map.InferredDirectories[Directory].InferModules = true;
2879 Map.InferredDirectories[Directory].Attrs = Attrs;
2880 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2881 // FIXME: Handle the 'framework' keyword.
2882 }
2883
2884 // Parse the opening brace.
2885 if (!Tok.is(MMToken::LBrace)) {
2886 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2887 HadError = true;
2888 return;
2889 }
2890 SourceLocation LBraceLoc = consumeToken();
2891
2892 // Parse the body of the inferred submodule.
2893 bool Done = false;
2894 do {
2895 switch (Tok.Kind) {
2896 case MMToken::EndOfFile:
2897 case MMToken::RBrace:
2898 Done = true;
2899 break;
2900
2901 case MMToken::ExcludeKeyword:
2902 if (ActiveModule) {
2903 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2904 << (ActiveModule != nullptr);
2905 consumeToken();
2906 break;
2907 }
2908
2909 consumeToken();
2910 // FIXME: Support string-literal module names here.
2911 if (!Tok.is(MMToken::Identifier)) {
2912 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2913 break;
2914 }
2915
2916 Map.InferredDirectories[Directory].ExcludedModules.push_back(
2917 std::string(Tok.getString()));
2918 consumeToken();
2919 break;
2920
2921 case MMToken::ExportKeyword:
2922 if (!ActiveModule) {
2923 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2924 << (ActiveModule != nullptr);
2925 consumeToken();
2926 break;
2927 }
2928
2929 consumeToken();
2930 if (Tok.is(MMToken::Star))
2931 ActiveModule->InferExportWildcard = true;
2932 else
2933 Diags.Report(Tok.getLocation(),
2934 diag::err_mmap_expected_export_wildcard);
2935 consumeToken();
2936 break;
2937
2938 case MMToken::ExplicitKeyword:
2939 case MMToken::ModuleKeyword:
2940 case MMToken::HeaderKeyword:
2941 case MMToken::PrivateKeyword:
2942 case MMToken::UmbrellaKeyword:
2943 default:
2944 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2945 << (ActiveModule != nullptr);
2946 consumeToken();
2947 break;
2948 }
2949 } while (!Done);
2950
2951 if (Tok.is(MMToken::RBrace))
2952 consumeToken();
2953 else {
2954 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2955 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2956 HadError = true;
2957 }
2958}
2959
2960/// Parse optional attributes.
2961///
2962/// attributes:
2963/// attribute attributes
2964/// attribute
2965///
2966/// attribute:
2967/// [ identifier ]
2968///
2969/// \param Attrs Will be filled in with the parsed attributes.
2970///
2971/// \returns true if an error occurred, false otherwise.
2972bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2973 bool HadError = false;
2974
2975 while (Tok.is(MMToken::LSquare)) {
2976 // Consume the '['.
2977 SourceLocation LSquareLoc = consumeToken();
2978
2979 // Check whether we have an attribute name here.
2980 if (!Tok.is(MMToken::Identifier)) {
2981 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2982 skipUntil(MMToken::RSquare);
2983 if (Tok.is(MMToken::RSquare))
2984 consumeToken();
2985 HadError = true;
2986 }
2987
2988 // Decode the attribute name.
2989 AttributeKind Attribute
2990 = llvm::StringSwitch<AttributeKind>(Tok.getString())
2991 .Case("exhaustive", AT_exhaustive)
2992 .Case("extern_c", AT_extern_c)
2993 .Case("no_undeclared_includes", AT_no_undeclared_includes)
2994 .Case("system", AT_system)
2995 .Default(AT_unknown);
2996 switch (Attribute) {
2997 case AT_unknown:
2998 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2999 << Tok.getString();
3000 break;
3001
3002 case AT_system:
3003 Attrs.IsSystem = true;
3004 break;
3005
3006 case AT_extern_c:
3007 Attrs.IsExternC = true;
3008 break;
3009
3010 case AT_exhaustive:
3011 Attrs.IsExhaustive = true;
3012 break;
3013
3014 case AT_no_undeclared_includes:
3015 Attrs.NoUndeclaredIncludes = true;
3016 break;
3017 }
3018 consumeToken();
3019
3020 // Consume the ']'.
3021 if (!Tok.is(MMToken::RSquare)) {
3022 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
3023 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
3024 skipUntil(MMToken::RSquare);
3025 HadError = true;
3026 }
3027
3028 if (Tok.is(MMToken::RSquare))
3029 consumeToken();
3030 }
3031
3032 return HadError;
3033}
3034
3035/// Parse a module map file.
3036///
3037/// module-map-file:
3038/// module-declaration*
3039bool ModuleMapParser::parseModuleMapFile() {
3040 do {
3041 switch (Tok.Kind) {
3042 case MMToken::EndOfFile:
3043 return HadError;
3044
3045 case MMToken::ExplicitKeyword:
3046 case MMToken::ExternKeyword:
3047 case MMToken::ModuleKeyword:
3048 case MMToken::FrameworkKeyword:
3049 parseModuleDecl();
3050 break;
3051
3052 case MMToken::Comma:
3053 case MMToken::ConfigMacros:
3054 case MMToken::Conflict:
3055 case MMToken::Exclaim:
3056 case MMToken::ExcludeKeyword:
3057 case MMToken::ExportKeyword:
3058 case MMToken::ExportAsKeyword:
3059 case MMToken::HeaderKeyword:
3060 case MMToken::Identifier:
3061 case MMToken::LBrace:
3062 case MMToken::LinkKeyword:
3063 case MMToken::LSquare:
3064 case MMToken::Period:
3065 case MMToken::PrivateKeyword:
3066 case MMToken::RBrace:
3067 case MMToken::RSquare:
3068 case MMToken::RequiresKeyword:
3069 case MMToken::Star:
3070 case MMToken::StringLiteral:
3071 case MMToken::IntegerLiteral:
3072 case MMToken::TextualKeyword:
3073 case MMToken::UmbrellaKeyword:
3074 case MMToken::UseKeyword:
3075 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
3076 HadError = true;
3077 consumeToken();
3078 break;
3079 }
3080 } while (true);
3081}
3082
3083bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
3084 const DirectoryEntry *Dir, FileID ID,
3085 unsigned *Offset,
3086 SourceLocation ExternModuleLoc) {
3087 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", 3087, __extension__ __PRETTY_FUNCTION__
))
;
3088 llvm::DenseMap<const FileEntry *, bool>::iterator Known
3089 = ParsedModuleMap.find(File);
3090 if (Known != ParsedModuleMap.end())
3091 return Known->second;
3092
3093 // If the module map file wasn't already entered, do so now.
3094 if (ID.isInvalid()) {
3095 auto FileCharacter =
3096 IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
3097 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
3098 }
3099
3100 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", 3100, __extension__ __PRETTY_FUNCTION__
))
;
3101 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
3102 if (!Buffer)
3103 return ParsedModuleMap[File] = true;
3104 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", 3105, __extension__ __PRETTY_FUNCTION__
))
3105 "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", 3105, __extension__ __PRETTY_FUNCTION__
))
;
3106
3107 // Parse this module map file.
3108 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
3109 Buffer->getBufferStart(),
3110 Buffer->getBufferStart() + (Offset ? *Offset : 0),
3111 Buffer->getBufferEnd());
3112 SourceLocation Start = L.getSourceLocation();
3113 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
3114 IsSystem);
3115 bool Result = Parser.parseModuleMapFile();
3116 ParsedModuleMap[File] = Result;
3117
3118 if (Offset) {
3119 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation());
3120 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", 3120, __extension__ __PRETTY_FUNCTION__
))
;
3121 *Offset = Loc.second;
3122 }
3123
3124 // Notify callbacks that we parsed it.
3125 for (const auto &Cb : Callbacks)
3126 Cb->moduleMapFileRead(Start, *File, IsSystem);
3127
3128 return Result;
3129}