Bug Summary

File:tools/clang/lib/Lex/ModuleMap.cpp
Warning:line 1181, column 7
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

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