Bug Summary

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