106f32e7eSjoerg //===- ModuleMap.cpp - Describe the layout of modules ---------------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file defines the ModuleMap implementation, which describes the layout
1006f32e7eSjoerg // of a module as it relates to headers.
1106f32e7eSjoerg //
1206f32e7eSjoerg //===----------------------------------------------------------------------===//
1306f32e7eSjoerg 
1406f32e7eSjoerg #include "clang/Lex/ModuleMap.h"
1506f32e7eSjoerg #include "clang/Basic/CharInfo.h"
1606f32e7eSjoerg #include "clang/Basic/Diagnostic.h"
1706f32e7eSjoerg #include "clang/Basic/FileManager.h"
1806f32e7eSjoerg #include "clang/Basic/LLVM.h"
1906f32e7eSjoerg #include "clang/Basic/LangOptions.h"
2006f32e7eSjoerg #include "clang/Basic/Module.h"
2106f32e7eSjoerg #include "clang/Basic/SourceLocation.h"
2206f32e7eSjoerg #include "clang/Basic/SourceManager.h"
2306f32e7eSjoerg #include "clang/Basic/TargetInfo.h"
2406f32e7eSjoerg #include "clang/Lex/HeaderSearch.h"
2506f32e7eSjoerg #include "clang/Lex/HeaderSearchOptions.h"
2606f32e7eSjoerg #include "clang/Lex/LexDiagnostic.h"
2706f32e7eSjoerg #include "clang/Lex/Lexer.h"
2806f32e7eSjoerg #include "clang/Lex/LiteralSupport.h"
2906f32e7eSjoerg #include "clang/Lex/Token.h"
3006f32e7eSjoerg #include "llvm/ADT/DenseMap.h"
3106f32e7eSjoerg #include "llvm/ADT/None.h"
3206f32e7eSjoerg #include "llvm/ADT/STLExtras.h"
3306f32e7eSjoerg #include "llvm/ADT/SmallPtrSet.h"
3406f32e7eSjoerg #include "llvm/ADT/SmallString.h"
3506f32e7eSjoerg #include "llvm/ADT/SmallVector.h"
3606f32e7eSjoerg #include "llvm/ADT/StringMap.h"
3706f32e7eSjoerg #include "llvm/ADT/StringRef.h"
3806f32e7eSjoerg #include "llvm/ADT/StringSwitch.h"
3906f32e7eSjoerg #include "llvm/Support/Allocator.h"
4006f32e7eSjoerg #include "llvm/Support/Compiler.h"
4106f32e7eSjoerg #include "llvm/Support/ErrorHandling.h"
4206f32e7eSjoerg #include "llvm/Support/MemoryBuffer.h"
4306f32e7eSjoerg #include "llvm/Support/Path.h"
4406f32e7eSjoerg #include "llvm/Support/VirtualFileSystem.h"
4506f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
4606f32e7eSjoerg #include <algorithm>
4706f32e7eSjoerg #include <cassert>
4806f32e7eSjoerg #include <cstdint>
4906f32e7eSjoerg #include <cstring>
5006f32e7eSjoerg #include <string>
5106f32e7eSjoerg #include <system_error>
5206f32e7eSjoerg #include <utility>
5306f32e7eSjoerg 
5406f32e7eSjoerg using namespace clang;
5506f32e7eSjoerg 
anchor()5606f32e7eSjoerg void ModuleMapCallbacks::anchor() {}
5706f32e7eSjoerg 
resolveLinkAsDependencies(Module * Mod)5806f32e7eSjoerg void ModuleMap::resolveLinkAsDependencies(Module *Mod) {
5906f32e7eSjoerg   auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);
6006f32e7eSjoerg   if (PendingLinkAs != PendingLinkAsModule.end()) {
6106f32e7eSjoerg     for (auto &Name : PendingLinkAs->second) {
6206f32e7eSjoerg       auto *M = findModule(Name.getKey());
6306f32e7eSjoerg       if (M)
6406f32e7eSjoerg         M->UseExportAsModuleLinkName = true;
6506f32e7eSjoerg     }
6606f32e7eSjoerg   }
6706f32e7eSjoerg }
6806f32e7eSjoerg 
addLinkAsDependency(Module * Mod)6906f32e7eSjoerg void ModuleMap::addLinkAsDependency(Module *Mod) {
7006f32e7eSjoerg   if (findModule(Mod->ExportAsModule))
7106f32e7eSjoerg     Mod->UseExportAsModuleLinkName = true;
7206f32e7eSjoerg   else
7306f32e7eSjoerg     PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name);
7406f32e7eSjoerg }
7506f32e7eSjoerg 
headerRoleToKind(ModuleHeaderRole Role)7606f32e7eSjoerg Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) {
7706f32e7eSjoerg   switch ((int)Role) {
7806f32e7eSjoerg   default: llvm_unreachable("unknown header role");
7906f32e7eSjoerg   case NormalHeader:
8006f32e7eSjoerg     return Module::HK_Normal;
8106f32e7eSjoerg   case PrivateHeader:
8206f32e7eSjoerg     return Module::HK_Private;
8306f32e7eSjoerg   case TextualHeader:
8406f32e7eSjoerg     return Module::HK_Textual;
8506f32e7eSjoerg   case PrivateHeader | TextualHeader:
8606f32e7eSjoerg     return Module::HK_PrivateTextual;
8706f32e7eSjoerg   }
8806f32e7eSjoerg }
8906f32e7eSjoerg 
9006f32e7eSjoerg ModuleMap::ModuleHeaderRole
headerKindToRole(Module::HeaderKind Kind)9106f32e7eSjoerg ModuleMap::headerKindToRole(Module::HeaderKind Kind) {
9206f32e7eSjoerg   switch ((int)Kind) {
9306f32e7eSjoerg   case Module::HK_Normal:
9406f32e7eSjoerg     return NormalHeader;
9506f32e7eSjoerg   case Module::HK_Private:
9606f32e7eSjoerg     return PrivateHeader;
9706f32e7eSjoerg   case Module::HK_Textual:
9806f32e7eSjoerg     return TextualHeader;
9906f32e7eSjoerg   case Module::HK_PrivateTextual:
10006f32e7eSjoerg     return ModuleHeaderRole(PrivateHeader | TextualHeader);
10106f32e7eSjoerg   case Module::HK_Excluded:
10206f32e7eSjoerg     llvm_unreachable("unexpected header kind");
10306f32e7eSjoerg   }
10406f32e7eSjoerg   llvm_unreachable("unknown header kind");
10506f32e7eSjoerg }
10606f32e7eSjoerg 
10706f32e7eSjoerg Module::ExportDecl
resolveExport(Module * Mod,const Module::UnresolvedExportDecl & Unresolved,bool Complain) const10806f32e7eSjoerg ModuleMap::resolveExport(Module *Mod,
10906f32e7eSjoerg                          const Module::UnresolvedExportDecl &Unresolved,
11006f32e7eSjoerg                          bool Complain) const {
11106f32e7eSjoerg   // We may have just a wildcard.
11206f32e7eSjoerg   if (Unresolved.Id.empty()) {
11306f32e7eSjoerg     assert(Unresolved.Wildcard && "Invalid unresolved export");
11406f32e7eSjoerg     return Module::ExportDecl(nullptr, true);
11506f32e7eSjoerg   }
11606f32e7eSjoerg 
11706f32e7eSjoerg   // Resolve the module-id.
11806f32e7eSjoerg   Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
11906f32e7eSjoerg   if (!Context)
12006f32e7eSjoerg     return {};
12106f32e7eSjoerg 
12206f32e7eSjoerg   return Module::ExportDecl(Context, Unresolved.Wildcard);
12306f32e7eSjoerg }
12406f32e7eSjoerg 
resolveModuleId(const ModuleId & Id,Module * Mod,bool Complain) const12506f32e7eSjoerg Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
12606f32e7eSjoerg                                    bool Complain) const {
12706f32e7eSjoerg   // Find the starting module.
12806f32e7eSjoerg   Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
12906f32e7eSjoerg   if (!Context) {
13006f32e7eSjoerg     if (Complain)
13106f32e7eSjoerg       Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
13206f32e7eSjoerg       << Id[0].first << Mod->getFullModuleName();
13306f32e7eSjoerg 
13406f32e7eSjoerg     return nullptr;
13506f32e7eSjoerg   }
13606f32e7eSjoerg 
13706f32e7eSjoerg   // Dig into the module path.
13806f32e7eSjoerg   for (unsigned I = 1, N = Id.size(); I != N; ++I) {
13906f32e7eSjoerg     Module *Sub = lookupModuleQualified(Id[I].first, Context);
14006f32e7eSjoerg     if (!Sub) {
14106f32e7eSjoerg       if (Complain)
14206f32e7eSjoerg         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
14306f32e7eSjoerg         << Id[I].first << Context->getFullModuleName()
14406f32e7eSjoerg         << SourceRange(Id[0].second, Id[I-1].second);
14506f32e7eSjoerg 
14606f32e7eSjoerg       return nullptr;
14706f32e7eSjoerg     }
14806f32e7eSjoerg 
14906f32e7eSjoerg     Context = Sub;
15006f32e7eSjoerg   }
15106f32e7eSjoerg 
15206f32e7eSjoerg   return Context;
15306f32e7eSjoerg }
15406f32e7eSjoerg 
15506f32e7eSjoerg /// Append to \p Paths the set of paths needed to get to the
15606f32e7eSjoerg /// subframework in which the given module lives.
appendSubframeworkPaths(Module * Mod,SmallVectorImpl<char> & Path)15706f32e7eSjoerg static void appendSubframeworkPaths(Module *Mod,
15806f32e7eSjoerg                                     SmallVectorImpl<char> &Path) {
15906f32e7eSjoerg   // Collect the framework names from the given module to the top-level module.
16006f32e7eSjoerg   SmallVector<StringRef, 2> Paths;
16106f32e7eSjoerg   for (; Mod; Mod = Mod->Parent) {
16206f32e7eSjoerg     if (Mod->IsFramework)
16306f32e7eSjoerg       Paths.push_back(Mod->Name);
16406f32e7eSjoerg   }
16506f32e7eSjoerg 
16606f32e7eSjoerg   if (Paths.empty())
16706f32e7eSjoerg     return;
16806f32e7eSjoerg 
16906f32e7eSjoerg   // Add Frameworks/Name.framework for each subframework.
17006f32e7eSjoerg   for (unsigned I = Paths.size() - 1; I != 0; --I)
17106f32e7eSjoerg     llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
17206f32e7eSjoerg }
17306f32e7eSjoerg 
findHeader(Module * M,const Module::UnresolvedHeaderDirective & Header,SmallVectorImpl<char> & RelativePathName,bool & NeedsFramework)174*13fbcb42Sjoerg Optional<FileEntryRef> ModuleMap::findHeader(
17506f32e7eSjoerg     Module *M, const Module::UnresolvedHeaderDirective &Header,
17606f32e7eSjoerg     SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) {
17706f32e7eSjoerg   // Search for the header file within the module's home directory.
17806f32e7eSjoerg   auto *Directory = M->Directory;
17906f32e7eSjoerg   SmallString<128> FullPathName(Directory->getName());
18006f32e7eSjoerg 
181*13fbcb42Sjoerg   auto GetFile = [&](StringRef Filename) -> Optional<FileEntryRef> {
182*13fbcb42Sjoerg     auto File =
183*13fbcb42Sjoerg         expectedToOptional(SourceMgr.getFileManager().getFileRef(Filename));
184*13fbcb42Sjoerg     if (!File || (Header.Size && File->getSize() != *Header.Size) ||
185*13fbcb42Sjoerg         (Header.ModTime && File->getModificationTime() != *Header.ModTime))
186*13fbcb42Sjoerg       return None;
18706f32e7eSjoerg     return *File;
18806f32e7eSjoerg   };
18906f32e7eSjoerg 
190*13fbcb42Sjoerg   auto GetFrameworkFile = [&]() -> Optional<FileEntryRef> {
19106f32e7eSjoerg     unsigned FullPathLength = FullPathName.size();
19206f32e7eSjoerg     appendSubframeworkPaths(M, RelativePathName);
19306f32e7eSjoerg     unsigned RelativePathLength = RelativePathName.size();
19406f32e7eSjoerg 
19506f32e7eSjoerg     // Check whether this file is in the public headers.
19606f32e7eSjoerg     llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
19706f32e7eSjoerg     llvm::sys::path::append(FullPathName, RelativePathName);
198*13fbcb42Sjoerg     if (auto File = GetFile(FullPathName))
19906f32e7eSjoerg       return File;
20006f32e7eSjoerg 
20106f32e7eSjoerg     // Check whether this file is in the private headers.
20206f32e7eSjoerg     // Ideally, private modules in the form 'FrameworkName.Private' should
20306f32e7eSjoerg     // be defined as 'module FrameworkName.Private', and not as
20406f32e7eSjoerg     // 'framework module FrameworkName.Private', since a 'Private.Framework'
20506f32e7eSjoerg     // does not usually exist. However, since both are currently widely used
20606f32e7eSjoerg     // for private modules, make sure we find the right path in both cases.
20706f32e7eSjoerg     if (M->IsFramework && M->Name == "Private")
20806f32e7eSjoerg       RelativePathName.clear();
20906f32e7eSjoerg     else
21006f32e7eSjoerg       RelativePathName.resize(RelativePathLength);
21106f32e7eSjoerg     FullPathName.resize(FullPathLength);
21206f32e7eSjoerg     llvm::sys::path::append(RelativePathName, "PrivateHeaders",
21306f32e7eSjoerg                             Header.FileName);
21406f32e7eSjoerg     llvm::sys::path::append(FullPathName, RelativePathName);
21506f32e7eSjoerg     return GetFile(FullPathName);
21606f32e7eSjoerg   };
21706f32e7eSjoerg 
21806f32e7eSjoerg   if (llvm::sys::path::is_absolute(Header.FileName)) {
21906f32e7eSjoerg     RelativePathName.clear();
22006f32e7eSjoerg     RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
22106f32e7eSjoerg     return GetFile(Header.FileName);
22206f32e7eSjoerg   }
22306f32e7eSjoerg 
22406f32e7eSjoerg   if (M->isPartOfFramework())
22506f32e7eSjoerg     return GetFrameworkFile();
22606f32e7eSjoerg 
22706f32e7eSjoerg   // Lookup for normal headers.
22806f32e7eSjoerg   llvm::sys::path::append(RelativePathName, Header.FileName);
22906f32e7eSjoerg   llvm::sys::path::append(FullPathName, RelativePathName);
230*13fbcb42Sjoerg   auto NormalHdrFile = GetFile(FullPathName);
23106f32e7eSjoerg 
232*13fbcb42Sjoerg   if (!NormalHdrFile && Directory->getName().endswith(".framework")) {
23306f32e7eSjoerg     // The lack of 'framework' keyword in a module declaration it's a simple
23406f32e7eSjoerg     // mistake we can diagnose when the header exists within the proper
23506f32e7eSjoerg     // framework style path.
23606f32e7eSjoerg     FullPathName.assign(Directory->getName());
23706f32e7eSjoerg     RelativePathName.clear();
23806f32e7eSjoerg     if (GetFrameworkFile()) {
23906f32e7eSjoerg       Diags.Report(Header.FileNameLoc,
24006f32e7eSjoerg                    diag::warn_mmap_incomplete_framework_module_declaration)
24106f32e7eSjoerg           << Header.FileName << M->getFullModuleName();
24206f32e7eSjoerg       NeedsFramework = true;
24306f32e7eSjoerg     }
244*13fbcb42Sjoerg     return None;
24506f32e7eSjoerg   }
24606f32e7eSjoerg 
24706f32e7eSjoerg   return NormalHdrFile;
24806f32e7eSjoerg }
24906f32e7eSjoerg 
resolveHeader(Module * Mod,const Module::UnresolvedHeaderDirective & Header,bool & NeedsFramework)25006f32e7eSjoerg void ModuleMap::resolveHeader(Module *Mod,
25106f32e7eSjoerg                               const Module::UnresolvedHeaderDirective &Header,
25206f32e7eSjoerg                               bool &NeedsFramework) {
25306f32e7eSjoerg   SmallString<128> RelativePathName;
254*13fbcb42Sjoerg   if (Optional<FileEntryRef> File =
25506f32e7eSjoerg           findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
25606f32e7eSjoerg     if (Header.IsUmbrella) {
257*13fbcb42Sjoerg       const DirectoryEntry *UmbrellaDir = &File->getDir().getDirEntry();
25806f32e7eSjoerg       if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
25906f32e7eSjoerg         Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
26006f32e7eSjoerg           << UmbrellaMod->getFullModuleName();
26106f32e7eSjoerg       else
26206f32e7eSjoerg         // Record this umbrella header.
263*13fbcb42Sjoerg         setUmbrellaHeader(Mod, *File, Header.FileName, RelativePathName.str());
26406f32e7eSjoerg     } else {
265*13fbcb42Sjoerg       Module::Header H = {Header.FileName, std::string(RelativePathName.str()),
266*13fbcb42Sjoerg                           *File};
26706f32e7eSjoerg       if (Header.Kind == Module::HK_Excluded)
26806f32e7eSjoerg         excludeHeader(Mod, H);
26906f32e7eSjoerg       else
27006f32e7eSjoerg         addHeader(Mod, H, headerKindToRole(Header.Kind));
27106f32e7eSjoerg     }
27206f32e7eSjoerg   } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) {
27306f32e7eSjoerg     // There's a builtin header but no corresponding on-disk header. Assume
27406f32e7eSjoerg     // this was supposed to modularize the builtin header alone.
27506f32e7eSjoerg   } else if (Header.Kind == Module::HK_Excluded) {
27606f32e7eSjoerg     // Ignore missing excluded header files. They're optional anyway.
27706f32e7eSjoerg   } else {
27806f32e7eSjoerg     // If we find a module that has a missing header, we mark this module as
27906f32e7eSjoerg     // unavailable and store the header directive for displaying diagnostics.
28006f32e7eSjoerg     Mod->MissingHeaders.push_back(Header);
28106f32e7eSjoerg     // A missing header with stat information doesn't make the module
28206f32e7eSjoerg     // unavailable; this keeps our behavior consistent as headers are lazily
28306f32e7eSjoerg     // resolved. (Such a module still can't be built though, except from
28406f32e7eSjoerg     // preprocessed source.)
28506f32e7eSjoerg     if (!Header.Size && !Header.ModTime)
286*13fbcb42Sjoerg       Mod->markUnavailable(/*Unimportable=*/false);
28706f32e7eSjoerg   }
28806f32e7eSjoerg }
28906f32e7eSjoerg 
resolveAsBuiltinHeader(Module * Mod,const Module::UnresolvedHeaderDirective & Header)29006f32e7eSjoerg bool ModuleMap::resolveAsBuiltinHeader(
29106f32e7eSjoerg     Module *Mod, const Module::UnresolvedHeaderDirective &Header) {
29206f32e7eSjoerg   if (Header.Kind == Module::HK_Excluded ||
29306f32e7eSjoerg       llvm::sys::path::is_absolute(Header.FileName) ||
29406f32e7eSjoerg       Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
29506f32e7eSjoerg       !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
29606f32e7eSjoerg       !isBuiltinHeader(Header.FileName))
29706f32e7eSjoerg     return false;
29806f32e7eSjoerg 
29906f32e7eSjoerg   // This is a system module with a top-level header. This header
30006f32e7eSjoerg   // may have a counterpart (or replacement) in the set of headers
30106f32e7eSjoerg   // supplied by Clang. Find that builtin header.
30206f32e7eSjoerg   SmallString<128> Path;
30306f32e7eSjoerg   llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
30406f32e7eSjoerg   auto File = SourceMgr.getFileManager().getFile(Path);
30506f32e7eSjoerg   if (!File)
30606f32e7eSjoerg     return false;
30706f32e7eSjoerg 
30806f32e7eSjoerg   auto Role = headerKindToRole(Header.Kind);
309*13fbcb42Sjoerg   Module::Header H = {Header.FileName, std::string(Path.str()), *File};
31006f32e7eSjoerg   addHeader(Mod, H, Role);
31106f32e7eSjoerg   return true;
31206f32e7eSjoerg }
31306f32e7eSjoerg 
ModuleMap(SourceManager & SourceMgr,DiagnosticsEngine & Diags,const LangOptions & LangOpts,const TargetInfo * Target,HeaderSearch & HeaderInfo)31406f32e7eSjoerg ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
31506f32e7eSjoerg                      const LangOptions &LangOpts, const TargetInfo *Target,
31606f32e7eSjoerg                      HeaderSearch &HeaderInfo)
31706f32e7eSjoerg     : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
31806f32e7eSjoerg       HeaderInfo(HeaderInfo) {
31906f32e7eSjoerg   MMapLangOpts.LineComment = true;
32006f32e7eSjoerg }
32106f32e7eSjoerg 
~ModuleMap()32206f32e7eSjoerg ModuleMap::~ModuleMap() {
32306f32e7eSjoerg   for (auto &M : Modules)
32406f32e7eSjoerg     delete M.getValue();
32506f32e7eSjoerg   for (auto *M : ShadowModules)
32606f32e7eSjoerg     delete M;
32706f32e7eSjoerg }
32806f32e7eSjoerg 
setTarget(const TargetInfo & Target)32906f32e7eSjoerg void ModuleMap::setTarget(const TargetInfo &Target) {
33006f32e7eSjoerg   assert((!this->Target || this->Target == &Target) &&
33106f32e7eSjoerg          "Improper target override");
33206f32e7eSjoerg   this->Target = &Target;
33306f32e7eSjoerg }
33406f32e7eSjoerg 
33506f32e7eSjoerg /// "Sanitize" a filename so that it can be used as an identifier.
sanitizeFilenameAsIdentifier(StringRef Name,SmallVectorImpl<char> & Buffer)33606f32e7eSjoerg static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
33706f32e7eSjoerg                                               SmallVectorImpl<char> &Buffer) {
33806f32e7eSjoerg   if (Name.empty())
33906f32e7eSjoerg     return Name;
34006f32e7eSjoerg 
34106f32e7eSjoerg   if (!isValidIdentifier(Name)) {
34206f32e7eSjoerg     // If we don't already have something with the form of an identifier,
34306f32e7eSjoerg     // create a buffer with the sanitized name.
34406f32e7eSjoerg     Buffer.clear();
34506f32e7eSjoerg     if (isDigit(Name[0]))
34606f32e7eSjoerg       Buffer.push_back('_');
34706f32e7eSjoerg     Buffer.reserve(Buffer.size() + Name.size());
34806f32e7eSjoerg     for (unsigned I = 0, N = Name.size(); I != N; ++I) {
34906f32e7eSjoerg       if (isIdentifierBody(Name[I]))
35006f32e7eSjoerg         Buffer.push_back(Name[I]);
35106f32e7eSjoerg       else
35206f32e7eSjoerg         Buffer.push_back('_');
35306f32e7eSjoerg     }
35406f32e7eSjoerg 
35506f32e7eSjoerg     Name = StringRef(Buffer.data(), Buffer.size());
35606f32e7eSjoerg   }
35706f32e7eSjoerg 
35806f32e7eSjoerg   while (llvm::StringSwitch<bool>(Name)
35906f32e7eSjoerg #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
36006f32e7eSjoerg #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
36106f32e7eSjoerg #include "clang/Basic/TokenKinds.def"
36206f32e7eSjoerg            .Default(false)) {
36306f32e7eSjoerg     if (Name.data() != Buffer.data())
36406f32e7eSjoerg       Buffer.append(Name.begin(), Name.end());
36506f32e7eSjoerg     Buffer.push_back('_');
36606f32e7eSjoerg     Name = StringRef(Buffer.data(), Buffer.size());
36706f32e7eSjoerg   }
36806f32e7eSjoerg 
36906f32e7eSjoerg   return Name;
37006f32e7eSjoerg }
37106f32e7eSjoerg 
37206f32e7eSjoerg /// Determine whether the given file name is the name of a builtin
37306f32e7eSjoerg /// header, supplied by Clang to replace, override, or augment existing system
37406f32e7eSjoerg /// headers.
isBuiltinHeader(StringRef FileName)37506f32e7eSjoerg bool ModuleMap::isBuiltinHeader(StringRef FileName) {
37606f32e7eSjoerg   return llvm::StringSwitch<bool>(FileName)
37706f32e7eSjoerg            .Case("float.h", true)
37806f32e7eSjoerg            .Case("iso646.h", true)
37906f32e7eSjoerg            .Case("limits.h", true)
38006f32e7eSjoerg            .Case("stdalign.h", true)
38106f32e7eSjoerg            .Case("stdarg.h", true)
38206f32e7eSjoerg            .Case("stdatomic.h", true)
38306f32e7eSjoerg            .Case("stdbool.h", true)
38406f32e7eSjoerg            .Case("stddef.h", true)
38506f32e7eSjoerg            .Case("stdint.h", true)
38606f32e7eSjoerg            .Case("tgmath.h", true)
38706f32e7eSjoerg            .Case("unwind.h", true)
38806f32e7eSjoerg            .Default(false);
38906f32e7eSjoerg }
39006f32e7eSjoerg 
isBuiltinHeader(const FileEntry * File)391*13fbcb42Sjoerg bool ModuleMap::isBuiltinHeader(const FileEntry *File) {
392*13fbcb42Sjoerg   return File->getDir() == BuiltinIncludeDir &&
393*13fbcb42Sjoerg          ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()));
394*13fbcb42Sjoerg }
395*13fbcb42Sjoerg 
39606f32e7eSjoerg ModuleMap::HeadersMap::iterator
findKnownHeader(const FileEntry * File)39706f32e7eSjoerg ModuleMap::findKnownHeader(const FileEntry *File) {
39806f32e7eSjoerg   resolveHeaderDirectives(File);
39906f32e7eSjoerg   HeadersMap::iterator Known = Headers.find(File);
40006f32e7eSjoerg   if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
401*13fbcb42Sjoerg       Known == Headers.end() && ModuleMap::isBuiltinHeader(File)) {
40206f32e7eSjoerg     HeaderInfo.loadTopLevelSystemModules();
40306f32e7eSjoerg     return Headers.find(File);
40406f32e7eSjoerg   }
40506f32e7eSjoerg   return Known;
40606f32e7eSjoerg }
40706f32e7eSjoerg 
40806f32e7eSjoerg ModuleMap::KnownHeader
findHeaderInUmbrellaDirs(const FileEntry * File,SmallVectorImpl<const DirectoryEntry * > & IntermediateDirs)40906f32e7eSjoerg ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
41006f32e7eSjoerg                     SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
41106f32e7eSjoerg   if (UmbrellaDirs.empty())
41206f32e7eSjoerg     return {};
41306f32e7eSjoerg 
41406f32e7eSjoerg   const DirectoryEntry *Dir = File->getDir();
41506f32e7eSjoerg   assert(Dir && "file in no directory");
41606f32e7eSjoerg 
41706f32e7eSjoerg   // Note: as an egregious but useful hack we use the real path here, because
41806f32e7eSjoerg   // frameworks moving from top-level frameworks to embedded frameworks tend
41906f32e7eSjoerg   // to be symlinked from the top-level location to the embedded location,
42006f32e7eSjoerg   // and we need to resolve lookups as if we had found the embedded location.
42106f32e7eSjoerg   StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
42206f32e7eSjoerg 
42306f32e7eSjoerg   // Keep walking up the directory hierarchy, looking for a directory with
42406f32e7eSjoerg   // an umbrella header.
42506f32e7eSjoerg   do {
42606f32e7eSjoerg     auto KnownDir = UmbrellaDirs.find(Dir);
42706f32e7eSjoerg     if (KnownDir != UmbrellaDirs.end())
42806f32e7eSjoerg       return KnownHeader(KnownDir->second, NormalHeader);
42906f32e7eSjoerg 
43006f32e7eSjoerg     IntermediateDirs.push_back(Dir);
43106f32e7eSjoerg 
43206f32e7eSjoerg     // Retrieve our parent path.
43306f32e7eSjoerg     DirName = llvm::sys::path::parent_path(DirName);
43406f32e7eSjoerg     if (DirName.empty())
43506f32e7eSjoerg       break;
43606f32e7eSjoerg 
43706f32e7eSjoerg     // Resolve the parent path to a directory entry.
43806f32e7eSjoerg     if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName))
43906f32e7eSjoerg       Dir = *DirEntry;
44006f32e7eSjoerg     else
44106f32e7eSjoerg       Dir = nullptr;
44206f32e7eSjoerg   } while (Dir);
44306f32e7eSjoerg   return {};
44406f32e7eSjoerg }
44506f32e7eSjoerg 
violatesPrivateInclude(Module * RequestingModule,const FileEntry * IncFileEnt,ModuleMap::KnownHeader Header)44606f32e7eSjoerg static bool violatesPrivateInclude(Module *RequestingModule,
44706f32e7eSjoerg                                    const FileEntry *IncFileEnt,
44806f32e7eSjoerg                                    ModuleMap::KnownHeader Header) {
44906f32e7eSjoerg #ifndef NDEBUG
45006f32e7eSjoerg   if (Header.getRole() & ModuleMap::PrivateHeader) {
45106f32e7eSjoerg     // Check for consistency between the module header role
45206f32e7eSjoerg     // as obtained from the lookup and as obtained from the module.
45306f32e7eSjoerg     // This check is not cheap, so enable it only for debugging.
45406f32e7eSjoerg     bool IsPrivate = false;
45506f32e7eSjoerg     SmallVectorImpl<Module::Header> *HeaderList[] = {
45606f32e7eSjoerg         &Header.getModule()->Headers[Module::HK_Private],
45706f32e7eSjoerg         &Header.getModule()->Headers[Module::HK_PrivateTextual]};
45806f32e7eSjoerg     for (auto *Hs : HeaderList)
45906f32e7eSjoerg       IsPrivate |=
46006f32e7eSjoerg           std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
46106f32e7eSjoerg             return H.Entry == IncFileEnt;
46206f32e7eSjoerg           }) != Hs->end();
46306f32e7eSjoerg     assert(IsPrivate && "inconsistent headers and roles");
46406f32e7eSjoerg   }
46506f32e7eSjoerg #endif
46606f32e7eSjoerg   return !Header.isAccessibleFrom(RequestingModule);
46706f32e7eSjoerg }
46806f32e7eSjoerg 
getTopLevelOrNull(Module * M)46906f32e7eSjoerg static Module *getTopLevelOrNull(Module *M) {
47006f32e7eSjoerg   return M ? M->getTopLevelModule() : nullptr;
47106f32e7eSjoerg }
47206f32e7eSjoerg 
diagnoseHeaderInclusion(Module * RequestingModule,bool RequestingModuleIsModuleInterface,SourceLocation FilenameLoc,StringRef Filename,const FileEntry * File)47306f32e7eSjoerg void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
47406f32e7eSjoerg                                         bool RequestingModuleIsModuleInterface,
47506f32e7eSjoerg                                         SourceLocation FilenameLoc,
47606f32e7eSjoerg                                         StringRef Filename,
47706f32e7eSjoerg                                         const FileEntry *File) {
47806f32e7eSjoerg   // No errors for indirect modules. This may be a bit of a problem for modules
47906f32e7eSjoerg   // with no source files.
48006f32e7eSjoerg   if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
48106f32e7eSjoerg     return;
48206f32e7eSjoerg 
48306f32e7eSjoerg   if (RequestingModule) {
48406f32e7eSjoerg     resolveUses(RequestingModule, /*Complain=*/false);
48506f32e7eSjoerg     resolveHeaderDirectives(RequestingModule);
48606f32e7eSjoerg   }
48706f32e7eSjoerg 
48806f32e7eSjoerg   bool Excluded = false;
48906f32e7eSjoerg   Module *Private = nullptr;
49006f32e7eSjoerg   Module *NotUsed = nullptr;
49106f32e7eSjoerg 
49206f32e7eSjoerg   HeadersMap::iterator Known = findKnownHeader(File);
49306f32e7eSjoerg   if (Known != Headers.end()) {
49406f32e7eSjoerg     for (const KnownHeader &Header : Known->second) {
49506f32e7eSjoerg       // Remember private headers for later printing of a diagnostic.
49606f32e7eSjoerg       if (violatesPrivateInclude(RequestingModule, File, Header)) {
49706f32e7eSjoerg         Private = Header.getModule();
49806f32e7eSjoerg         continue;
49906f32e7eSjoerg       }
50006f32e7eSjoerg 
50106f32e7eSjoerg       // If uses need to be specified explicitly, we are only allowed to return
50206f32e7eSjoerg       // modules that are explicitly used by the requesting module.
50306f32e7eSjoerg       if (RequestingModule && LangOpts.ModulesDeclUse &&
50406f32e7eSjoerg           !RequestingModule->directlyUses(Header.getModule())) {
50506f32e7eSjoerg         NotUsed = Header.getModule();
50606f32e7eSjoerg         continue;
50706f32e7eSjoerg       }
50806f32e7eSjoerg 
50906f32e7eSjoerg       // We have found a module that we can happily use.
51006f32e7eSjoerg       return;
51106f32e7eSjoerg     }
51206f32e7eSjoerg 
51306f32e7eSjoerg     Excluded = true;
51406f32e7eSjoerg   }
51506f32e7eSjoerg 
51606f32e7eSjoerg   // We have found a header, but it is private.
51706f32e7eSjoerg   if (Private) {
51806f32e7eSjoerg     Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
51906f32e7eSjoerg         << Filename;
52006f32e7eSjoerg     return;
52106f32e7eSjoerg   }
52206f32e7eSjoerg 
52306f32e7eSjoerg   // We have found a module, but we don't use it.
52406f32e7eSjoerg   if (NotUsed) {
52506f32e7eSjoerg     Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
52606f32e7eSjoerg         << RequestingModule->getTopLevelModule()->Name << Filename;
52706f32e7eSjoerg     return;
52806f32e7eSjoerg   }
52906f32e7eSjoerg 
53006f32e7eSjoerg   if (Excluded || isHeaderInUmbrellaDirs(File))
53106f32e7eSjoerg     return;
53206f32e7eSjoerg 
53306f32e7eSjoerg   // At this point, only non-modular includes remain.
53406f32e7eSjoerg 
53506f32e7eSjoerg   if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
53606f32e7eSjoerg     Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
53706f32e7eSjoerg         << RequestingModule->getTopLevelModule()->Name << Filename;
53806f32e7eSjoerg   } else if (RequestingModule && RequestingModuleIsModuleInterface &&
53906f32e7eSjoerg              LangOpts.isCompilingModule()) {
54006f32e7eSjoerg     // Do not diagnose when we are not compiling a module.
54106f32e7eSjoerg     diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
54206f32e7eSjoerg         diag::warn_non_modular_include_in_framework_module :
54306f32e7eSjoerg         diag::warn_non_modular_include_in_module;
54406f32e7eSjoerg     Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
54506f32e7eSjoerg         << File->getName();
54606f32e7eSjoerg   }
54706f32e7eSjoerg }
54806f32e7eSjoerg 
isBetterKnownHeader(const ModuleMap::KnownHeader & New,const ModuleMap::KnownHeader & Old)54906f32e7eSjoerg static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
55006f32e7eSjoerg                                 const ModuleMap::KnownHeader &Old) {
55106f32e7eSjoerg   // Prefer available modules.
552*13fbcb42Sjoerg   // FIXME: Considering whether the module is available rather than merely
553*13fbcb42Sjoerg   // importable is non-hermetic and can result in surprising behavior for
554*13fbcb42Sjoerg   // prebuilt modules. Consider only checking for importability here.
55506f32e7eSjoerg   if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
55606f32e7eSjoerg     return true;
55706f32e7eSjoerg 
55806f32e7eSjoerg   // Prefer a public header over a private header.
55906f32e7eSjoerg   if ((New.getRole() & ModuleMap::PrivateHeader) !=
56006f32e7eSjoerg       (Old.getRole() & ModuleMap::PrivateHeader))
56106f32e7eSjoerg     return !(New.getRole() & ModuleMap::PrivateHeader);
56206f32e7eSjoerg 
56306f32e7eSjoerg   // Prefer a non-textual header over a textual header.
56406f32e7eSjoerg   if ((New.getRole() & ModuleMap::TextualHeader) !=
56506f32e7eSjoerg       (Old.getRole() & ModuleMap::TextualHeader))
56606f32e7eSjoerg     return !(New.getRole() & ModuleMap::TextualHeader);
56706f32e7eSjoerg 
56806f32e7eSjoerg   // Don't have a reason to choose between these. Just keep the first one.
56906f32e7eSjoerg   return false;
57006f32e7eSjoerg }
57106f32e7eSjoerg 
findModuleForHeader(const FileEntry * File,bool AllowTextual)57206f32e7eSjoerg ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File,
57306f32e7eSjoerg                                                       bool AllowTextual) {
57406f32e7eSjoerg   auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
57506f32e7eSjoerg     if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
57606f32e7eSjoerg       return {};
57706f32e7eSjoerg     return R;
57806f32e7eSjoerg   };
57906f32e7eSjoerg 
58006f32e7eSjoerg   HeadersMap::iterator Known = findKnownHeader(File);
58106f32e7eSjoerg   if (Known != Headers.end()) {
58206f32e7eSjoerg     ModuleMap::KnownHeader Result;
58306f32e7eSjoerg     // Iterate over all modules that 'File' is part of to find the best fit.
58406f32e7eSjoerg     for (KnownHeader &H : Known->second) {
58506f32e7eSjoerg       // Prefer a header from the source module over all others.
58606f32e7eSjoerg       if (H.getModule()->getTopLevelModule() == SourceModule)
58706f32e7eSjoerg         return MakeResult(H);
58806f32e7eSjoerg       if (!Result || isBetterKnownHeader(H, Result))
58906f32e7eSjoerg         Result = H;
59006f32e7eSjoerg     }
59106f32e7eSjoerg     return MakeResult(Result);
59206f32e7eSjoerg   }
59306f32e7eSjoerg 
59406f32e7eSjoerg   return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
59506f32e7eSjoerg }
59606f32e7eSjoerg 
59706f32e7eSjoerg ModuleMap::KnownHeader
findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry * File)59806f32e7eSjoerg ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
59906f32e7eSjoerg   assert(!Headers.count(File) && "already have a module for this header");
60006f32e7eSjoerg 
60106f32e7eSjoerg   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
60206f32e7eSjoerg   KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
60306f32e7eSjoerg   if (H) {
60406f32e7eSjoerg     Module *Result = H.getModule();
60506f32e7eSjoerg 
60606f32e7eSjoerg     // Search up the module stack until we find a module with an umbrella
60706f32e7eSjoerg     // directory.
60806f32e7eSjoerg     Module *UmbrellaModule = Result;
60906f32e7eSjoerg     while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
61006f32e7eSjoerg       UmbrellaModule = UmbrellaModule->Parent;
61106f32e7eSjoerg 
61206f32e7eSjoerg     if (UmbrellaModule->InferSubmodules) {
61306f32e7eSjoerg       const FileEntry *UmbrellaModuleMap =
61406f32e7eSjoerg           getModuleMapFileForUniquing(UmbrellaModule);
61506f32e7eSjoerg 
61606f32e7eSjoerg       // Infer submodules for each of the directories we found between
61706f32e7eSjoerg       // the directory of the umbrella header and the directory where
61806f32e7eSjoerg       // the actual header is located.
61906f32e7eSjoerg       bool Explicit = UmbrellaModule->InferExplicitSubmodules;
62006f32e7eSjoerg 
62106f32e7eSjoerg       for (unsigned I = SkippedDirs.size(); I != 0; --I) {
62206f32e7eSjoerg         // Find or create the module that corresponds to this directory name.
62306f32e7eSjoerg         SmallString<32> NameBuf;
62406f32e7eSjoerg         StringRef Name = sanitizeFilenameAsIdentifier(
62506f32e7eSjoerg             llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
62606f32e7eSjoerg         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
62706f32e7eSjoerg                                     Explicit).first;
62806f32e7eSjoerg         InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
62906f32e7eSjoerg         Result->IsInferred = true;
63006f32e7eSjoerg 
63106f32e7eSjoerg         // Associate the module and the directory.
63206f32e7eSjoerg         UmbrellaDirs[SkippedDirs[I-1]] = Result;
63306f32e7eSjoerg 
63406f32e7eSjoerg         // If inferred submodules export everything they import, add a
63506f32e7eSjoerg         // wildcard to the set of exports.
63606f32e7eSjoerg         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
63706f32e7eSjoerg           Result->Exports.push_back(Module::ExportDecl(nullptr, true));
63806f32e7eSjoerg       }
63906f32e7eSjoerg 
64006f32e7eSjoerg       // Infer a submodule with the same name as this header file.
64106f32e7eSjoerg       SmallString<32> NameBuf;
64206f32e7eSjoerg       StringRef Name = sanitizeFilenameAsIdentifier(
64306f32e7eSjoerg                          llvm::sys::path::stem(File->getName()), NameBuf);
64406f32e7eSjoerg       Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
64506f32e7eSjoerg                                   Explicit).first;
64606f32e7eSjoerg       InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
64706f32e7eSjoerg       Result->IsInferred = true;
64806f32e7eSjoerg       Result->addTopHeader(File);
64906f32e7eSjoerg 
65006f32e7eSjoerg       // If inferred submodules export everything they import, add a
65106f32e7eSjoerg       // wildcard to the set of exports.
65206f32e7eSjoerg       if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
65306f32e7eSjoerg         Result->Exports.push_back(Module::ExportDecl(nullptr, true));
65406f32e7eSjoerg     } else {
65506f32e7eSjoerg       // Record each of the directories we stepped through as being part of
65606f32e7eSjoerg       // the module we found, since the umbrella header covers them all.
65706f32e7eSjoerg       for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
65806f32e7eSjoerg         UmbrellaDirs[SkippedDirs[I]] = Result;
65906f32e7eSjoerg     }
66006f32e7eSjoerg 
66106f32e7eSjoerg     KnownHeader Header(Result, NormalHeader);
66206f32e7eSjoerg     Headers[File].push_back(Header);
66306f32e7eSjoerg     return Header;
66406f32e7eSjoerg   }
66506f32e7eSjoerg 
66606f32e7eSjoerg   return {};
66706f32e7eSjoerg }
66806f32e7eSjoerg 
66906f32e7eSjoerg ArrayRef<ModuleMap::KnownHeader>
findAllModulesForHeader(const FileEntry * File)670*13fbcb42Sjoerg ModuleMap::findAllModulesForHeader(const FileEntry *File) {
671*13fbcb42Sjoerg   HeadersMap::iterator Known = findKnownHeader(File);
672*13fbcb42Sjoerg   if (Known != Headers.end())
673*13fbcb42Sjoerg     return Known->second;
674*13fbcb42Sjoerg 
675*13fbcb42Sjoerg   if (findOrCreateModuleForHeaderInUmbrellaDir(File))
676*13fbcb42Sjoerg     return Headers.find(File)->second;
677*13fbcb42Sjoerg 
678*13fbcb42Sjoerg   return None;
679*13fbcb42Sjoerg }
680*13fbcb42Sjoerg 
681*13fbcb42Sjoerg ArrayRef<ModuleMap::KnownHeader>
findResolvedModulesForHeader(const FileEntry * File) const682*13fbcb42Sjoerg ModuleMap::findResolvedModulesForHeader(const FileEntry *File) const {
683*13fbcb42Sjoerg   // FIXME: Is this necessary?
68406f32e7eSjoerg   resolveHeaderDirectives(File);
68506f32e7eSjoerg   auto It = Headers.find(File);
68606f32e7eSjoerg   if (It == Headers.end())
68706f32e7eSjoerg     return None;
68806f32e7eSjoerg   return It->second;
68906f32e7eSjoerg }
69006f32e7eSjoerg 
isHeaderInUnavailableModule(const FileEntry * Header) const69106f32e7eSjoerg bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
69206f32e7eSjoerg   return isHeaderUnavailableInModule(Header, nullptr);
69306f32e7eSjoerg }
69406f32e7eSjoerg 
69506f32e7eSjoerg bool
isHeaderUnavailableInModule(const FileEntry * Header,const Module * RequestingModule) const69606f32e7eSjoerg ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
69706f32e7eSjoerg                                        const Module *RequestingModule) const {
69806f32e7eSjoerg   resolveHeaderDirectives(Header);
69906f32e7eSjoerg   HeadersMap::const_iterator Known = Headers.find(Header);
70006f32e7eSjoerg   if (Known != Headers.end()) {
70106f32e7eSjoerg     for (SmallVectorImpl<KnownHeader>::const_iterator
70206f32e7eSjoerg              I = Known->second.begin(),
70306f32e7eSjoerg              E = Known->second.end();
70406f32e7eSjoerg          I != E; ++I) {
70506f32e7eSjoerg 
70606f32e7eSjoerg       if (I->isAvailable() &&
70706f32e7eSjoerg           (!RequestingModule ||
70806f32e7eSjoerg            I->getModule()->isSubModuleOf(RequestingModule))) {
70906f32e7eSjoerg         // When no requesting module is available, the caller is looking if a
71006f32e7eSjoerg         // header is part a module by only looking into the module map. This is
71106f32e7eSjoerg         // done by warn_uncovered_module_header checks; don't consider textual
71206f32e7eSjoerg         // headers part of it in this mode, otherwise we get misleading warnings
71306f32e7eSjoerg         // that a umbrella header is not including a textual header.
71406f32e7eSjoerg         if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
71506f32e7eSjoerg           continue;
71606f32e7eSjoerg         return false;
71706f32e7eSjoerg       }
71806f32e7eSjoerg     }
71906f32e7eSjoerg     return true;
72006f32e7eSjoerg   }
72106f32e7eSjoerg 
72206f32e7eSjoerg   const DirectoryEntry *Dir = Header->getDir();
72306f32e7eSjoerg   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
72406f32e7eSjoerg   StringRef DirName = Dir->getName();
72506f32e7eSjoerg 
72606f32e7eSjoerg   auto IsUnavailable = [&](const Module *M) {
72706f32e7eSjoerg     return !M->isAvailable() && (!RequestingModule ||
72806f32e7eSjoerg                                  M->isSubModuleOf(RequestingModule));
72906f32e7eSjoerg   };
73006f32e7eSjoerg 
73106f32e7eSjoerg   // Keep walking up the directory hierarchy, looking for a directory with
73206f32e7eSjoerg   // an umbrella header.
73306f32e7eSjoerg   do {
73406f32e7eSjoerg     llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
73506f32e7eSjoerg       = UmbrellaDirs.find(Dir);
73606f32e7eSjoerg     if (KnownDir != UmbrellaDirs.end()) {
73706f32e7eSjoerg       Module *Found = KnownDir->second;
73806f32e7eSjoerg       if (IsUnavailable(Found))
73906f32e7eSjoerg         return true;
74006f32e7eSjoerg 
74106f32e7eSjoerg       // Search up the module stack until we find a module with an umbrella
74206f32e7eSjoerg       // directory.
74306f32e7eSjoerg       Module *UmbrellaModule = Found;
74406f32e7eSjoerg       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
74506f32e7eSjoerg         UmbrellaModule = UmbrellaModule->Parent;
74606f32e7eSjoerg 
74706f32e7eSjoerg       if (UmbrellaModule->InferSubmodules) {
74806f32e7eSjoerg         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
74906f32e7eSjoerg           // Find or create the module that corresponds to this directory name.
75006f32e7eSjoerg           SmallString<32> NameBuf;
75106f32e7eSjoerg           StringRef Name = sanitizeFilenameAsIdentifier(
75206f32e7eSjoerg                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
75306f32e7eSjoerg                              NameBuf);
75406f32e7eSjoerg           Found = lookupModuleQualified(Name, Found);
75506f32e7eSjoerg           if (!Found)
75606f32e7eSjoerg             return false;
75706f32e7eSjoerg           if (IsUnavailable(Found))
75806f32e7eSjoerg             return true;
75906f32e7eSjoerg         }
76006f32e7eSjoerg 
76106f32e7eSjoerg         // Infer a submodule with the same name as this header file.
76206f32e7eSjoerg         SmallString<32> NameBuf;
76306f32e7eSjoerg         StringRef Name = sanitizeFilenameAsIdentifier(
76406f32e7eSjoerg                            llvm::sys::path::stem(Header->getName()),
76506f32e7eSjoerg                            NameBuf);
76606f32e7eSjoerg         Found = lookupModuleQualified(Name, Found);
76706f32e7eSjoerg         if (!Found)
76806f32e7eSjoerg           return false;
76906f32e7eSjoerg       }
77006f32e7eSjoerg 
77106f32e7eSjoerg       return IsUnavailable(Found);
77206f32e7eSjoerg     }
77306f32e7eSjoerg 
77406f32e7eSjoerg     SkippedDirs.push_back(Dir);
77506f32e7eSjoerg 
77606f32e7eSjoerg     // Retrieve our parent path.
77706f32e7eSjoerg     DirName = llvm::sys::path::parent_path(DirName);
77806f32e7eSjoerg     if (DirName.empty())
77906f32e7eSjoerg       break;
78006f32e7eSjoerg 
78106f32e7eSjoerg     // Resolve the parent path to a directory entry.
78206f32e7eSjoerg     if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName))
78306f32e7eSjoerg       Dir = *DirEntry;
78406f32e7eSjoerg     else
78506f32e7eSjoerg       Dir = nullptr;
78606f32e7eSjoerg   } while (Dir);
78706f32e7eSjoerg 
78806f32e7eSjoerg   return false;
78906f32e7eSjoerg }
79006f32e7eSjoerg 
findModule(StringRef Name) const79106f32e7eSjoerg Module *ModuleMap::findModule(StringRef Name) const {
79206f32e7eSjoerg   llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
79306f32e7eSjoerg   if (Known != Modules.end())
79406f32e7eSjoerg     return Known->getValue();
79506f32e7eSjoerg 
79606f32e7eSjoerg   return nullptr;
79706f32e7eSjoerg }
79806f32e7eSjoerg 
lookupModuleUnqualified(StringRef Name,Module * Context) const79906f32e7eSjoerg Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
80006f32e7eSjoerg                                            Module *Context) const {
80106f32e7eSjoerg   for(; Context; Context = Context->Parent) {
80206f32e7eSjoerg     if (Module *Sub = lookupModuleQualified(Name, Context))
80306f32e7eSjoerg       return Sub;
80406f32e7eSjoerg   }
80506f32e7eSjoerg 
80606f32e7eSjoerg   return findModule(Name);
80706f32e7eSjoerg }
80806f32e7eSjoerg 
lookupModuleQualified(StringRef Name,Module * Context) const80906f32e7eSjoerg Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
81006f32e7eSjoerg   if (!Context)
81106f32e7eSjoerg     return findModule(Name);
81206f32e7eSjoerg 
81306f32e7eSjoerg   return Context->findSubmodule(Name);
81406f32e7eSjoerg }
81506f32e7eSjoerg 
findOrCreateModule(StringRef Name,Module * Parent,bool IsFramework,bool IsExplicit)81606f32e7eSjoerg std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
81706f32e7eSjoerg                                                         Module *Parent,
81806f32e7eSjoerg                                                         bool IsFramework,
81906f32e7eSjoerg                                                         bool IsExplicit) {
82006f32e7eSjoerg   // Try to find an existing module with this name.
82106f32e7eSjoerg   if (Module *Sub = lookupModuleQualified(Name, Parent))
82206f32e7eSjoerg     return std::make_pair(Sub, false);
82306f32e7eSjoerg 
82406f32e7eSjoerg   // Create a new module with this name.
82506f32e7eSjoerg   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
82606f32e7eSjoerg                               IsExplicit, NumCreatedModules++);
82706f32e7eSjoerg   if (!Parent) {
82806f32e7eSjoerg     if (LangOpts.CurrentModule == Name)
82906f32e7eSjoerg       SourceModule = Result;
83006f32e7eSjoerg     Modules[Name] = Result;
83106f32e7eSjoerg     ModuleScopeIDs[Result] = CurrentModuleScopeID;
83206f32e7eSjoerg   }
83306f32e7eSjoerg   return std::make_pair(Result, true);
83406f32e7eSjoerg }
83506f32e7eSjoerg 
createGlobalModuleFragmentForModuleUnit(SourceLocation Loc)83606f32e7eSjoerg Module *ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc) {
83706f32e7eSjoerg   PendingSubmodules.emplace_back(
83806f32e7eSjoerg       new Module("<global>", Loc, nullptr, /*IsFramework*/ false,
83906f32e7eSjoerg                  /*IsExplicit*/ true, NumCreatedModules++));
84006f32e7eSjoerg   PendingSubmodules.back()->Kind = Module::GlobalModuleFragment;
84106f32e7eSjoerg   return PendingSubmodules.back().get();
84206f32e7eSjoerg }
84306f32e7eSjoerg 
84406f32e7eSjoerg Module *
createPrivateModuleFragmentForInterfaceUnit(Module * Parent,SourceLocation Loc)84506f32e7eSjoerg ModuleMap::createPrivateModuleFragmentForInterfaceUnit(Module *Parent,
84606f32e7eSjoerg                                                        SourceLocation Loc) {
84706f32e7eSjoerg   auto *Result =
84806f32e7eSjoerg       new Module("<private>", Loc, Parent, /*IsFramework*/ false,
84906f32e7eSjoerg                  /*IsExplicit*/ true, NumCreatedModules++);
85006f32e7eSjoerg   Result->Kind = Module::PrivateModuleFragment;
85106f32e7eSjoerg   return Result;
85206f32e7eSjoerg }
85306f32e7eSjoerg 
createModuleForInterfaceUnit(SourceLocation Loc,StringRef Name,Module * GlobalModule)85406f32e7eSjoerg Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
85506f32e7eSjoerg                                                 StringRef Name,
85606f32e7eSjoerg                                                 Module *GlobalModule) {
85706f32e7eSjoerg   assert(LangOpts.CurrentModule == Name && "module name mismatch");
85806f32e7eSjoerg   assert(!Modules[Name] && "redefining existing module");
85906f32e7eSjoerg 
86006f32e7eSjoerg   auto *Result =
86106f32e7eSjoerg       new Module(Name, Loc, nullptr, /*IsFramework*/ false,
86206f32e7eSjoerg                  /*IsExplicit*/ false, NumCreatedModules++);
86306f32e7eSjoerg   Result->Kind = Module::ModuleInterfaceUnit;
86406f32e7eSjoerg   Modules[Name] = SourceModule = Result;
86506f32e7eSjoerg 
86606f32e7eSjoerg   // Reparent the current global module fragment as a submodule of this module.
86706f32e7eSjoerg   for (auto &Submodule : PendingSubmodules) {
86806f32e7eSjoerg     Submodule->setParent(Result);
86906f32e7eSjoerg     Submodule.release(); // now owned by parent
87006f32e7eSjoerg   }
87106f32e7eSjoerg   PendingSubmodules.clear();
87206f32e7eSjoerg 
87306f32e7eSjoerg   // Mark the main source file as being within the newly-created module so that
87406f32e7eSjoerg   // declarations and macros are properly visibility-restricted to it.
87506f32e7eSjoerg   auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
87606f32e7eSjoerg   assert(MainFile && "no input file for module interface");
87706f32e7eSjoerg   Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
87806f32e7eSjoerg 
87906f32e7eSjoerg   return Result;
88006f32e7eSjoerg }
88106f32e7eSjoerg 
createHeaderModule(StringRef Name,ArrayRef<Module::Header> Headers)88206f32e7eSjoerg Module *ModuleMap::createHeaderModule(StringRef Name,
88306f32e7eSjoerg                                       ArrayRef<Module::Header> Headers) {
88406f32e7eSjoerg   assert(LangOpts.CurrentModule == Name && "module name mismatch");
88506f32e7eSjoerg   assert(!Modules[Name] && "redefining existing module");
88606f32e7eSjoerg 
88706f32e7eSjoerg   auto *Result =
88806f32e7eSjoerg       new Module(Name, SourceLocation(), nullptr, /*IsFramework*/ false,
88906f32e7eSjoerg                  /*IsExplicit*/ false, NumCreatedModules++);
89006f32e7eSjoerg   Result->Kind = Module::ModuleInterfaceUnit;
89106f32e7eSjoerg   Modules[Name] = SourceModule = Result;
89206f32e7eSjoerg 
89306f32e7eSjoerg   for (const Module::Header &H : Headers) {
89406f32e7eSjoerg     auto *M = new Module(H.NameAsWritten, SourceLocation(), Result,
89506f32e7eSjoerg                          /*IsFramework*/ false,
89606f32e7eSjoerg                          /*IsExplicit*/ true, NumCreatedModules++);
89706f32e7eSjoerg     // Header modules are implicitly 'export *'.
89806f32e7eSjoerg     M->Exports.push_back(Module::ExportDecl(nullptr, true));
89906f32e7eSjoerg     addHeader(M, H, NormalHeader);
90006f32e7eSjoerg   }
90106f32e7eSjoerg 
90206f32e7eSjoerg   return Result;
90306f32e7eSjoerg }
90406f32e7eSjoerg 
90506f32e7eSjoerg /// For a framework module, infer the framework against which we
90606f32e7eSjoerg /// should link.
inferFrameworkLink(Module * Mod,const DirectoryEntry * FrameworkDir,FileManager & FileMgr)90706f32e7eSjoerg static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
90806f32e7eSjoerg                                FileManager &FileMgr) {
90906f32e7eSjoerg   assert(Mod->IsFramework && "Can only infer linking for framework modules");
91006f32e7eSjoerg   assert(!Mod->isSubFramework() &&
91106f32e7eSjoerg          "Can only infer linking for top-level frameworks");
91206f32e7eSjoerg 
91306f32e7eSjoerg   SmallString<128> LibName;
91406f32e7eSjoerg   LibName += FrameworkDir->getName();
91506f32e7eSjoerg   llvm::sys::path::append(LibName, Mod->Name);
91606f32e7eSjoerg 
91706f32e7eSjoerg   // The library name of a framework has more than one possible extension since
91806f32e7eSjoerg   // the introduction of the text-based dynamic library format. We need to check
91906f32e7eSjoerg   // for both before we give up.
92006f32e7eSjoerg   for (const char *extension : {"", ".tbd"}) {
92106f32e7eSjoerg     llvm::sys::path::replace_extension(LibName, extension);
92206f32e7eSjoerg     if (FileMgr.getFile(LibName)) {
92306f32e7eSjoerg       Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
92406f32e7eSjoerg                                                        /*IsFramework=*/true));
92506f32e7eSjoerg       return;
92606f32e7eSjoerg     }
92706f32e7eSjoerg   }
92806f32e7eSjoerg }
92906f32e7eSjoerg 
inferFrameworkModule(const DirectoryEntry * FrameworkDir,bool IsSystem,Module * Parent)93006f32e7eSjoerg Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
93106f32e7eSjoerg                                         bool IsSystem, Module *Parent) {
93206f32e7eSjoerg   Attributes Attrs;
93306f32e7eSjoerg   Attrs.IsSystem = IsSystem;
93406f32e7eSjoerg   return inferFrameworkModule(FrameworkDir, Attrs, Parent);
93506f32e7eSjoerg }
93606f32e7eSjoerg 
inferFrameworkModule(const DirectoryEntry * FrameworkDir,Attributes Attrs,Module * Parent)93706f32e7eSjoerg Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
93806f32e7eSjoerg                                         Attributes Attrs, Module *Parent) {
93906f32e7eSjoerg   // Note: as an egregious but useful hack we use the real path here, because
94006f32e7eSjoerg   // we might be looking at an embedded framework that symlinks out to a
94106f32e7eSjoerg   // top-level framework, and we need to infer as if we were naming the
94206f32e7eSjoerg   // top-level framework.
94306f32e7eSjoerg   StringRef FrameworkDirName =
94406f32e7eSjoerg       SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
94506f32e7eSjoerg 
94606f32e7eSjoerg   // In case this is a case-insensitive filesystem, use the canonical
94706f32e7eSjoerg   // directory name as the ModuleName, since modules are case-sensitive.
94806f32e7eSjoerg   // FIXME: we should be able to give a fix-it hint for the correct spelling.
94906f32e7eSjoerg   SmallString<32> ModuleNameStorage;
95006f32e7eSjoerg   StringRef ModuleName = sanitizeFilenameAsIdentifier(
95106f32e7eSjoerg       llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
95206f32e7eSjoerg 
95306f32e7eSjoerg   // Check whether we've already found this module.
95406f32e7eSjoerg   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
95506f32e7eSjoerg     return Mod;
95606f32e7eSjoerg 
95706f32e7eSjoerg   FileManager &FileMgr = SourceMgr.getFileManager();
95806f32e7eSjoerg 
95906f32e7eSjoerg   // If the framework has a parent path from which we're allowed to infer
96006f32e7eSjoerg   // a framework module, do so.
96106f32e7eSjoerg   const FileEntry *ModuleMapFile = nullptr;
96206f32e7eSjoerg   if (!Parent) {
96306f32e7eSjoerg     // Determine whether we're allowed to infer a module map.
96406f32e7eSjoerg     bool canInfer = false;
96506f32e7eSjoerg     if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
96606f32e7eSjoerg       // Figure out the parent path.
96706f32e7eSjoerg       StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
96806f32e7eSjoerg       if (auto ParentDir = FileMgr.getDirectory(Parent)) {
96906f32e7eSjoerg         // Check whether we have already looked into the parent directory
97006f32e7eSjoerg         // for a module map.
97106f32e7eSjoerg         llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
97206f32e7eSjoerg           inferred = InferredDirectories.find(*ParentDir);
97306f32e7eSjoerg         if (inferred == InferredDirectories.end()) {
97406f32e7eSjoerg           // We haven't looked here before. Load a module map, if there is
97506f32e7eSjoerg           // one.
97606f32e7eSjoerg           bool IsFrameworkDir = Parent.endswith(".framework");
97706f32e7eSjoerg           if (const FileEntry *ModMapFile =
97806f32e7eSjoerg                 HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
97906f32e7eSjoerg             parseModuleMapFile(ModMapFile, Attrs.IsSystem, *ParentDir);
98006f32e7eSjoerg             inferred = InferredDirectories.find(*ParentDir);
98106f32e7eSjoerg           }
98206f32e7eSjoerg 
98306f32e7eSjoerg           if (inferred == InferredDirectories.end())
98406f32e7eSjoerg             inferred = InferredDirectories.insert(
98506f32e7eSjoerg                          std::make_pair(*ParentDir, InferredDirectory())).first;
98606f32e7eSjoerg         }
98706f32e7eSjoerg 
98806f32e7eSjoerg         if (inferred->second.InferModules) {
98906f32e7eSjoerg           // We're allowed to infer for this directory, but make sure it's okay
99006f32e7eSjoerg           // to infer this particular module.
99106f32e7eSjoerg           StringRef Name = llvm::sys::path::stem(FrameworkDirName);
99206f32e7eSjoerg           canInfer = std::find(inferred->second.ExcludedModules.begin(),
99306f32e7eSjoerg                                inferred->second.ExcludedModules.end(),
99406f32e7eSjoerg                                Name) == inferred->second.ExcludedModules.end();
99506f32e7eSjoerg 
99606f32e7eSjoerg           Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
99706f32e7eSjoerg           Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
99806f32e7eSjoerg           Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
99906f32e7eSjoerg           Attrs.NoUndeclaredIncludes |=
100006f32e7eSjoerg               inferred->second.Attrs.NoUndeclaredIncludes;
100106f32e7eSjoerg           ModuleMapFile = inferred->second.ModuleMapFile;
100206f32e7eSjoerg         }
100306f32e7eSjoerg       }
100406f32e7eSjoerg     }
100506f32e7eSjoerg 
100606f32e7eSjoerg     // If we're not allowed to infer a framework module, don't.
100706f32e7eSjoerg     if (!canInfer)
100806f32e7eSjoerg       return nullptr;
100906f32e7eSjoerg   } else
101006f32e7eSjoerg     ModuleMapFile = getModuleMapFileForUniquing(Parent);
101106f32e7eSjoerg 
101206f32e7eSjoerg 
101306f32e7eSjoerg   // Look for an umbrella header.
101406f32e7eSjoerg   SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
101506f32e7eSjoerg   llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
101606f32e7eSjoerg   auto UmbrellaHeader = FileMgr.getFile(UmbrellaName);
101706f32e7eSjoerg 
101806f32e7eSjoerg   // FIXME: If there's no umbrella header, we could probably scan the
101906f32e7eSjoerg   // framework to load *everything*. But, it's not clear that this is a good
102006f32e7eSjoerg   // idea.
102106f32e7eSjoerg   if (!UmbrellaHeader)
102206f32e7eSjoerg     return nullptr;
102306f32e7eSjoerg 
102406f32e7eSjoerg   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
102506f32e7eSjoerg                               /*IsFramework=*/true, /*IsExplicit=*/false,
102606f32e7eSjoerg                               NumCreatedModules++);
102706f32e7eSjoerg   InferredModuleAllowedBy[Result] = ModuleMapFile;
102806f32e7eSjoerg   Result->IsInferred = true;
102906f32e7eSjoerg   if (!Parent) {
103006f32e7eSjoerg     if (LangOpts.CurrentModule == ModuleName)
103106f32e7eSjoerg       SourceModule = Result;
103206f32e7eSjoerg     Modules[ModuleName] = Result;
103306f32e7eSjoerg     ModuleScopeIDs[Result] = CurrentModuleScopeID;
103406f32e7eSjoerg   }
103506f32e7eSjoerg 
103606f32e7eSjoerg   Result->IsSystem |= Attrs.IsSystem;
103706f32e7eSjoerg   Result->IsExternC |= Attrs.IsExternC;
103806f32e7eSjoerg   Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
103906f32e7eSjoerg   Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
104006f32e7eSjoerg   Result->Directory = FrameworkDir;
104106f32e7eSjoerg 
1042*13fbcb42Sjoerg   // Chop off the first framework bit, as that is implied.
1043*13fbcb42Sjoerg   StringRef RelativePath = UmbrellaName.str().substr(
1044*13fbcb42Sjoerg       Result->getTopLevelModule()->Directory->getName().size());
1045*13fbcb42Sjoerg   RelativePath = llvm::sys::path::relative_path(RelativePath);
1046*13fbcb42Sjoerg 
104706f32e7eSjoerg   // umbrella header "umbrella-header-name"
1048*13fbcb42Sjoerg   setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h", RelativePath);
104906f32e7eSjoerg 
105006f32e7eSjoerg   // export *
105106f32e7eSjoerg   Result->Exports.push_back(Module::ExportDecl(nullptr, true));
105206f32e7eSjoerg 
105306f32e7eSjoerg   // module * { export * }
105406f32e7eSjoerg   Result->InferSubmodules = true;
105506f32e7eSjoerg   Result->InferExportWildcard = true;
105606f32e7eSjoerg 
105706f32e7eSjoerg   // Look for subframeworks.
105806f32e7eSjoerg   std::error_code EC;
105906f32e7eSjoerg   SmallString<128> SubframeworksDirName
106006f32e7eSjoerg     = StringRef(FrameworkDir->getName());
106106f32e7eSjoerg   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
106206f32e7eSjoerg   llvm::sys::path::native(SubframeworksDirName);
106306f32e7eSjoerg   llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
106406f32e7eSjoerg   for (llvm::vfs::directory_iterator
106506f32e7eSjoerg            Dir = FS.dir_begin(SubframeworksDirName, EC),
106606f32e7eSjoerg            DirEnd;
106706f32e7eSjoerg        Dir != DirEnd && !EC; Dir.increment(EC)) {
106806f32e7eSjoerg     if (!StringRef(Dir->path()).endswith(".framework"))
106906f32e7eSjoerg       continue;
107006f32e7eSjoerg 
107106f32e7eSjoerg     if (auto SubframeworkDir =
107206f32e7eSjoerg             FileMgr.getDirectory(Dir->path())) {
107306f32e7eSjoerg       // Note: as an egregious but useful hack, we use the real path here and
107406f32e7eSjoerg       // check whether it is actually a subdirectory of the parent directory.
107506f32e7eSjoerg       // This will not be the case if the 'subframework' is actually a symlink
107606f32e7eSjoerg       // out to a top-level framework.
107706f32e7eSjoerg       StringRef SubframeworkDirName =
107806f32e7eSjoerg           FileMgr.getCanonicalName(*SubframeworkDir);
107906f32e7eSjoerg       bool FoundParent = false;
108006f32e7eSjoerg       do {
108106f32e7eSjoerg         // Get the parent directory name.
108206f32e7eSjoerg         SubframeworkDirName
108306f32e7eSjoerg           = llvm::sys::path::parent_path(SubframeworkDirName);
108406f32e7eSjoerg         if (SubframeworkDirName.empty())
108506f32e7eSjoerg           break;
108606f32e7eSjoerg 
108706f32e7eSjoerg         if (auto SubDir = FileMgr.getDirectory(SubframeworkDirName)) {
108806f32e7eSjoerg           if (*SubDir == FrameworkDir) {
108906f32e7eSjoerg             FoundParent = true;
109006f32e7eSjoerg             break;
109106f32e7eSjoerg           }
109206f32e7eSjoerg         }
109306f32e7eSjoerg       } while (true);
109406f32e7eSjoerg 
109506f32e7eSjoerg       if (!FoundParent)
109606f32e7eSjoerg         continue;
109706f32e7eSjoerg 
109806f32e7eSjoerg       // FIXME: Do we want to warn about subframeworks without umbrella headers?
109906f32e7eSjoerg       inferFrameworkModule(*SubframeworkDir, Attrs, Result);
110006f32e7eSjoerg     }
110106f32e7eSjoerg   }
110206f32e7eSjoerg 
110306f32e7eSjoerg   // If the module is a top-level framework, automatically link against the
110406f32e7eSjoerg   // framework.
110506f32e7eSjoerg   if (!Result->isSubFramework()) {
110606f32e7eSjoerg     inferFrameworkLink(Result, FrameworkDir, FileMgr);
110706f32e7eSjoerg   }
110806f32e7eSjoerg 
110906f32e7eSjoerg   return Result;
111006f32e7eSjoerg }
111106f32e7eSjoerg 
createShadowedModule(StringRef Name,bool IsFramework,Module * ShadowingModule)111206f32e7eSjoerg Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
111306f32e7eSjoerg                                         Module *ShadowingModule) {
111406f32e7eSjoerg 
111506f32e7eSjoerg   // Create a new module with this name.
111606f32e7eSjoerg   Module *Result =
111706f32e7eSjoerg       new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework,
111806f32e7eSjoerg                  /*IsExplicit=*/false, NumCreatedModules++);
111906f32e7eSjoerg   Result->ShadowingModule = ShadowingModule;
1120*13fbcb42Sjoerg   Result->markUnavailable(/*Unimportable*/true);
112106f32e7eSjoerg   ModuleScopeIDs[Result] = CurrentModuleScopeID;
112206f32e7eSjoerg   ShadowModules.push_back(Result);
112306f32e7eSjoerg 
112406f32e7eSjoerg   return Result;
112506f32e7eSjoerg }
112606f32e7eSjoerg 
setUmbrellaHeader(Module * Mod,const FileEntry * UmbrellaHeader,const Twine & NameAsWritten,const Twine & PathRelativeToRootModuleDirectory)1127*13fbcb42Sjoerg void ModuleMap::setUmbrellaHeader(
1128*13fbcb42Sjoerg     Module *Mod, const FileEntry *UmbrellaHeader, const Twine &NameAsWritten,
1129*13fbcb42Sjoerg     const Twine &PathRelativeToRootModuleDirectory) {
113006f32e7eSjoerg   Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
113106f32e7eSjoerg   Mod->Umbrella = UmbrellaHeader;
113206f32e7eSjoerg   Mod->UmbrellaAsWritten = NameAsWritten.str();
1133*13fbcb42Sjoerg   Mod->UmbrellaRelativeToRootModuleDirectory =
1134*13fbcb42Sjoerg       PathRelativeToRootModuleDirectory.str();
113506f32e7eSjoerg   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
113606f32e7eSjoerg 
113706f32e7eSjoerg   // Notify callbacks that we just added a new header.
113806f32e7eSjoerg   for (const auto &Cb : Callbacks)
113906f32e7eSjoerg     Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
114006f32e7eSjoerg }
114106f32e7eSjoerg 
setUmbrellaDir(Module * Mod,const DirectoryEntry * UmbrellaDir,const Twine & NameAsWritten,const Twine & PathRelativeToRootModuleDirectory)114206f32e7eSjoerg void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
1143*13fbcb42Sjoerg                                const Twine &NameAsWritten,
1144*13fbcb42Sjoerg                                const Twine &PathRelativeToRootModuleDirectory) {
114506f32e7eSjoerg   Mod->Umbrella = UmbrellaDir;
114606f32e7eSjoerg   Mod->UmbrellaAsWritten = NameAsWritten.str();
1147*13fbcb42Sjoerg   Mod->UmbrellaRelativeToRootModuleDirectory =
1148*13fbcb42Sjoerg       PathRelativeToRootModuleDirectory.str();
114906f32e7eSjoerg   UmbrellaDirs[UmbrellaDir] = Mod;
115006f32e7eSjoerg }
115106f32e7eSjoerg 
addUnresolvedHeader(Module * Mod,Module::UnresolvedHeaderDirective Header,bool & NeedsFramework)115206f32e7eSjoerg void ModuleMap::addUnresolvedHeader(Module *Mod,
115306f32e7eSjoerg                                     Module::UnresolvedHeaderDirective Header,
115406f32e7eSjoerg                                     bool &NeedsFramework) {
115506f32e7eSjoerg   // If there is a builtin counterpart to this file, add it now so it can
115606f32e7eSjoerg   // wrap the system header.
115706f32e7eSjoerg   if (resolveAsBuiltinHeader(Mod, Header)) {
115806f32e7eSjoerg     // If we have both a builtin and system version of the file, the
115906f32e7eSjoerg     // builtin version may want to inject macros into the system header, so
116006f32e7eSjoerg     // force the system header to be treated as a textual header in this
116106f32e7eSjoerg     // case.
116206f32e7eSjoerg     Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole(
116306f32e7eSjoerg         headerKindToRole(Header.Kind) | ModuleMap::TextualHeader));
116406f32e7eSjoerg     Header.HasBuiltinHeader = true;
116506f32e7eSjoerg   }
116606f32e7eSjoerg 
116706f32e7eSjoerg   // If possible, don't stat the header until we need to. This requires the
116806f32e7eSjoerg   // user to have provided us with some stat information about the file.
116906f32e7eSjoerg   // FIXME: Add support for lazily stat'ing umbrella headers and excluded
117006f32e7eSjoerg   // headers.
117106f32e7eSjoerg   if ((Header.Size || Header.ModTime) && !Header.IsUmbrella &&
117206f32e7eSjoerg       Header.Kind != Module::HK_Excluded) {
117306f32e7eSjoerg     // We expect more variation in mtime than size, so if we're given both,
117406f32e7eSjoerg     // use the mtime as the key.
117506f32e7eSjoerg     if (Header.ModTime)
117606f32e7eSjoerg       LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
117706f32e7eSjoerg     else
117806f32e7eSjoerg       LazyHeadersBySize[*Header.Size].push_back(Mod);
117906f32e7eSjoerg     Mod->UnresolvedHeaders.push_back(Header);
118006f32e7eSjoerg     return;
118106f32e7eSjoerg   }
118206f32e7eSjoerg 
118306f32e7eSjoerg   // We don't have stat information or can't defer looking this file up.
118406f32e7eSjoerg   // Perform the lookup now.
118506f32e7eSjoerg   resolveHeader(Mod, Header, NeedsFramework);
118606f32e7eSjoerg }
118706f32e7eSjoerg 
resolveHeaderDirectives(const FileEntry * File) const118806f32e7eSjoerg void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const {
118906f32e7eSjoerg   auto BySize = LazyHeadersBySize.find(File->getSize());
119006f32e7eSjoerg   if (BySize != LazyHeadersBySize.end()) {
119106f32e7eSjoerg     for (auto *M : BySize->second)
119206f32e7eSjoerg       resolveHeaderDirectives(M);
119306f32e7eSjoerg     LazyHeadersBySize.erase(BySize);
119406f32e7eSjoerg   }
119506f32e7eSjoerg 
119606f32e7eSjoerg   auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
119706f32e7eSjoerg   if (ByModTime != LazyHeadersByModTime.end()) {
119806f32e7eSjoerg     for (auto *M : ByModTime->second)
119906f32e7eSjoerg       resolveHeaderDirectives(M);
120006f32e7eSjoerg     LazyHeadersByModTime.erase(ByModTime);
120106f32e7eSjoerg   }
120206f32e7eSjoerg }
120306f32e7eSjoerg 
resolveHeaderDirectives(Module * Mod) const120406f32e7eSjoerg void ModuleMap::resolveHeaderDirectives(Module *Mod) const {
120506f32e7eSjoerg   bool NeedsFramework = false;
120606f32e7eSjoerg   for (auto &Header : Mod->UnresolvedHeaders)
120706f32e7eSjoerg     // This operation is logically const; we're just changing how we represent
120806f32e7eSjoerg     // the header information for this file.
120906f32e7eSjoerg     const_cast<ModuleMap*>(this)->resolveHeader(Mod, Header, NeedsFramework);
121006f32e7eSjoerg   Mod->UnresolvedHeaders.clear();
121106f32e7eSjoerg }
121206f32e7eSjoerg 
addHeader(Module * Mod,Module::Header Header,ModuleHeaderRole Role,bool Imported)121306f32e7eSjoerg void ModuleMap::addHeader(Module *Mod, Module::Header Header,
121406f32e7eSjoerg                           ModuleHeaderRole Role, bool Imported) {
121506f32e7eSjoerg   KnownHeader KH(Mod, Role);
121606f32e7eSjoerg 
121706f32e7eSjoerg   // Only add each header to the headers list once.
121806f32e7eSjoerg   // FIXME: Should we diagnose if a header is listed twice in the
121906f32e7eSjoerg   // same module definition?
122006f32e7eSjoerg   auto &HeaderList = Headers[Header.Entry];
122106f32e7eSjoerg   for (auto H : HeaderList)
122206f32e7eSjoerg     if (H == KH)
122306f32e7eSjoerg       return;
122406f32e7eSjoerg 
122506f32e7eSjoerg   HeaderList.push_back(KH);
122606f32e7eSjoerg   Mod->Headers[headerRoleToKind(Role)].push_back(Header);
122706f32e7eSjoerg 
122806f32e7eSjoerg   bool isCompilingModuleHeader =
122906f32e7eSjoerg       LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
123006f32e7eSjoerg   if (!Imported || isCompilingModuleHeader) {
123106f32e7eSjoerg     // When we import HeaderFileInfo, the external source is expected to
123206f32e7eSjoerg     // set the isModuleHeader flag itself.
123306f32e7eSjoerg     HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
123406f32e7eSjoerg                                     isCompilingModuleHeader);
123506f32e7eSjoerg   }
123606f32e7eSjoerg 
123706f32e7eSjoerg   // Notify callbacks that we just added a new header.
123806f32e7eSjoerg   for (const auto &Cb : Callbacks)
123906f32e7eSjoerg     Cb->moduleMapAddHeader(Header.Entry->getName());
124006f32e7eSjoerg }
124106f32e7eSjoerg 
excludeHeader(Module * Mod,Module::Header Header)124206f32e7eSjoerg void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
124306f32e7eSjoerg   // Add this as a known header so we won't implicitly add it to any
124406f32e7eSjoerg   // umbrella directory module.
124506f32e7eSjoerg   // FIXME: Should we only exclude it from umbrella modules within the
124606f32e7eSjoerg   // specified module?
124706f32e7eSjoerg   (void) Headers[Header.Entry];
124806f32e7eSjoerg 
124906f32e7eSjoerg   Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
125006f32e7eSjoerg }
125106f32e7eSjoerg 
125206f32e7eSjoerg const FileEntry *
getContainingModuleMapFile(const Module * Module) const125306f32e7eSjoerg ModuleMap::getContainingModuleMapFile(const Module *Module) const {
125406f32e7eSjoerg   if (Module->DefinitionLoc.isInvalid())
125506f32e7eSjoerg     return nullptr;
125606f32e7eSjoerg 
125706f32e7eSjoerg   return SourceMgr.getFileEntryForID(
125806f32e7eSjoerg            SourceMgr.getFileID(Module->DefinitionLoc));
125906f32e7eSjoerg }
126006f32e7eSjoerg 
getModuleMapFileForUniquing(const Module * M) const126106f32e7eSjoerg const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
126206f32e7eSjoerg   if (M->IsInferred) {
126306f32e7eSjoerg     assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
126406f32e7eSjoerg     return InferredModuleAllowedBy.find(M)->second;
126506f32e7eSjoerg   }
126606f32e7eSjoerg   return getContainingModuleMapFile(M);
126706f32e7eSjoerg }
126806f32e7eSjoerg 
setInferredModuleAllowedBy(Module * M,const FileEntry * ModMap)126906f32e7eSjoerg void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
127006f32e7eSjoerg   assert(M->IsInferred && "module not inferred");
127106f32e7eSjoerg   InferredModuleAllowedBy[M] = ModMap;
127206f32e7eSjoerg }
127306f32e7eSjoerg 
addAdditionalModuleMapFile(const Module * M,const FileEntry * ModuleMap)1274*13fbcb42Sjoerg void ModuleMap::addAdditionalModuleMapFile(const Module *M,
1275*13fbcb42Sjoerg                                            const FileEntry *ModuleMap) {
1276*13fbcb42Sjoerg   AdditionalModMaps[M].insert(ModuleMap);
1277*13fbcb42Sjoerg }
1278*13fbcb42Sjoerg 
dump()127906f32e7eSjoerg LLVM_DUMP_METHOD void ModuleMap::dump() {
128006f32e7eSjoerg   llvm::errs() << "Modules:";
128106f32e7eSjoerg   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
128206f32e7eSjoerg                                         MEnd = Modules.end();
128306f32e7eSjoerg        M != MEnd; ++M)
128406f32e7eSjoerg     M->getValue()->print(llvm::errs(), 2);
128506f32e7eSjoerg 
128606f32e7eSjoerg   llvm::errs() << "Headers:";
128706f32e7eSjoerg   for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
128806f32e7eSjoerg        H != HEnd; ++H) {
128906f32e7eSjoerg     llvm::errs() << "  \"" << H->first->getName() << "\" -> ";
129006f32e7eSjoerg     for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
129106f32e7eSjoerg                                                       E = H->second.end();
129206f32e7eSjoerg          I != E; ++I) {
129306f32e7eSjoerg       if (I != H->second.begin())
129406f32e7eSjoerg         llvm::errs() << ",";
129506f32e7eSjoerg       llvm::errs() << I->getModule()->getFullModuleName();
129606f32e7eSjoerg     }
129706f32e7eSjoerg     llvm::errs() << "\n";
129806f32e7eSjoerg   }
129906f32e7eSjoerg }
130006f32e7eSjoerg 
resolveExports(Module * Mod,bool Complain)130106f32e7eSjoerg bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
130206f32e7eSjoerg   auto Unresolved = std::move(Mod->UnresolvedExports);
130306f32e7eSjoerg   Mod->UnresolvedExports.clear();
130406f32e7eSjoerg   for (auto &UE : Unresolved) {
130506f32e7eSjoerg     Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
130606f32e7eSjoerg     if (Export.getPointer() || Export.getInt())
130706f32e7eSjoerg       Mod->Exports.push_back(Export);
130806f32e7eSjoerg     else
130906f32e7eSjoerg       Mod->UnresolvedExports.push_back(UE);
131006f32e7eSjoerg   }
131106f32e7eSjoerg   return !Mod->UnresolvedExports.empty();
131206f32e7eSjoerg }
131306f32e7eSjoerg 
resolveUses(Module * Mod,bool Complain)131406f32e7eSjoerg bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
131506f32e7eSjoerg   auto Unresolved = std::move(Mod->UnresolvedDirectUses);
131606f32e7eSjoerg   Mod->UnresolvedDirectUses.clear();
131706f32e7eSjoerg   for (auto &UDU : Unresolved) {
131806f32e7eSjoerg     Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
131906f32e7eSjoerg     if (DirectUse)
132006f32e7eSjoerg       Mod->DirectUses.push_back(DirectUse);
132106f32e7eSjoerg     else
132206f32e7eSjoerg       Mod->UnresolvedDirectUses.push_back(UDU);
132306f32e7eSjoerg   }
132406f32e7eSjoerg   return !Mod->UnresolvedDirectUses.empty();
132506f32e7eSjoerg }
132606f32e7eSjoerg 
resolveConflicts(Module * Mod,bool Complain)132706f32e7eSjoerg bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
132806f32e7eSjoerg   auto Unresolved = std::move(Mod->UnresolvedConflicts);
132906f32e7eSjoerg   Mod->UnresolvedConflicts.clear();
133006f32e7eSjoerg   for (auto &UC : Unresolved) {
133106f32e7eSjoerg     if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
133206f32e7eSjoerg       Module::Conflict Conflict;
133306f32e7eSjoerg       Conflict.Other = OtherMod;
133406f32e7eSjoerg       Conflict.Message = UC.Message;
133506f32e7eSjoerg       Mod->Conflicts.push_back(Conflict);
133606f32e7eSjoerg     } else
133706f32e7eSjoerg       Mod->UnresolvedConflicts.push_back(UC);
133806f32e7eSjoerg   }
133906f32e7eSjoerg   return !Mod->UnresolvedConflicts.empty();
134006f32e7eSjoerg }
134106f32e7eSjoerg 
134206f32e7eSjoerg //----------------------------------------------------------------------------//
134306f32e7eSjoerg // Module map file parser
134406f32e7eSjoerg //----------------------------------------------------------------------------//
134506f32e7eSjoerg 
134606f32e7eSjoerg namespace clang {
134706f32e7eSjoerg 
134806f32e7eSjoerg   /// A token in a module map file.
134906f32e7eSjoerg   struct MMToken {
135006f32e7eSjoerg     enum TokenKind {
135106f32e7eSjoerg       Comma,
135206f32e7eSjoerg       ConfigMacros,
135306f32e7eSjoerg       Conflict,
135406f32e7eSjoerg       EndOfFile,
135506f32e7eSjoerg       HeaderKeyword,
135606f32e7eSjoerg       Identifier,
135706f32e7eSjoerg       Exclaim,
135806f32e7eSjoerg       ExcludeKeyword,
135906f32e7eSjoerg       ExplicitKeyword,
136006f32e7eSjoerg       ExportKeyword,
136106f32e7eSjoerg       ExportAsKeyword,
136206f32e7eSjoerg       ExternKeyword,
136306f32e7eSjoerg       FrameworkKeyword,
136406f32e7eSjoerg       LinkKeyword,
136506f32e7eSjoerg       ModuleKeyword,
136606f32e7eSjoerg       Period,
136706f32e7eSjoerg       PrivateKeyword,
136806f32e7eSjoerg       UmbrellaKeyword,
136906f32e7eSjoerg       UseKeyword,
137006f32e7eSjoerg       RequiresKeyword,
137106f32e7eSjoerg       Star,
137206f32e7eSjoerg       StringLiteral,
137306f32e7eSjoerg       IntegerLiteral,
137406f32e7eSjoerg       TextualKeyword,
137506f32e7eSjoerg       LBrace,
137606f32e7eSjoerg       RBrace,
137706f32e7eSjoerg       LSquare,
137806f32e7eSjoerg       RSquare
137906f32e7eSjoerg     } Kind;
138006f32e7eSjoerg 
138106f32e7eSjoerg     unsigned Location;
138206f32e7eSjoerg     unsigned StringLength;
138306f32e7eSjoerg     union {
138406f32e7eSjoerg       // If Kind != IntegerLiteral.
138506f32e7eSjoerg       const char *StringData;
138606f32e7eSjoerg 
138706f32e7eSjoerg       // If Kind == IntegerLiteral.
138806f32e7eSjoerg       uint64_t IntegerValue;
138906f32e7eSjoerg     };
139006f32e7eSjoerg 
clearclang::MMToken139106f32e7eSjoerg     void clear() {
139206f32e7eSjoerg       Kind = EndOfFile;
139306f32e7eSjoerg       Location = 0;
139406f32e7eSjoerg       StringLength = 0;
139506f32e7eSjoerg       StringData = nullptr;
139606f32e7eSjoerg     }
139706f32e7eSjoerg 
isclang::MMToken139806f32e7eSjoerg     bool is(TokenKind K) const { return Kind == K; }
139906f32e7eSjoerg 
getLocationclang::MMToken140006f32e7eSjoerg     SourceLocation getLocation() const {
140106f32e7eSjoerg       return SourceLocation::getFromRawEncoding(Location);
140206f32e7eSjoerg     }
140306f32e7eSjoerg 
getIntegerclang::MMToken140406f32e7eSjoerg     uint64_t getInteger() const {
140506f32e7eSjoerg       return Kind == IntegerLiteral ? IntegerValue : 0;
140606f32e7eSjoerg     }
140706f32e7eSjoerg 
getStringclang::MMToken140806f32e7eSjoerg     StringRef getString() const {
140906f32e7eSjoerg       return Kind == IntegerLiteral ? StringRef()
141006f32e7eSjoerg                                     : StringRef(StringData, StringLength);
141106f32e7eSjoerg     }
141206f32e7eSjoerg   };
141306f32e7eSjoerg 
141406f32e7eSjoerg   class ModuleMapParser {
141506f32e7eSjoerg     Lexer &L;
141606f32e7eSjoerg     SourceManager &SourceMgr;
141706f32e7eSjoerg 
141806f32e7eSjoerg     /// Default target information, used only for string literal
141906f32e7eSjoerg     /// parsing.
142006f32e7eSjoerg     const TargetInfo *Target;
142106f32e7eSjoerg 
142206f32e7eSjoerg     DiagnosticsEngine &Diags;
142306f32e7eSjoerg     ModuleMap &Map;
142406f32e7eSjoerg 
142506f32e7eSjoerg     /// The current module map file.
142606f32e7eSjoerg     const FileEntry *ModuleMapFile;
142706f32e7eSjoerg 
142806f32e7eSjoerg     /// Source location of most recent parsed module declaration
142906f32e7eSjoerg     SourceLocation CurrModuleDeclLoc;
143006f32e7eSjoerg 
143106f32e7eSjoerg     /// The directory that file names in this module map file should
143206f32e7eSjoerg     /// be resolved relative to.
143306f32e7eSjoerg     const DirectoryEntry *Directory;
143406f32e7eSjoerg 
143506f32e7eSjoerg     /// Whether this module map is in a system header directory.
143606f32e7eSjoerg     bool IsSystem;
143706f32e7eSjoerg 
143806f32e7eSjoerg     /// Whether an error occurred.
143906f32e7eSjoerg     bool HadError = false;
144006f32e7eSjoerg 
144106f32e7eSjoerg     /// Stores string data for the various string literals referenced
144206f32e7eSjoerg     /// during parsing.
144306f32e7eSjoerg     llvm::BumpPtrAllocator StringData;
144406f32e7eSjoerg 
144506f32e7eSjoerg     /// The current token.
144606f32e7eSjoerg     MMToken Tok;
144706f32e7eSjoerg 
144806f32e7eSjoerg     /// The active module.
144906f32e7eSjoerg     Module *ActiveModule = nullptr;
145006f32e7eSjoerg 
145106f32e7eSjoerg     /// Whether a module uses the 'requires excluded' hack to mark its
145206f32e7eSjoerg     /// contents as 'textual'.
145306f32e7eSjoerg     ///
145406f32e7eSjoerg     /// On older Darwin SDK versions, 'requires excluded' is used to mark the
145506f32e7eSjoerg     /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
145606f32e7eSjoerg     /// non-modular headers.  For backwards compatibility, we continue to
145706f32e7eSjoerg     /// support this idiom for just these modules, and map the headers to
145806f32e7eSjoerg     /// 'textual' to match the original intent.
145906f32e7eSjoerg     llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
146006f32e7eSjoerg 
146106f32e7eSjoerg     /// Consume the current token and return its location.
146206f32e7eSjoerg     SourceLocation consumeToken();
146306f32e7eSjoerg 
146406f32e7eSjoerg     /// Skip tokens until we reach the a token with the given kind
146506f32e7eSjoerg     /// (or the end of the file).
146606f32e7eSjoerg     void skipUntil(MMToken::TokenKind K);
146706f32e7eSjoerg 
146806f32e7eSjoerg     using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>;
146906f32e7eSjoerg 
147006f32e7eSjoerg     bool parseModuleId(ModuleId &Id);
147106f32e7eSjoerg     void parseModuleDecl();
147206f32e7eSjoerg     void parseExternModuleDecl();
147306f32e7eSjoerg     void parseRequiresDecl();
147406f32e7eSjoerg     void parseHeaderDecl(MMToken::TokenKind, SourceLocation LeadingLoc);
147506f32e7eSjoerg     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
147606f32e7eSjoerg     void parseExportDecl();
147706f32e7eSjoerg     void parseExportAsDecl();
147806f32e7eSjoerg     void parseUseDecl();
147906f32e7eSjoerg     void parseLinkDecl();
148006f32e7eSjoerg     void parseConfigMacros();
148106f32e7eSjoerg     void parseConflict();
148206f32e7eSjoerg     void parseInferredModuleDecl(bool Framework, bool Explicit);
148306f32e7eSjoerg 
148406f32e7eSjoerg     /// Private modules are canonicalized as Foo_Private. Clang provides extra
148506f32e7eSjoerg     /// module map search logic to find the appropriate private module when PCH
148606f32e7eSjoerg     /// is used with implicit module maps. Warn when private modules are written
148706f32e7eSjoerg     /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
148806f32e7eSjoerg     void diagnosePrivateModules(SourceLocation ExplicitLoc,
148906f32e7eSjoerg                                 SourceLocation FrameworkLoc);
149006f32e7eSjoerg 
149106f32e7eSjoerg     using Attributes = ModuleMap::Attributes;
149206f32e7eSjoerg 
149306f32e7eSjoerg     bool parseOptionalAttributes(Attributes &Attrs);
149406f32e7eSjoerg 
149506f32e7eSjoerg   public:
ModuleMapParser(Lexer & L,SourceManager & SourceMgr,const TargetInfo * Target,DiagnosticsEngine & Diags,ModuleMap & Map,const FileEntry * ModuleMapFile,const DirectoryEntry * Directory,bool IsSystem)149606f32e7eSjoerg     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
149706f32e7eSjoerg                              const TargetInfo *Target, DiagnosticsEngine &Diags,
149806f32e7eSjoerg                              ModuleMap &Map, const FileEntry *ModuleMapFile,
149906f32e7eSjoerg                              const DirectoryEntry *Directory, bool IsSystem)
150006f32e7eSjoerg         : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
150106f32e7eSjoerg           ModuleMapFile(ModuleMapFile), Directory(Directory),
150206f32e7eSjoerg           IsSystem(IsSystem) {
150306f32e7eSjoerg       Tok.clear();
150406f32e7eSjoerg       consumeToken();
150506f32e7eSjoerg     }
150606f32e7eSjoerg 
150706f32e7eSjoerg     bool parseModuleMapFile();
150806f32e7eSjoerg 
terminatedByDirective()150906f32e7eSjoerg     bool terminatedByDirective() { return false; }
getLocation()151006f32e7eSjoerg     SourceLocation getLocation() { return Tok.getLocation(); }
151106f32e7eSjoerg   };
151206f32e7eSjoerg 
151306f32e7eSjoerg } // namespace clang
151406f32e7eSjoerg 
consumeToken()151506f32e7eSjoerg SourceLocation ModuleMapParser::consumeToken() {
151606f32e7eSjoerg   SourceLocation Result = Tok.getLocation();
151706f32e7eSjoerg 
151806f32e7eSjoerg retry:
151906f32e7eSjoerg   Tok.clear();
152006f32e7eSjoerg   Token LToken;
152106f32e7eSjoerg   L.LexFromRawLexer(LToken);
152206f32e7eSjoerg   Tok.Location = LToken.getLocation().getRawEncoding();
152306f32e7eSjoerg   switch (LToken.getKind()) {
152406f32e7eSjoerg   case tok::raw_identifier: {
152506f32e7eSjoerg     StringRef RI = LToken.getRawIdentifier();
152606f32e7eSjoerg     Tok.StringData = RI.data();
152706f32e7eSjoerg     Tok.StringLength = RI.size();
152806f32e7eSjoerg     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
152906f32e7eSjoerg                  .Case("config_macros", MMToken::ConfigMacros)
153006f32e7eSjoerg                  .Case("conflict", MMToken::Conflict)
153106f32e7eSjoerg                  .Case("exclude", MMToken::ExcludeKeyword)
153206f32e7eSjoerg                  .Case("explicit", MMToken::ExplicitKeyword)
153306f32e7eSjoerg                  .Case("export", MMToken::ExportKeyword)
153406f32e7eSjoerg                  .Case("export_as", MMToken::ExportAsKeyword)
153506f32e7eSjoerg                  .Case("extern", MMToken::ExternKeyword)
153606f32e7eSjoerg                  .Case("framework", MMToken::FrameworkKeyword)
153706f32e7eSjoerg                  .Case("header", MMToken::HeaderKeyword)
153806f32e7eSjoerg                  .Case("link", MMToken::LinkKeyword)
153906f32e7eSjoerg                  .Case("module", MMToken::ModuleKeyword)
154006f32e7eSjoerg                  .Case("private", MMToken::PrivateKeyword)
154106f32e7eSjoerg                  .Case("requires", MMToken::RequiresKeyword)
154206f32e7eSjoerg                  .Case("textual", MMToken::TextualKeyword)
154306f32e7eSjoerg                  .Case("umbrella", MMToken::UmbrellaKeyword)
154406f32e7eSjoerg                  .Case("use", MMToken::UseKeyword)
154506f32e7eSjoerg                  .Default(MMToken::Identifier);
154606f32e7eSjoerg     break;
154706f32e7eSjoerg   }
154806f32e7eSjoerg 
154906f32e7eSjoerg   case tok::comma:
155006f32e7eSjoerg     Tok.Kind = MMToken::Comma;
155106f32e7eSjoerg     break;
155206f32e7eSjoerg 
155306f32e7eSjoerg   case tok::eof:
155406f32e7eSjoerg     Tok.Kind = MMToken::EndOfFile;
155506f32e7eSjoerg     break;
155606f32e7eSjoerg 
155706f32e7eSjoerg   case tok::l_brace:
155806f32e7eSjoerg     Tok.Kind = MMToken::LBrace;
155906f32e7eSjoerg     break;
156006f32e7eSjoerg 
156106f32e7eSjoerg   case tok::l_square:
156206f32e7eSjoerg     Tok.Kind = MMToken::LSquare;
156306f32e7eSjoerg     break;
156406f32e7eSjoerg 
156506f32e7eSjoerg   case tok::period:
156606f32e7eSjoerg     Tok.Kind = MMToken::Period;
156706f32e7eSjoerg     break;
156806f32e7eSjoerg 
156906f32e7eSjoerg   case tok::r_brace:
157006f32e7eSjoerg     Tok.Kind = MMToken::RBrace;
157106f32e7eSjoerg     break;
157206f32e7eSjoerg 
157306f32e7eSjoerg   case tok::r_square:
157406f32e7eSjoerg     Tok.Kind = MMToken::RSquare;
157506f32e7eSjoerg     break;
157606f32e7eSjoerg 
157706f32e7eSjoerg   case tok::star:
157806f32e7eSjoerg     Tok.Kind = MMToken::Star;
157906f32e7eSjoerg     break;
158006f32e7eSjoerg 
158106f32e7eSjoerg   case tok::exclaim:
158206f32e7eSjoerg     Tok.Kind = MMToken::Exclaim;
158306f32e7eSjoerg     break;
158406f32e7eSjoerg 
158506f32e7eSjoerg   case tok::string_literal: {
158606f32e7eSjoerg     if (LToken.hasUDSuffix()) {
158706f32e7eSjoerg       Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
158806f32e7eSjoerg       HadError = true;
158906f32e7eSjoerg       goto retry;
159006f32e7eSjoerg     }
159106f32e7eSjoerg 
159206f32e7eSjoerg     // Parse the string literal.
159306f32e7eSjoerg     LangOptions LangOpts;
159406f32e7eSjoerg     StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
159506f32e7eSjoerg     if (StringLiteral.hadError)
159606f32e7eSjoerg       goto retry;
159706f32e7eSjoerg 
159806f32e7eSjoerg     // Copy the string literal into our string data allocator.
159906f32e7eSjoerg     unsigned Length = StringLiteral.GetStringLength();
160006f32e7eSjoerg     char *Saved = StringData.Allocate<char>(Length + 1);
160106f32e7eSjoerg     memcpy(Saved, StringLiteral.GetString().data(), Length);
160206f32e7eSjoerg     Saved[Length] = 0;
160306f32e7eSjoerg 
160406f32e7eSjoerg     // Form the token.
160506f32e7eSjoerg     Tok.Kind = MMToken::StringLiteral;
160606f32e7eSjoerg     Tok.StringData = Saved;
160706f32e7eSjoerg     Tok.StringLength = Length;
160806f32e7eSjoerg     break;
160906f32e7eSjoerg   }
161006f32e7eSjoerg 
161106f32e7eSjoerg   case tok::numeric_constant: {
161206f32e7eSjoerg     // We don't support any suffixes or other complications.
161306f32e7eSjoerg     SmallString<32> SpellingBuffer;
161406f32e7eSjoerg     SpellingBuffer.resize(LToken.getLength() + 1);
161506f32e7eSjoerg     const char *Start = SpellingBuffer.data();
161606f32e7eSjoerg     unsigned Length =
161706f32e7eSjoerg         Lexer::getSpelling(LToken, Start, SourceMgr, L.getLangOpts());
161806f32e7eSjoerg     uint64_t Value;
161906f32e7eSjoerg     if (StringRef(Start, Length).getAsInteger(0, Value)) {
162006f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
162106f32e7eSjoerg       HadError = true;
162206f32e7eSjoerg       goto retry;
162306f32e7eSjoerg     }
162406f32e7eSjoerg 
162506f32e7eSjoerg     Tok.Kind = MMToken::IntegerLiteral;
162606f32e7eSjoerg     Tok.IntegerValue = Value;
162706f32e7eSjoerg     break;
162806f32e7eSjoerg   }
162906f32e7eSjoerg 
163006f32e7eSjoerg   case tok::comment:
163106f32e7eSjoerg     goto retry;
163206f32e7eSjoerg 
163306f32e7eSjoerg   case tok::hash:
163406f32e7eSjoerg     // A module map can be terminated prematurely by
163506f32e7eSjoerg     //   #pragma clang module contents
163606f32e7eSjoerg     // When building the module, we'll treat the rest of the file as the
163706f32e7eSjoerg     // contents of the module.
163806f32e7eSjoerg     {
163906f32e7eSjoerg       auto NextIsIdent = [&](StringRef Str) -> bool {
164006f32e7eSjoerg         L.LexFromRawLexer(LToken);
164106f32e7eSjoerg         return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
164206f32e7eSjoerg                LToken.getRawIdentifier() == Str;
164306f32e7eSjoerg       };
164406f32e7eSjoerg       if (NextIsIdent("pragma") && NextIsIdent("clang") &&
164506f32e7eSjoerg           NextIsIdent("module") && NextIsIdent("contents")) {
164606f32e7eSjoerg         Tok.Kind = MMToken::EndOfFile;
164706f32e7eSjoerg         break;
164806f32e7eSjoerg       }
164906f32e7eSjoerg     }
165006f32e7eSjoerg     LLVM_FALLTHROUGH;
165106f32e7eSjoerg 
165206f32e7eSjoerg   default:
165306f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
165406f32e7eSjoerg     HadError = true;
165506f32e7eSjoerg     goto retry;
165606f32e7eSjoerg   }
165706f32e7eSjoerg 
165806f32e7eSjoerg   return Result;
165906f32e7eSjoerg }
166006f32e7eSjoerg 
skipUntil(MMToken::TokenKind K)166106f32e7eSjoerg void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
166206f32e7eSjoerg   unsigned braceDepth = 0;
166306f32e7eSjoerg   unsigned squareDepth = 0;
166406f32e7eSjoerg   do {
166506f32e7eSjoerg     switch (Tok.Kind) {
166606f32e7eSjoerg     case MMToken::EndOfFile:
166706f32e7eSjoerg       return;
166806f32e7eSjoerg 
166906f32e7eSjoerg     case MMToken::LBrace:
167006f32e7eSjoerg       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
167106f32e7eSjoerg         return;
167206f32e7eSjoerg 
167306f32e7eSjoerg       ++braceDepth;
167406f32e7eSjoerg       break;
167506f32e7eSjoerg 
167606f32e7eSjoerg     case MMToken::LSquare:
167706f32e7eSjoerg       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
167806f32e7eSjoerg         return;
167906f32e7eSjoerg 
168006f32e7eSjoerg       ++squareDepth;
168106f32e7eSjoerg       break;
168206f32e7eSjoerg 
168306f32e7eSjoerg     case MMToken::RBrace:
168406f32e7eSjoerg       if (braceDepth > 0)
168506f32e7eSjoerg         --braceDepth;
168606f32e7eSjoerg       else if (Tok.is(K))
168706f32e7eSjoerg         return;
168806f32e7eSjoerg       break;
168906f32e7eSjoerg 
169006f32e7eSjoerg     case MMToken::RSquare:
169106f32e7eSjoerg       if (squareDepth > 0)
169206f32e7eSjoerg         --squareDepth;
169306f32e7eSjoerg       else if (Tok.is(K))
169406f32e7eSjoerg         return;
169506f32e7eSjoerg       break;
169606f32e7eSjoerg 
169706f32e7eSjoerg     default:
169806f32e7eSjoerg       if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
169906f32e7eSjoerg         return;
170006f32e7eSjoerg       break;
170106f32e7eSjoerg     }
170206f32e7eSjoerg 
170306f32e7eSjoerg    consumeToken();
170406f32e7eSjoerg   } while (true);
170506f32e7eSjoerg }
170606f32e7eSjoerg 
170706f32e7eSjoerg /// Parse a module-id.
170806f32e7eSjoerg ///
170906f32e7eSjoerg ///   module-id:
171006f32e7eSjoerg ///     identifier
171106f32e7eSjoerg ///     identifier '.' module-id
171206f32e7eSjoerg ///
171306f32e7eSjoerg /// \returns true if an error occurred, false otherwise.
parseModuleId(ModuleId & Id)171406f32e7eSjoerg bool ModuleMapParser::parseModuleId(ModuleId &Id) {
171506f32e7eSjoerg   Id.clear();
171606f32e7eSjoerg   do {
171706f32e7eSjoerg     if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
1718*13fbcb42Sjoerg       Id.push_back(
1719*13fbcb42Sjoerg           std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
172006f32e7eSjoerg       consumeToken();
172106f32e7eSjoerg     } else {
172206f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
172306f32e7eSjoerg       return true;
172406f32e7eSjoerg     }
172506f32e7eSjoerg 
172606f32e7eSjoerg     if (!Tok.is(MMToken::Period))
172706f32e7eSjoerg       break;
172806f32e7eSjoerg 
172906f32e7eSjoerg     consumeToken();
173006f32e7eSjoerg   } while (true);
173106f32e7eSjoerg 
173206f32e7eSjoerg   return false;
173306f32e7eSjoerg }
173406f32e7eSjoerg 
173506f32e7eSjoerg namespace {
173606f32e7eSjoerg 
173706f32e7eSjoerg   /// Enumerates the known attributes.
173806f32e7eSjoerg   enum AttributeKind {
173906f32e7eSjoerg     /// An unknown attribute.
174006f32e7eSjoerg     AT_unknown,
174106f32e7eSjoerg 
174206f32e7eSjoerg     /// The 'system' attribute.
174306f32e7eSjoerg     AT_system,
174406f32e7eSjoerg 
174506f32e7eSjoerg     /// The 'extern_c' attribute.
174606f32e7eSjoerg     AT_extern_c,
174706f32e7eSjoerg 
174806f32e7eSjoerg     /// The 'exhaustive' attribute.
174906f32e7eSjoerg     AT_exhaustive,
175006f32e7eSjoerg 
175106f32e7eSjoerg     /// The 'no_undeclared_includes' attribute.
175206f32e7eSjoerg     AT_no_undeclared_includes
175306f32e7eSjoerg   };
175406f32e7eSjoerg 
175506f32e7eSjoerg } // namespace
175606f32e7eSjoerg 
175706f32e7eSjoerg /// Private modules are canonicalized as Foo_Private. Clang provides extra
175806f32e7eSjoerg /// module map search logic to find the appropriate private module when PCH
175906f32e7eSjoerg /// is used with implicit module maps. Warn when private modules are written
176006f32e7eSjoerg /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
diagnosePrivateModules(SourceLocation ExplicitLoc,SourceLocation FrameworkLoc)176106f32e7eSjoerg void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc,
176206f32e7eSjoerg                                              SourceLocation FrameworkLoc) {
176306f32e7eSjoerg   auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
176406f32e7eSjoerg                              const Module *M, SourceRange ReplLoc) {
176506f32e7eSjoerg     auto D = Diags.Report(ActiveModule->DefinitionLoc,
176606f32e7eSjoerg                           diag::note_mmap_rename_top_level_private_module);
176706f32e7eSjoerg     D << BadName << M->Name;
176806f32e7eSjoerg     D << FixItHint::CreateReplacement(ReplLoc, Canonical);
176906f32e7eSjoerg   };
177006f32e7eSjoerg 
177106f32e7eSjoerg   for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
177206f32e7eSjoerg     auto const *M = E->getValue();
177306f32e7eSjoerg     if (M->Directory != ActiveModule->Directory)
177406f32e7eSjoerg       continue;
177506f32e7eSjoerg 
177606f32e7eSjoerg     SmallString<128> FullName(ActiveModule->getFullModuleName());
177706f32e7eSjoerg     if (!FullName.startswith(M->Name) && !FullName.endswith("Private"))
177806f32e7eSjoerg       continue;
177906f32e7eSjoerg     SmallString<128> FixedPrivModDecl;
178006f32e7eSjoerg     SmallString<128> Canonical(M->Name);
178106f32e7eSjoerg     Canonical.append("_Private");
178206f32e7eSjoerg 
178306f32e7eSjoerg     // Foo.Private -> Foo_Private
178406f32e7eSjoerg     if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
178506f32e7eSjoerg         M->Name == ActiveModule->Parent->Name) {
178606f32e7eSjoerg       Diags.Report(ActiveModule->DefinitionLoc,
178706f32e7eSjoerg                    diag::warn_mmap_mismatched_private_submodule)
178806f32e7eSjoerg           << FullName;
178906f32e7eSjoerg 
179006f32e7eSjoerg       SourceLocation FixItInitBegin = CurrModuleDeclLoc;
179106f32e7eSjoerg       if (FrameworkLoc.isValid())
179206f32e7eSjoerg         FixItInitBegin = FrameworkLoc;
179306f32e7eSjoerg       if (ExplicitLoc.isValid())
179406f32e7eSjoerg         FixItInitBegin = ExplicitLoc;
179506f32e7eSjoerg 
179606f32e7eSjoerg       if (FrameworkLoc.isValid() || ActiveModule->Parent->IsFramework)
179706f32e7eSjoerg         FixedPrivModDecl.append("framework ");
179806f32e7eSjoerg       FixedPrivModDecl.append("module ");
179906f32e7eSjoerg       FixedPrivModDecl.append(Canonical);
180006f32e7eSjoerg 
180106f32e7eSjoerg       GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
180206f32e7eSjoerg                       SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
180306f32e7eSjoerg       continue;
180406f32e7eSjoerg     }
180506f32e7eSjoerg 
180606f32e7eSjoerg     // FooPrivate and whatnots -> Foo_Private
180706f32e7eSjoerg     if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
180806f32e7eSjoerg         ActiveModule->Name != Canonical) {
180906f32e7eSjoerg       Diags.Report(ActiveModule->DefinitionLoc,
181006f32e7eSjoerg                    diag::warn_mmap_mismatched_private_module_name)
181106f32e7eSjoerg           << ActiveModule->Name;
181206f32e7eSjoerg       GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
181306f32e7eSjoerg                       SourceRange(ActiveModule->DefinitionLoc));
181406f32e7eSjoerg     }
181506f32e7eSjoerg   }
181606f32e7eSjoerg }
181706f32e7eSjoerg 
181806f32e7eSjoerg /// Parse a module declaration.
181906f32e7eSjoerg ///
182006f32e7eSjoerg ///   module-declaration:
182106f32e7eSjoerg ///     'extern' 'module' module-id string-literal
182206f32e7eSjoerg ///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
182306f32e7eSjoerg ///       { module-member* }
182406f32e7eSjoerg ///
182506f32e7eSjoerg ///   module-member:
182606f32e7eSjoerg ///     requires-declaration
182706f32e7eSjoerg ///     header-declaration
182806f32e7eSjoerg ///     submodule-declaration
182906f32e7eSjoerg ///     export-declaration
183006f32e7eSjoerg ///     export-as-declaration
183106f32e7eSjoerg ///     link-declaration
183206f32e7eSjoerg ///
183306f32e7eSjoerg ///   submodule-declaration:
183406f32e7eSjoerg ///     module-declaration
183506f32e7eSjoerg ///     inferred-submodule-declaration
parseModuleDecl()183606f32e7eSjoerg void ModuleMapParser::parseModuleDecl() {
183706f32e7eSjoerg   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
183806f32e7eSjoerg          Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
183906f32e7eSjoerg   if (Tok.is(MMToken::ExternKeyword)) {
184006f32e7eSjoerg     parseExternModuleDecl();
184106f32e7eSjoerg     return;
184206f32e7eSjoerg   }
184306f32e7eSjoerg 
184406f32e7eSjoerg   // Parse 'explicit' or 'framework' keyword, if present.
184506f32e7eSjoerg   SourceLocation ExplicitLoc;
184606f32e7eSjoerg   SourceLocation FrameworkLoc;
184706f32e7eSjoerg   bool Explicit = false;
184806f32e7eSjoerg   bool Framework = false;
184906f32e7eSjoerg 
185006f32e7eSjoerg   // Parse 'explicit' keyword, if present.
185106f32e7eSjoerg   if (Tok.is(MMToken::ExplicitKeyword)) {
185206f32e7eSjoerg     ExplicitLoc = consumeToken();
185306f32e7eSjoerg     Explicit = true;
185406f32e7eSjoerg   }
185506f32e7eSjoerg 
185606f32e7eSjoerg   // Parse 'framework' keyword, if present.
185706f32e7eSjoerg   if (Tok.is(MMToken::FrameworkKeyword)) {
185806f32e7eSjoerg     FrameworkLoc = consumeToken();
185906f32e7eSjoerg     Framework = true;
186006f32e7eSjoerg   }
186106f32e7eSjoerg 
186206f32e7eSjoerg   // Parse 'module' keyword.
186306f32e7eSjoerg   if (!Tok.is(MMToken::ModuleKeyword)) {
186406f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
186506f32e7eSjoerg     consumeToken();
186606f32e7eSjoerg     HadError = true;
186706f32e7eSjoerg     return;
186806f32e7eSjoerg   }
186906f32e7eSjoerg   CurrModuleDeclLoc = consumeToken(); // 'module' keyword
187006f32e7eSjoerg 
187106f32e7eSjoerg   // If we have a wildcard for the module name, this is an inferred submodule.
187206f32e7eSjoerg   // Parse it.
187306f32e7eSjoerg   if (Tok.is(MMToken::Star))
187406f32e7eSjoerg     return parseInferredModuleDecl(Framework, Explicit);
187506f32e7eSjoerg 
187606f32e7eSjoerg   // Parse the module name.
187706f32e7eSjoerg   ModuleId Id;
187806f32e7eSjoerg   if (parseModuleId(Id)) {
187906f32e7eSjoerg     HadError = true;
188006f32e7eSjoerg     return;
188106f32e7eSjoerg   }
188206f32e7eSjoerg 
188306f32e7eSjoerg   if (ActiveModule) {
188406f32e7eSjoerg     if (Id.size() > 1) {
188506f32e7eSjoerg       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
188606f32e7eSjoerg         << SourceRange(Id.front().second, Id.back().second);
188706f32e7eSjoerg 
188806f32e7eSjoerg       HadError = true;
188906f32e7eSjoerg       return;
189006f32e7eSjoerg     }
189106f32e7eSjoerg   } else if (Id.size() == 1 && Explicit) {
189206f32e7eSjoerg     // Top-level modules can't be explicit.
189306f32e7eSjoerg     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
189406f32e7eSjoerg     Explicit = false;
189506f32e7eSjoerg     ExplicitLoc = SourceLocation();
189606f32e7eSjoerg     HadError = true;
189706f32e7eSjoerg   }
189806f32e7eSjoerg 
189906f32e7eSjoerg   Module *PreviousActiveModule = ActiveModule;
190006f32e7eSjoerg   if (Id.size() > 1) {
190106f32e7eSjoerg     // This module map defines a submodule. Go find the module of which it
190206f32e7eSjoerg     // is a submodule.
190306f32e7eSjoerg     ActiveModule = nullptr;
190406f32e7eSjoerg     const Module *TopLevelModule = nullptr;
190506f32e7eSjoerg     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
190606f32e7eSjoerg       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
190706f32e7eSjoerg         if (I == 0)
190806f32e7eSjoerg           TopLevelModule = Next;
190906f32e7eSjoerg         ActiveModule = Next;
191006f32e7eSjoerg         continue;
191106f32e7eSjoerg       }
191206f32e7eSjoerg 
1913*13fbcb42Sjoerg       Diags.Report(Id[I].second, diag::err_mmap_missing_parent_module)
1914*13fbcb42Sjoerg           << Id[I].first << (ActiveModule != nullptr)
1915*13fbcb42Sjoerg           << (ActiveModule
1916*13fbcb42Sjoerg                   ? ActiveModule->getTopLevelModule()->getFullModuleName()
1917*13fbcb42Sjoerg                   : "");
191806f32e7eSjoerg       HadError = true;
191906f32e7eSjoerg     }
192006f32e7eSjoerg 
1921*13fbcb42Sjoerg     if (TopLevelModule &&
1922*13fbcb42Sjoerg         ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
192306f32e7eSjoerg       assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
192406f32e7eSjoerg              "submodule defined in same file as 'module *' that allowed its "
192506f32e7eSjoerg              "top-level module");
192606f32e7eSjoerg       Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
192706f32e7eSjoerg     }
192806f32e7eSjoerg   }
192906f32e7eSjoerg 
193006f32e7eSjoerg   StringRef ModuleName = Id.back().first;
193106f32e7eSjoerg   SourceLocation ModuleNameLoc = Id.back().second;
193206f32e7eSjoerg 
193306f32e7eSjoerg   // Parse the optional attribute list.
193406f32e7eSjoerg   Attributes Attrs;
193506f32e7eSjoerg   if (parseOptionalAttributes(Attrs))
193606f32e7eSjoerg     return;
193706f32e7eSjoerg 
193806f32e7eSjoerg   // Parse the opening brace.
193906f32e7eSjoerg   if (!Tok.is(MMToken::LBrace)) {
194006f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
194106f32e7eSjoerg       << ModuleName;
194206f32e7eSjoerg     HadError = true;
194306f32e7eSjoerg     return;
194406f32e7eSjoerg   }
194506f32e7eSjoerg   SourceLocation LBraceLoc = consumeToken();
194606f32e7eSjoerg 
194706f32e7eSjoerg   // Determine whether this (sub)module has already been defined.
194806f32e7eSjoerg   Module *ShadowingModule = nullptr;
194906f32e7eSjoerg   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
195006f32e7eSjoerg     // We might see a (re)definition of a module that we already have a
195106f32e7eSjoerg     // definition for in two cases:
195206f32e7eSjoerg     //  - If we loaded one definition from an AST file and we've just found a
195306f32e7eSjoerg     //    corresponding definition in a module map file, or
195406f32e7eSjoerg     bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid();
195506f32e7eSjoerg     //  - If we're building a (preprocessed) module and we've just loaded the
195606f32e7eSjoerg     //    module map file from which it was created.
195706f32e7eSjoerg     bool ParsedAsMainInput =
195806f32e7eSjoerg         Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
195906f32e7eSjoerg         Map.LangOpts.CurrentModule == ModuleName &&
196006f32e7eSjoerg         SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
196106f32e7eSjoerg             SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
196206f32e7eSjoerg     if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
196306f32e7eSjoerg       // Skip the module definition.
196406f32e7eSjoerg       skipUntil(MMToken::RBrace);
196506f32e7eSjoerg       if (Tok.is(MMToken::RBrace))
196606f32e7eSjoerg         consumeToken();
196706f32e7eSjoerg       else {
196806f32e7eSjoerg         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
196906f32e7eSjoerg         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
197006f32e7eSjoerg         HadError = true;
197106f32e7eSjoerg       }
197206f32e7eSjoerg       return;
197306f32e7eSjoerg     }
197406f32e7eSjoerg 
197506f32e7eSjoerg     if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
197606f32e7eSjoerg       ShadowingModule = Existing;
197706f32e7eSjoerg     } else {
197806f32e7eSjoerg       // This is not a shawdowed module decl, it is an illegal redefinition.
197906f32e7eSjoerg       Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
198006f32e7eSjoerg           << ModuleName;
198106f32e7eSjoerg       Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
198206f32e7eSjoerg 
198306f32e7eSjoerg       // Skip the module definition.
198406f32e7eSjoerg       skipUntil(MMToken::RBrace);
198506f32e7eSjoerg       if (Tok.is(MMToken::RBrace))
198606f32e7eSjoerg         consumeToken();
198706f32e7eSjoerg 
198806f32e7eSjoerg       HadError = true;
198906f32e7eSjoerg       return;
199006f32e7eSjoerg     }
199106f32e7eSjoerg   }
199206f32e7eSjoerg 
199306f32e7eSjoerg   // Start defining this module.
199406f32e7eSjoerg   if (ShadowingModule) {
199506f32e7eSjoerg     ActiveModule =
199606f32e7eSjoerg         Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
199706f32e7eSjoerg   } else {
199806f32e7eSjoerg     ActiveModule =
199906f32e7eSjoerg         Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
200006f32e7eSjoerg             .first;
200106f32e7eSjoerg   }
200206f32e7eSjoerg 
200306f32e7eSjoerg   ActiveModule->DefinitionLoc = ModuleNameLoc;
200406f32e7eSjoerg   if (Attrs.IsSystem || IsSystem)
200506f32e7eSjoerg     ActiveModule->IsSystem = true;
200606f32e7eSjoerg   if (Attrs.IsExternC)
200706f32e7eSjoerg     ActiveModule->IsExternC = true;
200806f32e7eSjoerg   if (Attrs.NoUndeclaredIncludes ||
200906f32e7eSjoerg       (!ActiveModule->Parent && ModuleName == "Darwin"))
201006f32e7eSjoerg     ActiveModule->NoUndeclaredIncludes = true;
201106f32e7eSjoerg   ActiveModule->Directory = Directory;
201206f32e7eSjoerg 
201306f32e7eSjoerg   StringRef MapFileName(ModuleMapFile->getName());
201406f32e7eSjoerg   if (MapFileName.endswith("module.private.modulemap") ||
201506f32e7eSjoerg       MapFileName.endswith("module_private.map")) {
201606f32e7eSjoerg     ActiveModule->ModuleMapIsPrivate = true;
201706f32e7eSjoerg   }
201806f32e7eSjoerg 
201906f32e7eSjoerg   // Private modules named as FooPrivate, Foo.Private or similar are likely a
202006f32e7eSjoerg   // user error; provide warnings, notes and fixits to direct users to use
202106f32e7eSjoerg   // Foo_Private instead.
202206f32e7eSjoerg   SourceLocation StartLoc =
202306f32e7eSjoerg       SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
202406f32e7eSjoerg   if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
202506f32e7eSjoerg       !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
202606f32e7eSjoerg                        StartLoc) &&
202706f32e7eSjoerg       !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
202806f32e7eSjoerg                        StartLoc) &&
202906f32e7eSjoerg       ActiveModule->ModuleMapIsPrivate)
203006f32e7eSjoerg     diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
203106f32e7eSjoerg 
203206f32e7eSjoerg   bool Done = false;
203306f32e7eSjoerg   do {
203406f32e7eSjoerg     switch (Tok.Kind) {
203506f32e7eSjoerg     case MMToken::EndOfFile:
203606f32e7eSjoerg     case MMToken::RBrace:
203706f32e7eSjoerg       Done = true;
203806f32e7eSjoerg       break;
203906f32e7eSjoerg 
204006f32e7eSjoerg     case MMToken::ConfigMacros:
204106f32e7eSjoerg       parseConfigMacros();
204206f32e7eSjoerg       break;
204306f32e7eSjoerg 
204406f32e7eSjoerg     case MMToken::Conflict:
204506f32e7eSjoerg       parseConflict();
204606f32e7eSjoerg       break;
204706f32e7eSjoerg 
204806f32e7eSjoerg     case MMToken::ExplicitKeyword:
204906f32e7eSjoerg     case MMToken::ExternKeyword:
205006f32e7eSjoerg     case MMToken::FrameworkKeyword:
205106f32e7eSjoerg     case MMToken::ModuleKeyword:
205206f32e7eSjoerg       parseModuleDecl();
205306f32e7eSjoerg       break;
205406f32e7eSjoerg 
205506f32e7eSjoerg     case MMToken::ExportKeyword:
205606f32e7eSjoerg       parseExportDecl();
205706f32e7eSjoerg       break;
205806f32e7eSjoerg 
205906f32e7eSjoerg     case MMToken::ExportAsKeyword:
206006f32e7eSjoerg       parseExportAsDecl();
206106f32e7eSjoerg       break;
206206f32e7eSjoerg 
206306f32e7eSjoerg     case MMToken::UseKeyword:
206406f32e7eSjoerg       parseUseDecl();
206506f32e7eSjoerg       break;
206606f32e7eSjoerg 
206706f32e7eSjoerg     case MMToken::RequiresKeyword:
206806f32e7eSjoerg       parseRequiresDecl();
206906f32e7eSjoerg       break;
207006f32e7eSjoerg 
207106f32e7eSjoerg     case MMToken::TextualKeyword:
207206f32e7eSjoerg       parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
207306f32e7eSjoerg       break;
207406f32e7eSjoerg 
207506f32e7eSjoerg     case MMToken::UmbrellaKeyword: {
207606f32e7eSjoerg       SourceLocation UmbrellaLoc = consumeToken();
207706f32e7eSjoerg       if (Tok.is(MMToken::HeaderKeyword))
207806f32e7eSjoerg         parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
207906f32e7eSjoerg       else
208006f32e7eSjoerg         parseUmbrellaDirDecl(UmbrellaLoc);
208106f32e7eSjoerg       break;
208206f32e7eSjoerg     }
208306f32e7eSjoerg 
208406f32e7eSjoerg     case MMToken::ExcludeKeyword:
208506f32e7eSjoerg       parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
208606f32e7eSjoerg       break;
208706f32e7eSjoerg 
208806f32e7eSjoerg     case MMToken::PrivateKeyword:
208906f32e7eSjoerg       parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
209006f32e7eSjoerg       break;
209106f32e7eSjoerg 
209206f32e7eSjoerg     case MMToken::HeaderKeyword:
209306f32e7eSjoerg       parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
209406f32e7eSjoerg       break;
209506f32e7eSjoerg 
209606f32e7eSjoerg     case MMToken::LinkKeyword:
209706f32e7eSjoerg       parseLinkDecl();
209806f32e7eSjoerg       break;
209906f32e7eSjoerg 
210006f32e7eSjoerg     default:
210106f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
210206f32e7eSjoerg       consumeToken();
210306f32e7eSjoerg       break;
210406f32e7eSjoerg     }
210506f32e7eSjoerg   } while (!Done);
210606f32e7eSjoerg 
210706f32e7eSjoerg   if (Tok.is(MMToken::RBrace))
210806f32e7eSjoerg     consumeToken();
210906f32e7eSjoerg   else {
211006f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
211106f32e7eSjoerg     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
211206f32e7eSjoerg     HadError = true;
211306f32e7eSjoerg   }
211406f32e7eSjoerg 
211506f32e7eSjoerg   // If the active module is a top-level framework, and there are no link
211606f32e7eSjoerg   // libraries, automatically link against the framework.
211706f32e7eSjoerg   if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
211806f32e7eSjoerg       ActiveModule->LinkLibraries.empty()) {
211906f32e7eSjoerg     inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
212006f32e7eSjoerg   }
212106f32e7eSjoerg 
212206f32e7eSjoerg   // If the module meets all requirements but is still unavailable, mark the
212306f32e7eSjoerg   // whole tree as unavailable to prevent it from building.
2124*13fbcb42Sjoerg   if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
212506f32e7eSjoerg       ActiveModule->Parent) {
2126*13fbcb42Sjoerg     ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
212706f32e7eSjoerg     ActiveModule->getTopLevelModule()->MissingHeaders.append(
212806f32e7eSjoerg       ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
212906f32e7eSjoerg   }
213006f32e7eSjoerg 
213106f32e7eSjoerg   // We're done parsing this module. Pop back to the previous module.
213206f32e7eSjoerg   ActiveModule = PreviousActiveModule;
213306f32e7eSjoerg }
213406f32e7eSjoerg 
213506f32e7eSjoerg /// Parse an extern module declaration.
213606f32e7eSjoerg ///
213706f32e7eSjoerg ///   extern module-declaration:
213806f32e7eSjoerg ///     'extern' 'module' module-id string-literal
parseExternModuleDecl()213906f32e7eSjoerg void ModuleMapParser::parseExternModuleDecl() {
214006f32e7eSjoerg   assert(Tok.is(MMToken::ExternKeyword));
214106f32e7eSjoerg   SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
214206f32e7eSjoerg 
214306f32e7eSjoerg   // Parse 'module' keyword.
214406f32e7eSjoerg   if (!Tok.is(MMToken::ModuleKeyword)) {
214506f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
214606f32e7eSjoerg     consumeToken();
214706f32e7eSjoerg     HadError = true;
214806f32e7eSjoerg     return;
214906f32e7eSjoerg   }
215006f32e7eSjoerg   consumeToken(); // 'module' keyword
215106f32e7eSjoerg 
215206f32e7eSjoerg   // Parse the module name.
215306f32e7eSjoerg   ModuleId Id;
215406f32e7eSjoerg   if (parseModuleId(Id)) {
215506f32e7eSjoerg     HadError = true;
215606f32e7eSjoerg     return;
215706f32e7eSjoerg   }
215806f32e7eSjoerg 
215906f32e7eSjoerg   // Parse the referenced module map file name.
216006f32e7eSjoerg   if (!Tok.is(MMToken::StringLiteral)) {
216106f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
216206f32e7eSjoerg     HadError = true;
216306f32e7eSjoerg     return;
216406f32e7eSjoerg   }
2165*13fbcb42Sjoerg   std::string FileName = std::string(Tok.getString());
216606f32e7eSjoerg   consumeToken(); // filename
216706f32e7eSjoerg 
216806f32e7eSjoerg   StringRef FileNameRef = FileName;
216906f32e7eSjoerg   SmallString<128> ModuleMapFileName;
217006f32e7eSjoerg   if (llvm::sys::path::is_relative(FileNameRef)) {
217106f32e7eSjoerg     ModuleMapFileName += Directory->getName();
217206f32e7eSjoerg     llvm::sys::path::append(ModuleMapFileName, FileName);
217306f32e7eSjoerg     FileNameRef = ModuleMapFileName;
217406f32e7eSjoerg   }
217506f32e7eSjoerg   if (auto File = SourceMgr.getFileManager().getFile(FileNameRef))
217606f32e7eSjoerg     Map.parseModuleMapFile(
217706f32e7eSjoerg         *File, /*IsSystem=*/false,
217806f32e7eSjoerg         Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
217906f32e7eSjoerg             ? Directory
218006f32e7eSjoerg             : (*File)->getDir(),
218106f32e7eSjoerg         FileID(), nullptr, ExternLoc);
218206f32e7eSjoerg }
218306f32e7eSjoerg 
218406f32e7eSjoerg /// Whether to add the requirement \p Feature to the module \p M.
218506f32e7eSjoerg ///
218606f32e7eSjoerg /// This preserves backwards compatibility for two hacks in the Darwin system
218706f32e7eSjoerg /// module map files:
218806f32e7eSjoerg ///
218906f32e7eSjoerg /// 1. The use of 'requires excluded' to make headers non-modular, which
219006f32e7eSjoerg ///    should really be mapped to 'textual' now that we have this feature.  We
219106f32e7eSjoerg ///    drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
219206f32e7eSjoerg ///    true.  Later, this bit will be used to map all the headers inside this
219306f32e7eSjoerg ///    module to 'textual'.
219406f32e7eSjoerg ///
219506f32e7eSjoerg ///    This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
219606f32e7eSjoerg ///
219706f32e7eSjoerg /// 2. Removes a bogus cplusplus requirement from IOKit.avc.  This requirement
219806f32e7eSjoerg ///    was never correct and causes issues now that we check it, so drop it.
shouldAddRequirement(Module * M,StringRef Feature,bool & IsRequiresExcludedHack)219906f32e7eSjoerg static bool shouldAddRequirement(Module *M, StringRef Feature,
220006f32e7eSjoerg                                  bool &IsRequiresExcludedHack) {
220106f32e7eSjoerg   if (Feature == "excluded" &&
220206f32e7eSjoerg       (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
220306f32e7eSjoerg        M->fullModuleNameIs({"Tcl", "Private"}))) {
220406f32e7eSjoerg     IsRequiresExcludedHack = true;
220506f32e7eSjoerg     return false;
220606f32e7eSjoerg   } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
220706f32e7eSjoerg     return false;
220806f32e7eSjoerg   }
220906f32e7eSjoerg 
221006f32e7eSjoerg   return true;
221106f32e7eSjoerg }
221206f32e7eSjoerg 
221306f32e7eSjoerg /// Parse a requires declaration.
221406f32e7eSjoerg ///
221506f32e7eSjoerg ///   requires-declaration:
221606f32e7eSjoerg ///     'requires' feature-list
221706f32e7eSjoerg ///
221806f32e7eSjoerg ///   feature-list:
221906f32e7eSjoerg ///     feature ',' feature-list
222006f32e7eSjoerg ///     feature
222106f32e7eSjoerg ///
222206f32e7eSjoerg ///   feature:
222306f32e7eSjoerg ///     '!'[opt] identifier
parseRequiresDecl()222406f32e7eSjoerg void ModuleMapParser::parseRequiresDecl() {
222506f32e7eSjoerg   assert(Tok.is(MMToken::RequiresKeyword));
222606f32e7eSjoerg 
222706f32e7eSjoerg   // Parse 'requires' keyword.
222806f32e7eSjoerg   consumeToken();
222906f32e7eSjoerg 
223006f32e7eSjoerg   // Parse the feature-list.
223106f32e7eSjoerg   do {
223206f32e7eSjoerg     bool RequiredState = true;
223306f32e7eSjoerg     if (Tok.is(MMToken::Exclaim)) {
223406f32e7eSjoerg       RequiredState = false;
223506f32e7eSjoerg       consumeToken();
223606f32e7eSjoerg     }
223706f32e7eSjoerg 
223806f32e7eSjoerg     if (!Tok.is(MMToken::Identifier)) {
223906f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
224006f32e7eSjoerg       HadError = true;
224106f32e7eSjoerg       return;
224206f32e7eSjoerg     }
224306f32e7eSjoerg 
224406f32e7eSjoerg     // Consume the feature name.
2245*13fbcb42Sjoerg     std::string Feature = std::string(Tok.getString());
224606f32e7eSjoerg     consumeToken();
224706f32e7eSjoerg 
224806f32e7eSjoerg     bool IsRequiresExcludedHack = false;
224906f32e7eSjoerg     bool ShouldAddRequirement =
225006f32e7eSjoerg         shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
225106f32e7eSjoerg 
225206f32e7eSjoerg     if (IsRequiresExcludedHack)
225306f32e7eSjoerg       UsesRequiresExcludedHack.insert(ActiveModule);
225406f32e7eSjoerg 
225506f32e7eSjoerg     if (ShouldAddRequirement) {
225606f32e7eSjoerg       // Add this feature.
225706f32e7eSjoerg       ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
225806f32e7eSjoerg                                    *Map.Target);
225906f32e7eSjoerg     }
226006f32e7eSjoerg 
226106f32e7eSjoerg     if (!Tok.is(MMToken::Comma))
226206f32e7eSjoerg       break;
226306f32e7eSjoerg 
226406f32e7eSjoerg     // Consume the comma.
226506f32e7eSjoerg     consumeToken();
226606f32e7eSjoerg   } while (true);
226706f32e7eSjoerg }
226806f32e7eSjoerg 
226906f32e7eSjoerg /// Parse a header declaration.
227006f32e7eSjoerg ///
227106f32e7eSjoerg ///   header-declaration:
227206f32e7eSjoerg ///     'textual'[opt] 'header' string-literal
227306f32e7eSjoerg ///     'private' 'textual'[opt] 'header' string-literal
227406f32e7eSjoerg ///     'exclude' 'header' string-literal
227506f32e7eSjoerg ///     'umbrella' 'header' string-literal
227606f32e7eSjoerg ///
227706f32e7eSjoerg /// FIXME: Support 'private textual header'.
parseHeaderDecl(MMToken::TokenKind LeadingToken,SourceLocation LeadingLoc)227806f32e7eSjoerg void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
227906f32e7eSjoerg                                       SourceLocation LeadingLoc) {
228006f32e7eSjoerg   // We've already consumed the first token.
228106f32e7eSjoerg   ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
228206f32e7eSjoerg   if (LeadingToken == MMToken::PrivateKeyword) {
228306f32e7eSjoerg     Role = ModuleMap::PrivateHeader;
228406f32e7eSjoerg     // 'private' may optionally be followed by 'textual'.
228506f32e7eSjoerg     if (Tok.is(MMToken::TextualKeyword)) {
228606f32e7eSjoerg       LeadingToken = Tok.Kind;
228706f32e7eSjoerg       consumeToken();
228806f32e7eSjoerg     }
228906f32e7eSjoerg   }
229006f32e7eSjoerg 
229106f32e7eSjoerg   if (LeadingToken == MMToken::TextualKeyword)
229206f32e7eSjoerg     Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
229306f32e7eSjoerg 
229406f32e7eSjoerg   if (UsesRequiresExcludedHack.count(ActiveModule)) {
229506f32e7eSjoerg     // Mark this header 'textual' (see doc comment for
229606f32e7eSjoerg     // Module::UsesRequiresExcludedHack).
229706f32e7eSjoerg     Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
229806f32e7eSjoerg   }
229906f32e7eSjoerg 
230006f32e7eSjoerg   if (LeadingToken != MMToken::HeaderKeyword) {
230106f32e7eSjoerg     if (!Tok.is(MMToken::HeaderKeyword)) {
230206f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
230306f32e7eSjoerg           << (LeadingToken == MMToken::PrivateKeyword ? "private" :
230406f32e7eSjoerg               LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
230506f32e7eSjoerg               LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
230606f32e7eSjoerg       return;
230706f32e7eSjoerg     }
230806f32e7eSjoerg     consumeToken();
230906f32e7eSjoerg   }
231006f32e7eSjoerg 
231106f32e7eSjoerg   // Parse the header name.
231206f32e7eSjoerg   if (!Tok.is(MMToken::StringLiteral)) {
231306f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
231406f32e7eSjoerg       << "header";
231506f32e7eSjoerg     HadError = true;
231606f32e7eSjoerg     return;
231706f32e7eSjoerg   }
231806f32e7eSjoerg   Module::UnresolvedHeaderDirective Header;
2319*13fbcb42Sjoerg   Header.FileName = std::string(Tok.getString());
232006f32e7eSjoerg   Header.FileNameLoc = consumeToken();
232106f32e7eSjoerg   Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
232206f32e7eSjoerg   Header.Kind =
232306f32e7eSjoerg       (LeadingToken == MMToken::ExcludeKeyword ? Module::HK_Excluded
232406f32e7eSjoerg                                                : Map.headerRoleToKind(Role));
232506f32e7eSjoerg 
232606f32e7eSjoerg   // Check whether we already have an umbrella.
232706f32e7eSjoerg   if (Header.IsUmbrella && ActiveModule->Umbrella) {
232806f32e7eSjoerg     Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
232906f32e7eSjoerg       << ActiveModule->getFullModuleName();
233006f32e7eSjoerg     HadError = true;
233106f32e7eSjoerg     return;
233206f32e7eSjoerg   }
233306f32e7eSjoerg 
233406f32e7eSjoerg   // If we were given stat information, parse it so we can skip looking for
233506f32e7eSjoerg   // the file.
233606f32e7eSjoerg   if (Tok.is(MMToken::LBrace)) {
233706f32e7eSjoerg     SourceLocation LBraceLoc = consumeToken();
233806f32e7eSjoerg 
233906f32e7eSjoerg     while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) {
234006f32e7eSjoerg       enum Attribute { Size, ModTime, Unknown };
234106f32e7eSjoerg       StringRef Str = Tok.getString();
234206f32e7eSjoerg       SourceLocation Loc = consumeToken();
234306f32e7eSjoerg       switch (llvm::StringSwitch<Attribute>(Str)
234406f32e7eSjoerg                   .Case("size", Size)
234506f32e7eSjoerg                   .Case("mtime", ModTime)
234606f32e7eSjoerg                   .Default(Unknown)) {
234706f32e7eSjoerg       case Size:
234806f32e7eSjoerg         if (Header.Size)
234906f32e7eSjoerg           Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
235006f32e7eSjoerg         if (!Tok.is(MMToken::IntegerLiteral)) {
235106f32e7eSjoerg           Diags.Report(Tok.getLocation(),
235206f32e7eSjoerg                        diag::err_mmap_invalid_header_attribute_value) << Str;
235306f32e7eSjoerg           skipUntil(MMToken::RBrace);
235406f32e7eSjoerg           break;
235506f32e7eSjoerg         }
235606f32e7eSjoerg         Header.Size = Tok.getInteger();
235706f32e7eSjoerg         consumeToken();
235806f32e7eSjoerg         break;
235906f32e7eSjoerg 
236006f32e7eSjoerg       case ModTime:
236106f32e7eSjoerg         if (Header.ModTime)
236206f32e7eSjoerg           Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
236306f32e7eSjoerg         if (!Tok.is(MMToken::IntegerLiteral)) {
236406f32e7eSjoerg           Diags.Report(Tok.getLocation(),
236506f32e7eSjoerg                        diag::err_mmap_invalid_header_attribute_value) << Str;
236606f32e7eSjoerg           skipUntil(MMToken::RBrace);
236706f32e7eSjoerg           break;
236806f32e7eSjoerg         }
236906f32e7eSjoerg         Header.ModTime = Tok.getInteger();
237006f32e7eSjoerg         consumeToken();
237106f32e7eSjoerg         break;
237206f32e7eSjoerg 
237306f32e7eSjoerg       case Unknown:
237406f32e7eSjoerg         Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
237506f32e7eSjoerg         skipUntil(MMToken::RBrace);
237606f32e7eSjoerg         break;
237706f32e7eSjoerg       }
237806f32e7eSjoerg     }
237906f32e7eSjoerg 
238006f32e7eSjoerg     if (Tok.is(MMToken::RBrace))
238106f32e7eSjoerg       consumeToken();
238206f32e7eSjoerg     else {
238306f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
238406f32e7eSjoerg       Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
238506f32e7eSjoerg       HadError = true;
238606f32e7eSjoerg     }
238706f32e7eSjoerg   }
238806f32e7eSjoerg 
238906f32e7eSjoerg   bool NeedsFramework = false;
239006f32e7eSjoerg   Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
239106f32e7eSjoerg 
239206f32e7eSjoerg   if (NeedsFramework && ActiveModule)
239306f32e7eSjoerg     Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
239406f32e7eSjoerg       << ActiveModule->getFullModuleName()
239506f32e7eSjoerg       << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module");
239606f32e7eSjoerg }
239706f32e7eSjoerg 
compareModuleHeaders(const Module::Header * A,const Module::Header * B)239806f32e7eSjoerg static int compareModuleHeaders(const Module::Header *A,
239906f32e7eSjoerg                                 const Module::Header *B) {
240006f32e7eSjoerg   return A->NameAsWritten.compare(B->NameAsWritten);
240106f32e7eSjoerg }
240206f32e7eSjoerg 
240306f32e7eSjoerg /// Parse an umbrella directory declaration.
240406f32e7eSjoerg ///
240506f32e7eSjoerg ///   umbrella-dir-declaration:
240606f32e7eSjoerg ///     umbrella string-literal
parseUmbrellaDirDecl(SourceLocation UmbrellaLoc)240706f32e7eSjoerg void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
240806f32e7eSjoerg   // Parse the directory name.
240906f32e7eSjoerg   if (!Tok.is(MMToken::StringLiteral)) {
241006f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
241106f32e7eSjoerg       << "umbrella";
241206f32e7eSjoerg     HadError = true;
241306f32e7eSjoerg     return;
241406f32e7eSjoerg   }
241506f32e7eSjoerg 
2416*13fbcb42Sjoerg   std::string DirName = std::string(Tok.getString());
2417*13fbcb42Sjoerg   std::string DirNameAsWritten = DirName;
241806f32e7eSjoerg   SourceLocation DirNameLoc = consumeToken();
241906f32e7eSjoerg 
242006f32e7eSjoerg   // Check whether we already have an umbrella.
242106f32e7eSjoerg   if (ActiveModule->Umbrella) {
242206f32e7eSjoerg     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
242306f32e7eSjoerg       << ActiveModule->getFullModuleName();
242406f32e7eSjoerg     HadError = true;
242506f32e7eSjoerg     return;
242606f32e7eSjoerg   }
242706f32e7eSjoerg 
242806f32e7eSjoerg   // Look for this file.
242906f32e7eSjoerg   const DirectoryEntry *Dir = nullptr;
243006f32e7eSjoerg   if (llvm::sys::path::is_absolute(DirName)) {
243106f32e7eSjoerg     if (auto D = SourceMgr.getFileManager().getDirectory(DirName))
243206f32e7eSjoerg       Dir = *D;
243306f32e7eSjoerg   } else {
243406f32e7eSjoerg     SmallString<128> PathName;
243506f32e7eSjoerg     PathName = Directory->getName();
243606f32e7eSjoerg     llvm::sys::path::append(PathName, DirName);
243706f32e7eSjoerg     if (auto D = SourceMgr.getFileManager().getDirectory(PathName))
243806f32e7eSjoerg       Dir = *D;
243906f32e7eSjoerg   }
244006f32e7eSjoerg 
244106f32e7eSjoerg   if (!Dir) {
244206f32e7eSjoerg     Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
244306f32e7eSjoerg       << DirName;
244406f32e7eSjoerg     return;
244506f32e7eSjoerg   }
244606f32e7eSjoerg 
244706f32e7eSjoerg   if (UsesRequiresExcludedHack.count(ActiveModule)) {
244806f32e7eSjoerg     // Mark this header 'textual' (see doc comment for
244906f32e7eSjoerg     // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
245006f32e7eSjoerg     // directory is relatively expensive, in practice this only applies to the
245106f32e7eSjoerg     // uncommonly used Tcl module on Darwin platforms.
245206f32e7eSjoerg     std::error_code EC;
245306f32e7eSjoerg     SmallVector<Module::Header, 6> Headers;
245406f32e7eSjoerg     llvm::vfs::FileSystem &FS =
245506f32e7eSjoerg         SourceMgr.getFileManager().getVirtualFileSystem();
245606f32e7eSjoerg     for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
245706f32e7eSjoerg          I != E && !EC; I.increment(EC)) {
245806f32e7eSjoerg       if (auto FE = SourceMgr.getFileManager().getFile(I->path())) {
2459*13fbcb42Sjoerg         Module::Header Header = {"", std::string(I->path()), *FE};
246006f32e7eSjoerg         Headers.push_back(std::move(Header));
246106f32e7eSjoerg       }
246206f32e7eSjoerg     }
246306f32e7eSjoerg 
246406f32e7eSjoerg     // Sort header paths so that the pcm doesn't depend on iteration order.
246506f32e7eSjoerg     llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
246606f32e7eSjoerg 
246706f32e7eSjoerg     for (auto &Header : Headers)
246806f32e7eSjoerg       Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
246906f32e7eSjoerg     return;
247006f32e7eSjoerg   }
247106f32e7eSjoerg 
247206f32e7eSjoerg   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
247306f32e7eSjoerg     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
247406f32e7eSjoerg       << OwningModule->getFullModuleName();
247506f32e7eSjoerg     HadError = true;
247606f32e7eSjoerg     return;
247706f32e7eSjoerg   }
247806f32e7eSjoerg 
247906f32e7eSjoerg   // Record this umbrella directory.
2480*13fbcb42Sjoerg   Map.setUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName);
248106f32e7eSjoerg }
248206f32e7eSjoerg 
248306f32e7eSjoerg /// Parse a module export declaration.
248406f32e7eSjoerg ///
248506f32e7eSjoerg ///   export-declaration:
248606f32e7eSjoerg ///     'export' wildcard-module-id
248706f32e7eSjoerg ///
248806f32e7eSjoerg ///   wildcard-module-id:
248906f32e7eSjoerg ///     identifier
249006f32e7eSjoerg ///     '*'
249106f32e7eSjoerg ///     identifier '.' wildcard-module-id
parseExportDecl()249206f32e7eSjoerg void ModuleMapParser::parseExportDecl() {
249306f32e7eSjoerg   assert(Tok.is(MMToken::ExportKeyword));
249406f32e7eSjoerg   SourceLocation ExportLoc = consumeToken();
249506f32e7eSjoerg 
249606f32e7eSjoerg   // Parse the module-id with an optional wildcard at the end.
249706f32e7eSjoerg   ModuleId ParsedModuleId;
249806f32e7eSjoerg   bool Wildcard = false;
249906f32e7eSjoerg   do {
250006f32e7eSjoerg     // FIXME: Support string-literal module names here.
250106f32e7eSjoerg     if (Tok.is(MMToken::Identifier)) {
2502*13fbcb42Sjoerg       ParsedModuleId.push_back(
2503*13fbcb42Sjoerg           std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
250406f32e7eSjoerg       consumeToken();
250506f32e7eSjoerg 
250606f32e7eSjoerg       if (Tok.is(MMToken::Period)) {
250706f32e7eSjoerg         consumeToken();
250806f32e7eSjoerg         continue;
250906f32e7eSjoerg       }
251006f32e7eSjoerg 
251106f32e7eSjoerg       break;
251206f32e7eSjoerg     }
251306f32e7eSjoerg 
251406f32e7eSjoerg     if(Tok.is(MMToken::Star)) {
251506f32e7eSjoerg       Wildcard = true;
251606f32e7eSjoerg       consumeToken();
251706f32e7eSjoerg       break;
251806f32e7eSjoerg     }
251906f32e7eSjoerg 
252006f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
252106f32e7eSjoerg     HadError = true;
252206f32e7eSjoerg     return;
252306f32e7eSjoerg   } while (true);
252406f32e7eSjoerg 
252506f32e7eSjoerg   Module::UnresolvedExportDecl Unresolved = {
252606f32e7eSjoerg     ExportLoc, ParsedModuleId, Wildcard
252706f32e7eSjoerg   };
252806f32e7eSjoerg   ActiveModule->UnresolvedExports.push_back(Unresolved);
252906f32e7eSjoerg }
253006f32e7eSjoerg 
253106f32e7eSjoerg /// Parse a module export_as declaration.
253206f32e7eSjoerg ///
253306f32e7eSjoerg ///   export-as-declaration:
253406f32e7eSjoerg ///     'export_as' identifier
parseExportAsDecl()253506f32e7eSjoerg void ModuleMapParser::parseExportAsDecl() {
253606f32e7eSjoerg   assert(Tok.is(MMToken::ExportAsKeyword));
253706f32e7eSjoerg   consumeToken();
253806f32e7eSjoerg 
253906f32e7eSjoerg   if (!Tok.is(MMToken::Identifier)) {
254006f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
254106f32e7eSjoerg     HadError = true;
254206f32e7eSjoerg     return;
254306f32e7eSjoerg   }
254406f32e7eSjoerg 
254506f32e7eSjoerg   if (ActiveModule->Parent) {
254606f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);
254706f32e7eSjoerg     consumeToken();
254806f32e7eSjoerg     return;
254906f32e7eSjoerg   }
255006f32e7eSjoerg 
255106f32e7eSjoerg   if (!ActiveModule->ExportAsModule.empty()) {
255206f32e7eSjoerg     if (ActiveModule->ExportAsModule == Tok.getString()) {
255306f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as)
255406f32e7eSjoerg         << ActiveModule->Name << Tok.getString();
255506f32e7eSjoerg     } else {
255606f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as)
255706f32e7eSjoerg         << ActiveModule->Name << ActiveModule->ExportAsModule
255806f32e7eSjoerg         << Tok.getString();
255906f32e7eSjoerg     }
256006f32e7eSjoerg   }
256106f32e7eSjoerg 
2562*13fbcb42Sjoerg   ActiveModule->ExportAsModule = std::string(Tok.getString());
256306f32e7eSjoerg   Map.addLinkAsDependency(ActiveModule);
256406f32e7eSjoerg 
256506f32e7eSjoerg   consumeToken();
256606f32e7eSjoerg }
256706f32e7eSjoerg 
256806f32e7eSjoerg /// Parse a module use declaration.
256906f32e7eSjoerg ///
257006f32e7eSjoerg ///   use-declaration:
257106f32e7eSjoerg ///     'use' wildcard-module-id
parseUseDecl()257206f32e7eSjoerg void ModuleMapParser::parseUseDecl() {
257306f32e7eSjoerg   assert(Tok.is(MMToken::UseKeyword));
257406f32e7eSjoerg   auto KWLoc = consumeToken();
257506f32e7eSjoerg   // Parse the module-id.
257606f32e7eSjoerg   ModuleId ParsedModuleId;
257706f32e7eSjoerg   parseModuleId(ParsedModuleId);
257806f32e7eSjoerg 
257906f32e7eSjoerg   if (ActiveModule->Parent)
258006f32e7eSjoerg     Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
258106f32e7eSjoerg   else
258206f32e7eSjoerg     ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
258306f32e7eSjoerg }
258406f32e7eSjoerg 
258506f32e7eSjoerg /// Parse a link declaration.
258606f32e7eSjoerg ///
258706f32e7eSjoerg ///   module-declaration:
258806f32e7eSjoerg ///     'link' 'framework'[opt] string-literal
parseLinkDecl()258906f32e7eSjoerg void ModuleMapParser::parseLinkDecl() {
259006f32e7eSjoerg   assert(Tok.is(MMToken::LinkKeyword));
259106f32e7eSjoerg   SourceLocation LinkLoc = consumeToken();
259206f32e7eSjoerg 
259306f32e7eSjoerg   // Parse the optional 'framework' keyword.
259406f32e7eSjoerg   bool IsFramework = false;
259506f32e7eSjoerg   if (Tok.is(MMToken::FrameworkKeyword)) {
259606f32e7eSjoerg     consumeToken();
259706f32e7eSjoerg     IsFramework = true;
259806f32e7eSjoerg   }
259906f32e7eSjoerg 
260006f32e7eSjoerg   // Parse the library name
260106f32e7eSjoerg   if (!Tok.is(MMToken::StringLiteral)) {
260206f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
260306f32e7eSjoerg       << IsFramework << SourceRange(LinkLoc);
260406f32e7eSjoerg     HadError = true;
260506f32e7eSjoerg     return;
260606f32e7eSjoerg   }
260706f32e7eSjoerg 
2608*13fbcb42Sjoerg   std::string LibraryName = std::string(Tok.getString());
260906f32e7eSjoerg   consumeToken();
261006f32e7eSjoerg   ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
261106f32e7eSjoerg                                                             IsFramework));
261206f32e7eSjoerg }
261306f32e7eSjoerg 
261406f32e7eSjoerg /// Parse a configuration macro declaration.
261506f32e7eSjoerg ///
261606f32e7eSjoerg ///   module-declaration:
261706f32e7eSjoerg ///     'config_macros' attributes[opt] config-macro-list?
261806f32e7eSjoerg ///
261906f32e7eSjoerg ///   config-macro-list:
262006f32e7eSjoerg ///     identifier (',' identifier)?
parseConfigMacros()262106f32e7eSjoerg void ModuleMapParser::parseConfigMacros() {
262206f32e7eSjoerg   assert(Tok.is(MMToken::ConfigMacros));
262306f32e7eSjoerg   SourceLocation ConfigMacrosLoc = consumeToken();
262406f32e7eSjoerg 
262506f32e7eSjoerg   // Only top-level modules can have configuration macros.
262606f32e7eSjoerg   if (ActiveModule->Parent) {
262706f32e7eSjoerg     Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
262806f32e7eSjoerg   }
262906f32e7eSjoerg 
263006f32e7eSjoerg   // Parse the optional attributes.
263106f32e7eSjoerg   Attributes Attrs;
263206f32e7eSjoerg   if (parseOptionalAttributes(Attrs))
263306f32e7eSjoerg     return;
263406f32e7eSjoerg 
263506f32e7eSjoerg   if (Attrs.IsExhaustive && !ActiveModule->Parent) {
263606f32e7eSjoerg     ActiveModule->ConfigMacrosExhaustive = true;
263706f32e7eSjoerg   }
263806f32e7eSjoerg 
263906f32e7eSjoerg   // If we don't have an identifier, we're done.
264006f32e7eSjoerg   // FIXME: Support macros with the same name as a keyword here.
264106f32e7eSjoerg   if (!Tok.is(MMToken::Identifier))
264206f32e7eSjoerg     return;
264306f32e7eSjoerg 
264406f32e7eSjoerg   // Consume the first identifier.
264506f32e7eSjoerg   if (!ActiveModule->Parent) {
264606f32e7eSjoerg     ActiveModule->ConfigMacros.push_back(Tok.getString().str());
264706f32e7eSjoerg   }
264806f32e7eSjoerg   consumeToken();
264906f32e7eSjoerg 
265006f32e7eSjoerg   do {
265106f32e7eSjoerg     // If there's a comma, consume it.
265206f32e7eSjoerg     if (!Tok.is(MMToken::Comma))
265306f32e7eSjoerg       break;
265406f32e7eSjoerg     consumeToken();
265506f32e7eSjoerg 
265606f32e7eSjoerg     // We expect to see a macro name here.
265706f32e7eSjoerg     // FIXME: Support macros with the same name as a keyword here.
265806f32e7eSjoerg     if (!Tok.is(MMToken::Identifier)) {
265906f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
266006f32e7eSjoerg       break;
266106f32e7eSjoerg     }
266206f32e7eSjoerg 
266306f32e7eSjoerg     // Consume the macro name.
266406f32e7eSjoerg     if (!ActiveModule->Parent) {
266506f32e7eSjoerg       ActiveModule->ConfigMacros.push_back(Tok.getString().str());
266606f32e7eSjoerg     }
266706f32e7eSjoerg     consumeToken();
266806f32e7eSjoerg   } while (true);
266906f32e7eSjoerg }
267006f32e7eSjoerg 
267106f32e7eSjoerg /// Format a module-id into a string.
formatModuleId(const ModuleId & Id)267206f32e7eSjoerg static std::string formatModuleId(const ModuleId &Id) {
267306f32e7eSjoerg   std::string result;
267406f32e7eSjoerg   {
267506f32e7eSjoerg     llvm::raw_string_ostream OS(result);
267606f32e7eSjoerg 
267706f32e7eSjoerg     for (unsigned I = 0, N = Id.size(); I != N; ++I) {
267806f32e7eSjoerg       if (I)
267906f32e7eSjoerg         OS << ".";
268006f32e7eSjoerg       OS << Id[I].first;
268106f32e7eSjoerg     }
268206f32e7eSjoerg   }
268306f32e7eSjoerg 
268406f32e7eSjoerg   return result;
268506f32e7eSjoerg }
268606f32e7eSjoerg 
268706f32e7eSjoerg /// Parse a conflict declaration.
268806f32e7eSjoerg ///
268906f32e7eSjoerg ///   module-declaration:
269006f32e7eSjoerg ///     'conflict' module-id ',' string-literal
parseConflict()269106f32e7eSjoerg void ModuleMapParser::parseConflict() {
269206f32e7eSjoerg   assert(Tok.is(MMToken::Conflict));
269306f32e7eSjoerg   SourceLocation ConflictLoc = consumeToken();
269406f32e7eSjoerg   Module::UnresolvedConflict Conflict;
269506f32e7eSjoerg 
269606f32e7eSjoerg   // Parse the module-id.
269706f32e7eSjoerg   if (parseModuleId(Conflict.Id))
269806f32e7eSjoerg     return;
269906f32e7eSjoerg 
270006f32e7eSjoerg   // Parse the ','.
270106f32e7eSjoerg   if (!Tok.is(MMToken::Comma)) {
270206f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
270306f32e7eSjoerg       << SourceRange(ConflictLoc);
270406f32e7eSjoerg     return;
270506f32e7eSjoerg   }
270606f32e7eSjoerg   consumeToken();
270706f32e7eSjoerg 
270806f32e7eSjoerg   // Parse the message.
270906f32e7eSjoerg   if (!Tok.is(MMToken::StringLiteral)) {
271006f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
271106f32e7eSjoerg       << formatModuleId(Conflict.Id);
271206f32e7eSjoerg     return;
271306f32e7eSjoerg   }
271406f32e7eSjoerg   Conflict.Message = Tok.getString().str();
271506f32e7eSjoerg   consumeToken();
271606f32e7eSjoerg 
271706f32e7eSjoerg   // Add this unresolved conflict.
271806f32e7eSjoerg   ActiveModule->UnresolvedConflicts.push_back(Conflict);
271906f32e7eSjoerg }
272006f32e7eSjoerg 
272106f32e7eSjoerg /// Parse an inferred module declaration (wildcard modules).
272206f32e7eSjoerg ///
272306f32e7eSjoerg ///   module-declaration:
272406f32e7eSjoerg ///     'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
272506f32e7eSjoerg ///       { inferred-module-member* }
272606f32e7eSjoerg ///
272706f32e7eSjoerg ///   inferred-module-member:
272806f32e7eSjoerg ///     'export' '*'
272906f32e7eSjoerg ///     'exclude' identifier
parseInferredModuleDecl(bool Framework,bool Explicit)273006f32e7eSjoerg void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
273106f32e7eSjoerg   assert(Tok.is(MMToken::Star));
273206f32e7eSjoerg   SourceLocation StarLoc = consumeToken();
273306f32e7eSjoerg   bool Failed = false;
273406f32e7eSjoerg 
273506f32e7eSjoerg   // Inferred modules must be submodules.
273606f32e7eSjoerg   if (!ActiveModule && !Framework) {
273706f32e7eSjoerg     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
273806f32e7eSjoerg     Failed = true;
273906f32e7eSjoerg   }
274006f32e7eSjoerg 
274106f32e7eSjoerg   if (ActiveModule) {
274206f32e7eSjoerg     // Inferred modules must have umbrella directories.
274306f32e7eSjoerg     if (!Failed && ActiveModule->IsAvailable &&
274406f32e7eSjoerg         !ActiveModule->getUmbrellaDir()) {
274506f32e7eSjoerg       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
274606f32e7eSjoerg       Failed = true;
274706f32e7eSjoerg     }
274806f32e7eSjoerg 
274906f32e7eSjoerg     // Check for redefinition of an inferred module.
275006f32e7eSjoerg     if (!Failed && ActiveModule->InferSubmodules) {
275106f32e7eSjoerg       Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
275206f32e7eSjoerg       if (ActiveModule->InferredSubmoduleLoc.isValid())
275306f32e7eSjoerg         Diags.Report(ActiveModule->InferredSubmoduleLoc,
275406f32e7eSjoerg                      diag::note_mmap_prev_definition);
275506f32e7eSjoerg       Failed = true;
275606f32e7eSjoerg     }
275706f32e7eSjoerg 
275806f32e7eSjoerg     // Check for the 'framework' keyword, which is not permitted here.
275906f32e7eSjoerg     if (Framework) {
276006f32e7eSjoerg       Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
276106f32e7eSjoerg       Framework = false;
276206f32e7eSjoerg     }
276306f32e7eSjoerg   } else if (Explicit) {
276406f32e7eSjoerg     Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
276506f32e7eSjoerg     Explicit = false;
276606f32e7eSjoerg   }
276706f32e7eSjoerg 
276806f32e7eSjoerg   // If there were any problems with this inferred submodule, skip its body.
276906f32e7eSjoerg   if (Failed) {
277006f32e7eSjoerg     if (Tok.is(MMToken::LBrace)) {
277106f32e7eSjoerg       consumeToken();
277206f32e7eSjoerg       skipUntil(MMToken::RBrace);
277306f32e7eSjoerg       if (Tok.is(MMToken::RBrace))
277406f32e7eSjoerg         consumeToken();
277506f32e7eSjoerg     }
277606f32e7eSjoerg     HadError = true;
277706f32e7eSjoerg     return;
277806f32e7eSjoerg   }
277906f32e7eSjoerg 
278006f32e7eSjoerg   // Parse optional attributes.
278106f32e7eSjoerg   Attributes Attrs;
278206f32e7eSjoerg   if (parseOptionalAttributes(Attrs))
278306f32e7eSjoerg     return;
278406f32e7eSjoerg 
278506f32e7eSjoerg   if (ActiveModule) {
278606f32e7eSjoerg     // Note that we have an inferred submodule.
278706f32e7eSjoerg     ActiveModule->InferSubmodules = true;
278806f32e7eSjoerg     ActiveModule->InferredSubmoduleLoc = StarLoc;
278906f32e7eSjoerg     ActiveModule->InferExplicitSubmodules = Explicit;
279006f32e7eSjoerg   } else {
279106f32e7eSjoerg     // We'll be inferring framework modules for this directory.
279206f32e7eSjoerg     Map.InferredDirectories[Directory].InferModules = true;
279306f32e7eSjoerg     Map.InferredDirectories[Directory].Attrs = Attrs;
279406f32e7eSjoerg     Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
279506f32e7eSjoerg     // FIXME: Handle the 'framework' keyword.
279606f32e7eSjoerg   }
279706f32e7eSjoerg 
279806f32e7eSjoerg   // Parse the opening brace.
279906f32e7eSjoerg   if (!Tok.is(MMToken::LBrace)) {
280006f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
280106f32e7eSjoerg     HadError = true;
280206f32e7eSjoerg     return;
280306f32e7eSjoerg   }
280406f32e7eSjoerg   SourceLocation LBraceLoc = consumeToken();
280506f32e7eSjoerg 
280606f32e7eSjoerg   // Parse the body of the inferred submodule.
280706f32e7eSjoerg   bool Done = false;
280806f32e7eSjoerg   do {
280906f32e7eSjoerg     switch (Tok.Kind) {
281006f32e7eSjoerg     case MMToken::EndOfFile:
281106f32e7eSjoerg     case MMToken::RBrace:
281206f32e7eSjoerg       Done = true;
281306f32e7eSjoerg       break;
281406f32e7eSjoerg 
281506f32e7eSjoerg     case MMToken::ExcludeKeyword:
281606f32e7eSjoerg       if (ActiveModule) {
281706f32e7eSjoerg         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
281806f32e7eSjoerg           << (ActiveModule != nullptr);
281906f32e7eSjoerg         consumeToken();
282006f32e7eSjoerg         break;
282106f32e7eSjoerg       }
282206f32e7eSjoerg 
282306f32e7eSjoerg       consumeToken();
282406f32e7eSjoerg       // FIXME: Support string-literal module names here.
282506f32e7eSjoerg       if (!Tok.is(MMToken::Identifier)) {
282606f32e7eSjoerg         Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
282706f32e7eSjoerg         break;
282806f32e7eSjoerg       }
282906f32e7eSjoerg 
2830*13fbcb42Sjoerg       Map.InferredDirectories[Directory].ExcludedModules.push_back(
2831*13fbcb42Sjoerg           std::string(Tok.getString()));
283206f32e7eSjoerg       consumeToken();
283306f32e7eSjoerg       break;
283406f32e7eSjoerg 
283506f32e7eSjoerg     case MMToken::ExportKeyword:
283606f32e7eSjoerg       if (!ActiveModule) {
283706f32e7eSjoerg         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
283806f32e7eSjoerg           << (ActiveModule != nullptr);
283906f32e7eSjoerg         consumeToken();
284006f32e7eSjoerg         break;
284106f32e7eSjoerg       }
284206f32e7eSjoerg 
284306f32e7eSjoerg       consumeToken();
284406f32e7eSjoerg       if (Tok.is(MMToken::Star))
284506f32e7eSjoerg         ActiveModule->InferExportWildcard = true;
284606f32e7eSjoerg       else
284706f32e7eSjoerg         Diags.Report(Tok.getLocation(),
284806f32e7eSjoerg                      diag::err_mmap_expected_export_wildcard);
284906f32e7eSjoerg       consumeToken();
285006f32e7eSjoerg       break;
285106f32e7eSjoerg 
285206f32e7eSjoerg     case MMToken::ExplicitKeyword:
285306f32e7eSjoerg     case MMToken::ModuleKeyword:
285406f32e7eSjoerg     case MMToken::HeaderKeyword:
285506f32e7eSjoerg     case MMToken::PrivateKeyword:
285606f32e7eSjoerg     case MMToken::UmbrellaKeyword:
285706f32e7eSjoerg     default:
285806f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
285906f32e7eSjoerg           << (ActiveModule != nullptr);
286006f32e7eSjoerg       consumeToken();
286106f32e7eSjoerg       break;
286206f32e7eSjoerg     }
286306f32e7eSjoerg   } while (!Done);
286406f32e7eSjoerg 
286506f32e7eSjoerg   if (Tok.is(MMToken::RBrace))
286606f32e7eSjoerg     consumeToken();
286706f32e7eSjoerg   else {
286806f32e7eSjoerg     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
286906f32e7eSjoerg     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
287006f32e7eSjoerg     HadError = true;
287106f32e7eSjoerg   }
287206f32e7eSjoerg }
287306f32e7eSjoerg 
287406f32e7eSjoerg /// Parse optional attributes.
287506f32e7eSjoerg ///
287606f32e7eSjoerg ///   attributes:
287706f32e7eSjoerg ///     attribute attributes
287806f32e7eSjoerg ///     attribute
287906f32e7eSjoerg ///
288006f32e7eSjoerg ///   attribute:
288106f32e7eSjoerg ///     [ identifier ]
288206f32e7eSjoerg ///
288306f32e7eSjoerg /// \param Attrs Will be filled in with the parsed attributes.
288406f32e7eSjoerg ///
288506f32e7eSjoerg /// \returns true if an error occurred, false otherwise.
parseOptionalAttributes(Attributes & Attrs)288606f32e7eSjoerg bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
288706f32e7eSjoerg   bool HadError = false;
288806f32e7eSjoerg 
288906f32e7eSjoerg   while (Tok.is(MMToken::LSquare)) {
289006f32e7eSjoerg     // Consume the '['.
289106f32e7eSjoerg     SourceLocation LSquareLoc = consumeToken();
289206f32e7eSjoerg 
289306f32e7eSjoerg     // Check whether we have an attribute name here.
289406f32e7eSjoerg     if (!Tok.is(MMToken::Identifier)) {
289506f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
289606f32e7eSjoerg       skipUntil(MMToken::RSquare);
289706f32e7eSjoerg       if (Tok.is(MMToken::RSquare))
289806f32e7eSjoerg         consumeToken();
289906f32e7eSjoerg       HadError = true;
290006f32e7eSjoerg     }
290106f32e7eSjoerg 
290206f32e7eSjoerg     // Decode the attribute name.
290306f32e7eSjoerg     AttributeKind Attribute
290406f32e7eSjoerg       = llvm::StringSwitch<AttributeKind>(Tok.getString())
290506f32e7eSjoerg           .Case("exhaustive", AT_exhaustive)
290606f32e7eSjoerg           .Case("extern_c", AT_extern_c)
290706f32e7eSjoerg           .Case("no_undeclared_includes", AT_no_undeclared_includes)
290806f32e7eSjoerg           .Case("system", AT_system)
290906f32e7eSjoerg           .Default(AT_unknown);
291006f32e7eSjoerg     switch (Attribute) {
291106f32e7eSjoerg     case AT_unknown:
291206f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
291306f32e7eSjoerg         << Tok.getString();
291406f32e7eSjoerg       break;
291506f32e7eSjoerg 
291606f32e7eSjoerg     case AT_system:
291706f32e7eSjoerg       Attrs.IsSystem = true;
291806f32e7eSjoerg       break;
291906f32e7eSjoerg 
292006f32e7eSjoerg     case AT_extern_c:
292106f32e7eSjoerg       Attrs.IsExternC = true;
292206f32e7eSjoerg       break;
292306f32e7eSjoerg 
292406f32e7eSjoerg     case AT_exhaustive:
292506f32e7eSjoerg       Attrs.IsExhaustive = true;
292606f32e7eSjoerg       break;
292706f32e7eSjoerg 
292806f32e7eSjoerg     case AT_no_undeclared_includes:
292906f32e7eSjoerg       Attrs.NoUndeclaredIncludes = true;
293006f32e7eSjoerg       break;
293106f32e7eSjoerg     }
293206f32e7eSjoerg     consumeToken();
293306f32e7eSjoerg 
293406f32e7eSjoerg     // Consume the ']'.
293506f32e7eSjoerg     if (!Tok.is(MMToken::RSquare)) {
293606f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
293706f32e7eSjoerg       Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
293806f32e7eSjoerg       skipUntil(MMToken::RSquare);
293906f32e7eSjoerg       HadError = true;
294006f32e7eSjoerg     }
294106f32e7eSjoerg 
294206f32e7eSjoerg     if (Tok.is(MMToken::RSquare))
294306f32e7eSjoerg       consumeToken();
294406f32e7eSjoerg   }
294506f32e7eSjoerg 
294606f32e7eSjoerg   return HadError;
294706f32e7eSjoerg }
294806f32e7eSjoerg 
294906f32e7eSjoerg /// Parse a module map file.
295006f32e7eSjoerg ///
295106f32e7eSjoerg ///   module-map-file:
295206f32e7eSjoerg ///     module-declaration*
parseModuleMapFile()295306f32e7eSjoerg bool ModuleMapParser::parseModuleMapFile() {
295406f32e7eSjoerg   do {
295506f32e7eSjoerg     switch (Tok.Kind) {
295606f32e7eSjoerg     case MMToken::EndOfFile:
295706f32e7eSjoerg       return HadError;
295806f32e7eSjoerg 
295906f32e7eSjoerg     case MMToken::ExplicitKeyword:
296006f32e7eSjoerg     case MMToken::ExternKeyword:
296106f32e7eSjoerg     case MMToken::ModuleKeyword:
296206f32e7eSjoerg     case MMToken::FrameworkKeyword:
296306f32e7eSjoerg       parseModuleDecl();
296406f32e7eSjoerg       break;
296506f32e7eSjoerg 
296606f32e7eSjoerg     case MMToken::Comma:
296706f32e7eSjoerg     case MMToken::ConfigMacros:
296806f32e7eSjoerg     case MMToken::Conflict:
296906f32e7eSjoerg     case MMToken::Exclaim:
297006f32e7eSjoerg     case MMToken::ExcludeKeyword:
297106f32e7eSjoerg     case MMToken::ExportKeyword:
297206f32e7eSjoerg     case MMToken::ExportAsKeyword:
297306f32e7eSjoerg     case MMToken::HeaderKeyword:
297406f32e7eSjoerg     case MMToken::Identifier:
297506f32e7eSjoerg     case MMToken::LBrace:
297606f32e7eSjoerg     case MMToken::LinkKeyword:
297706f32e7eSjoerg     case MMToken::LSquare:
297806f32e7eSjoerg     case MMToken::Period:
297906f32e7eSjoerg     case MMToken::PrivateKeyword:
298006f32e7eSjoerg     case MMToken::RBrace:
298106f32e7eSjoerg     case MMToken::RSquare:
298206f32e7eSjoerg     case MMToken::RequiresKeyword:
298306f32e7eSjoerg     case MMToken::Star:
298406f32e7eSjoerg     case MMToken::StringLiteral:
298506f32e7eSjoerg     case MMToken::IntegerLiteral:
298606f32e7eSjoerg     case MMToken::TextualKeyword:
298706f32e7eSjoerg     case MMToken::UmbrellaKeyword:
298806f32e7eSjoerg     case MMToken::UseKeyword:
298906f32e7eSjoerg       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
299006f32e7eSjoerg       HadError = true;
299106f32e7eSjoerg       consumeToken();
299206f32e7eSjoerg       break;
299306f32e7eSjoerg     }
299406f32e7eSjoerg   } while (true);
299506f32e7eSjoerg }
299606f32e7eSjoerg 
parseModuleMapFile(const FileEntry * File,bool IsSystem,const DirectoryEntry * Dir,FileID ID,unsigned * Offset,SourceLocation ExternModuleLoc)299706f32e7eSjoerg bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
299806f32e7eSjoerg                                    const DirectoryEntry *Dir, FileID ID,
299906f32e7eSjoerg                                    unsigned *Offset,
300006f32e7eSjoerg                                    SourceLocation ExternModuleLoc) {
300106f32e7eSjoerg   assert(Target && "Missing target information");
300206f32e7eSjoerg   llvm::DenseMap<const FileEntry *, bool>::iterator Known
300306f32e7eSjoerg     = ParsedModuleMap.find(File);
300406f32e7eSjoerg   if (Known != ParsedModuleMap.end())
300506f32e7eSjoerg     return Known->second;
300606f32e7eSjoerg 
300706f32e7eSjoerg   // If the module map file wasn't already entered, do so now.
300806f32e7eSjoerg   if (ID.isInvalid()) {
300906f32e7eSjoerg     auto FileCharacter =
301006f32e7eSjoerg         IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
301106f32e7eSjoerg     ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
301206f32e7eSjoerg   }
301306f32e7eSjoerg 
301406f32e7eSjoerg   assert(Target && "Missing target information");
3015*13fbcb42Sjoerg   llvm::Optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
301606f32e7eSjoerg   if (!Buffer)
301706f32e7eSjoerg     return ParsedModuleMap[File] = true;
301806f32e7eSjoerg   assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
301906f32e7eSjoerg          "invalid buffer offset");
302006f32e7eSjoerg 
302106f32e7eSjoerg   // Parse this module map file.
302206f32e7eSjoerg   Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
302306f32e7eSjoerg           Buffer->getBufferStart(),
302406f32e7eSjoerg           Buffer->getBufferStart() + (Offset ? *Offset : 0),
302506f32e7eSjoerg           Buffer->getBufferEnd());
302606f32e7eSjoerg   SourceLocation Start = L.getSourceLocation();
302706f32e7eSjoerg   ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
302806f32e7eSjoerg                          IsSystem);
302906f32e7eSjoerg   bool Result = Parser.parseModuleMapFile();
303006f32e7eSjoerg   ParsedModuleMap[File] = Result;
303106f32e7eSjoerg 
303206f32e7eSjoerg   if (Offset) {
303306f32e7eSjoerg     auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation());
303406f32e7eSjoerg     assert(Loc.first == ID && "stopped in a different file?");
303506f32e7eSjoerg     *Offset = Loc.second;
303606f32e7eSjoerg   }
303706f32e7eSjoerg 
303806f32e7eSjoerg   // Notify callbacks that we parsed it.
303906f32e7eSjoerg   for (const auto &Cb : Callbacks)
304006f32e7eSjoerg     Cb->moduleMapFileRead(Start, *File, IsSystem);
304106f32e7eSjoerg 
304206f32e7eSjoerg   return Result;
304306f32e7eSjoerg }
3044