Bug Summary

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