Bug Summary

File:clang/lib/Lex/ModuleMap.cpp
Warning:line 2730, column 7
Value stored to 'Framework' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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