Bug Summary

File:build/llvm-toolchain-snapshot-16~++20220929111209+ac2e2d659819/clang/lib/Lex/ModuleMap.cpp
Warning:line 2788, column 7
Value stored to 'Framework' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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