Bug Summary

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