10b57cec5SDimitry Andric //===- ModuleMap.cpp - Describe the layout of modules ---------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the ModuleMap implementation, which describes the layout
100b57cec5SDimitry Andric // of a module as it relates to headers.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "clang/Lex/ModuleMap.h"
150b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h"
160b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h"
170b57cec5SDimitry Andric #include "clang/Basic/FileManager.h"
180b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
190b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
200b57cec5SDimitry Andric #include "clang/Basic/Module.h"
210b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
220b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
230b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
240b57cec5SDimitry Andric #include "clang/Lex/HeaderSearch.h"
250b57cec5SDimitry Andric #include "clang/Lex/HeaderSearchOptions.h"
260b57cec5SDimitry Andric #include "clang/Lex/LexDiagnostic.h"
270b57cec5SDimitry Andric #include "clang/Lex/Lexer.h"
280b57cec5SDimitry Andric #include "clang/Lex/LiteralSupport.h"
290b57cec5SDimitry Andric #include "clang/Lex/Token.h"
300b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
310b57cec5SDimitry Andric #include "llvm/ADT/None.h"
320b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
330b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
340b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
350b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
360b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h"
370b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
380b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
390b57cec5SDimitry Andric #include "llvm/Support/Allocator.h"
400b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
410b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
420b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
430b57cec5SDimitry Andric #include "llvm/Support/Path.h"
440b57cec5SDimitry Andric #include "llvm/Support/VirtualFileSystem.h"
450b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
460b57cec5SDimitry Andric #include <algorithm>
470b57cec5SDimitry Andric #include <cassert>
480b57cec5SDimitry Andric #include <cstdint>
490b57cec5SDimitry Andric #include <cstring>
500b57cec5SDimitry Andric #include <string>
510b57cec5SDimitry Andric #include <system_error>
520b57cec5SDimitry Andric #include <utility>
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric using namespace clang;
550b57cec5SDimitry Andric 
anchor()560b57cec5SDimitry Andric void ModuleMapCallbacks::anchor() {}
570b57cec5SDimitry Andric 
resolveLinkAsDependencies(Module * Mod)580b57cec5SDimitry Andric void ModuleMap::resolveLinkAsDependencies(Module *Mod) {
590b57cec5SDimitry Andric   auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);
600b57cec5SDimitry Andric   if (PendingLinkAs != PendingLinkAsModule.end()) {
610b57cec5SDimitry Andric     for (auto &Name : PendingLinkAs->second) {
620b57cec5SDimitry Andric       auto *M = findModule(Name.getKey());
630b57cec5SDimitry Andric       if (M)
640b57cec5SDimitry Andric         M->UseExportAsModuleLinkName = true;
650b57cec5SDimitry Andric     }
660b57cec5SDimitry Andric   }
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric 
addLinkAsDependency(Module * Mod)690b57cec5SDimitry Andric void ModuleMap::addLinkAsDependency(Module *Mod) {
700b57cec5SDimitry Andric   if (findModule(Mod->ExportAsModule))
710b57cec5SDimitry Andric     Mod->UseExportAsModuleLinkName = true;
720b57cec5SDimitry Andric   else
730b57cec5SDimitry Andric     PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name);
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric 
headerRoleToKind(ModuleHeaderRole Role)760b57cec5SDimitry Andric Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) {
770b57cec5SDimitry Andric   switch ((int)Role) {
780b57cec5SDimitry Andric   default: llvm_unreachable("unknown header role");
790b57cec5SDimitry Andric   case NormalHeader:
800b57cec5SDimitry Andric     return Module::HK_Normal;
810b57cec5SDimitry Andric   case PrivateHeader:
820b57cec5SDimitry Andric     return Module::HK_Private;
830b57cec5SDimitry Andric   case TextualHeader:
840b57cec5SDimitry Andric     return Module::HK_Textual;
850b57cec5SDimitry Andric   case PrivateHeader | TextualHeader:
860b57cec5SDimitry Andric     return Module::HK_PrivateTextual;
870b57cec5SDimitry Andric   }
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric ModuleMap::ModuleHeaderRole
headerKindToRole(Module::HeaderKind Kind)910b57cec5SDimitry Andric ModuleMap::headerKindToRole(Module::HeaderKind Kind) {
920b57cec5SDimitry Andric   switch ((int)Kind) {
930b57cec5SDimitry Andric   case Module::HK_Normal:
940b57cec5SDimitry Andric     return NormalHeader;
950b57cec5SDimitry Andric   case Module::HK_Private:
960b57cec5SDimitry Andric     return PrivateHeader;
970b57cec5SDimitry Andric   case Module::HK_Textual:
980b57cec5SDimitry Andric     return TextualHeader;
990b57cec5SDimitry Andric   case Module::HK_PrivateTextual:
1000b57cec5SDimitry Andric     return ModuleHeaderRole(PrivateHeader | TextualHeader);
1010b57cec5SDimitry Andric   case Module::HK_Excluded:
1020b57cec5SDimitry Andric     llvm_unreachable("unexpected header kind");
1030b57cec5SDimitry Andric   }
1040b57cec5SDimitry Andric   llvm_unreachable("unknown header kind");
1050b57cec5SDimitry Andric }
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric Module::ExportDecl
resolveExport(Module * Mod,const Module::UnresolvedExportDecl & Unresolved,bool Complain) const1080b57cec5SDimitry Andric ModuleMap::resolveExport(Module *Mod,
1090b57cec5SDimitry Andric                          const Module::UnresolvedExportDecl &Unresolved,
1100b57cec5SDimitry Andric                          bool Complain) const {
1110b57cec5SDimitry Andric   // We may have just a wildcard.
1120b57cec5SDimitry Andric   if (Unresolved.Id.empty()) {
1130b57cec5SDimitry Andric     assert(Unresolved.Wildcard && "Invalid unresolved export");
1140b57cec5SDimitry Andric     return Module::ExportDecl(nullptr, true);
1150b57cec5SDimitry Andric   }
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   // Resolve the module-id.
1180b57cec5SDimitry Andric   Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
1190b57cec5SDimitry Andric   if (!Context)
1200b57cec5SDimitry Andric     return {};
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   return Module::ExportDecl(Context, Unresolved.Wildcard);
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric 
resolveModuleId(const ModuleId & Id,Module * Mod,bool Complain) const1250b57cec5SDimitry Andric Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
1260b57cec5SDimitry Andric                                    bool Complain) const {
1270b57cec5SDimitry Andric   // Find the starting module.
1280b57cec5SDimitry Andric   Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
1290b57cec5SDimitry Andric   if (!Context) {
1300b57cec5SDimitry Andric     if (Complain)
1310b57cec5SDimitry Andric       Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
1320b57cec5SDimitry Andric       << Id[0].first << Mod->getFullModuleName();
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric     return nullptr;
1350b57cec5SDimitry Andric   }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   // Dig into the module path.
1380b57cec5SDimitry Andric   for (unsigned I = 1, N = Id.size(); I != N; ++I) {
1390b57cec5SDimitry Andric     Module *Sub = lookupModuleQualified(Id[I].first, Context);
1400b57cec5SDimitry Andric     if (!Sub) {
1410b57cec5SDimitry Andric       if (Complain)
1420b57cec5SDimitry Andric         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1430b57cec5SDimitry Andric         << Id[I].first << Context->getFullModuleName()
1440b57cec5SDimitry Andric         << SourceRange(Id[0].second, Id[I-1].second);
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric       return nullptr;
1470b57cec5SDimitry Andric     }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric     Context = Sub;
1500b57cec5SDimitry Andric   }
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric   return Context;
1530b57cec5SDimitry Andric }
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric /// Append to \p Paths the set of paths needed to get to the
1560b57cec5SDimitry Andric /// subframework in which the given module lives.
appendSubframeworkPaths(Module * Mod,SmallVectorImpl<char> & Path)1570b57cec5SDimitry Andric static void appendSubframeworkPaths(Module *Mod,
1580b57cec5SDimitry Andric                                     SmallVectorImpl<char> &Path) {
1590b57cec5SDimitry Andric   // Collect the framework names from the given module to the top-level module.
1600b57cec5SDimitry Andric   SmallVector<StringRef, 2> Paths;
1610b57cec5SDimitry Andric   for (; Mod; Mod = Mod->Parent) {
1620b57cec5SDimitry Andric     if (Mod->IsFramework)
1630b57cec5SDimitry Andric       Paths.push_back(Mod->Name);
1640b57cec5SDimitry Andric   }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   if (Paths.empty())
1670b57cec5SDimitry Andric     return;
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   // Add Frameworks/Name.framework for each subframework.
1700b57cec5SDimitry Andric   for (unsigned I = Paths.size() - 1; I != 0; --I)
1710b57cec5SDimitry Andric     llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
1720b57cec5SDimitry Andric }
1730b57cec5SDimitry Andric 
findHeader(Module * M,const Module::UnresolvedHeaderDirective & Header,SmallVectorImpl<char> & RelativePathName,bool & NeedsFramework)174af732203SDimitry Andric Optional<FileEntryRef> ModuleMap::findHeader(
1750b57cec5SDimitry Andric     Module *M, const Module::UnresolvedHeaderDirective &Header,
1760b57cec5SDimitry Andric     SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) {
1770b57cec5SDimitry Andric   // Search for the header file within the module's home directory.
1780b57cec5SDimitry Andric   auto *Directory = M->Directory;
1790b57cec5SDimitry Andric   SmallString<128> FullPathName(Directory->getName());
1800b57cec5SDimitry Andric 
181af732203SDimitry Andric   auto GetFile = [&](StringRef Filename) -> Optional<FileEntryRef> {
182af732203SDimitry Andric     auto File =
183af732203SDimitry Andric         expectedToOptional(SourceMgr.getFileManager().getFileRef(Filename));
184af732203SDimitry Andric     if (!File || (Header.Size && File->getSize() != *Header.Size) ||
185af732203SDimitry Andric         (Header.ModTime && File->getModificationTime() != *Header.ModTime))
186af732203SDimitry Andric       return None;
187a7dea167SDimitry Andric     return *File;
1880b57cec5SDimitry Andric   };
1890b57cec5SDimitry Andric 
190af732203SDimitry Andric   auto GetFrameworkFile = [&]() -> Optional<FileEntryRef> {
1910b57cec5SDimitry Andric     unsigned FullPathLength = FullPathName.size();
1920b57cec5SDimitry Andric     appendSubframeworkPaths(M, RelativePathName);
1930b57cec5SDimitry Andric     unsigned RelativePathLength = RelativePathName.size();
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric     // Check whether this file is in the public headers.
1960b57cec5SDimitry Andric     llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
1970b57cec5SDimitry Andric     llvm::sys::path::append(FullPathName, RelativePathName);
198af732203SDimitry Andric     if (auto File = GetFile(FullPathName))
1990b57cec5SDimitry Andric       return File;
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric     // Check whether this file is in the private headers.
2020b57cec5SDimitry Andric     // Ideally, private modules in the form 'FrameworkName.Private' should
2030b57cec5SDimitry Andric     // be defined as 'module FrameworkName.Private', and not as
2040b57cec5SDimitry Andric     // 'framework module FrameworkName.Private', since a 'Private.Framework'
2050b57cec5SDimitry Andric     // does not usually exist. However, since both are currently widely used
2060b57cec5SDimitry Andric     // for private modules, make sure we find the right path in both cases.
2070b57cec5SDimitry Andric     if (M->IsFramework && M->Name == "Private")
2080b57cec5SDimitry Andric       RelativePathName.clear();
2090b57cec5SDimitry Andric     else
2100b57cec5SDimitry Andric       RelativePathName.resize(RelativePathLength);
2110b57cec5SDimitry Andric     FullPathName.resize(FullPathLength);
2120b57cec5SDimitry Andric     llvm::sys::path::append(RelativePathName, "PrivateHeaders",
2130b57cec5SDimitry Andric                             Header.FileName);
2140b57cec5SDimitry Andric     llvm::sys::path::append(FullPathName, RelativePathName);
2150b57cec5SDimitry Andric     return GetFile(FullPathName);
2160b57cec5SDimitry Andric   };
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric   if (llvm::sys::path::is_absolute(Header.FileName)) {
2190b57cec5SDimitry Andric     RelativePathName.clear();
2200b57cec5SDimitry Andric     RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
2210b57cec5SDimitry Andric     return GetFile(Header.FileName);
2220b57cec5SDimitry Andric   }
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   if (M->isPartOfFramework())
2250b57cec5SDimitry Andric     return GetFrameworkFile();
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric   // Lookup for normal headers.
2280b57cec5SDimitry Andric   llvm::sys::path::append(RelativePathName, Header.FileName);
2290b57cec5SDimitry Andric   llvm::sys::path::append(FullPathName, RelativePathName);
230af732203SDimitry Andric   auto NormalHdrFile = GetFile(FullPathName);
2310b57cec5SDimitry Andric 
232480093f4SDimitry Andric   if (!NormalHdrFile && Directory->getName().endswith(".framework")) {
2330b57cec5SDimitry Andric     // The lack of 'framework' keyword in a module declaration it's a simple
2340b57cec5SDimitry Andric     // mistake we can diagnose when the header exists within the proper
2350b57cec5SDimitry Andric     // framework style path.
2360b57cec5SDimitry Andric     FullPathName.assign(Directory->getName());
2370b57cec5SDimitry Andric     RelativePathName.clear();
2380b57cec5SDimitry Andric     if (GetFrameworkFile()) {
2390b57cec5SDimitry Andric       Diags.Report(Header.FileNameLoc,
2400b57cec5SDimitry Andric                    diag::warn_mmap_incomplete_framework_module_declaration)
2410b57cec5SDimitry Andric           << Header.FileName << M->getFullModuleName();
2420b57cec5SDimitry Andric       NeedsFramework = true;
2430b57cec5SDimitry Andric     }
244af732203SDimitry Andric     return None;
2450b57cec5SDimitry Andric   }
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   return NormalHdrFile;
2480b57cec5SDimitry Andric }
2490b57cec5SDimitry Andric 
resolveHeader(Module * Mod,const Module::UnresolvedHeaderDirective & Header,bool & NeedsFramework)2500b57cec5SDimitry Andric void ModuleMap::resolveHeader(Module *Mod,
2510b57cec5SDimitry Andric                               const Module::UnresolvedHeaderDirective &Header,
2520b57cec5SDimitry Andric                               bool &NeedsFramework) {
2530b57cec5SDimitry Andric   SmallString<128> RelativePathName;
254af732203SDimitry Andric   if (Optional<FileEntryRef> File =
2550b57cec5SDimitry Andric           findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
2560b57cec5SDimitry Andric     if (Header.IsUmbrella) {
257af732203SDimitry Andric       const DirectoryEntry *UmbrellaDir = &File->getDir().getDirEntry();
2580b57cec5SDimitry Andric       if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
2590b57cec5SDimitry Andric         Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
2600b57cec5SDimitry Andric           << UmbrellaMod->getFullModuleName();
2610b57cec5SDimitry Andric       else
2620b57cec5SDimitry Andric         // Record this umbrella header.
263*5f7ddb14SDimitry Andric         setUmbrellaHeader(Mod, *File, Header.FileName, RelativePathName.str());
2640b57cec5SDimitry Andric     } else {
265*5f7ddb14SDimitry Andric       Module::Header H = {Header.FileName, std::string(RelativePathName.str()),
266*5f7ddb14SDimitry Andric                           *File};
2670b57cec5SDimitry Andric       if (Header.Kind == Module::HK_Excluded)
2680b57cec5SDimitry Andric         excludeHeader(Mod, H);
2690b57cec5SDimitry Andric       else
2700b57cec5SDimitry Andric         addHeader(Mod, H, headerKindToRole(Header.Kind));
2710b57cec5SDimitry Andric     }
2720b57cec5SDimitry Andric   } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) {
2730b57cec5SDimitry Andric     // There's a builtin header but no corresponding on-disk header. Assume
2740b57cec5SDimitry Andric     // this was supposed to modularize the builtin header alone.
2750b57cec5SDimitry Andric   } else if (Header.Kind == Module::HK_Excluded) {
2760b57cec5SDimitry Andric     // Ignore missing excluded header files. They're optional anyway.
2770b57cec5SDimitry Andric   } else {
2780b57cec5SDimitry Andric     // If we find a module that has a missing header, we mark this module as
2790b57cec5SDimitry Andric     // unavailable and store the header directive for displaying diagnostics.
2800b57cec5SDimitry Andric     Mod->MissingHeaders.push_back(Header);
2810b57cec5SDimitry Andric     // A missing header with stat information doesn't make the module
2820b57cec5SDimitry Andric     // unavailable; this keeps our behavior consistent as headers are lazily
2830b57cec5SDimitry Andric     // resolved. (Such a module still can't be built though, except from
2840b57cec5SDimitry Andric     // preprocessed source.)
2850b57cec5SDimitry Andric     if (!Header.Size && !Header.ModTime)
2865ffd83dbSDimitry Andric       Mod->markUnavailable(/*Unimportable=*/false);
2870b57cec5SDimitry Andric   }
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric 
resolveAsBuiltinHeader(Module * Mod,const Module::UnresolvedHeaderDirective & Header)2900b57cec5SDimitry Andric bool ModuleMap::resolveAsBuiltinHeader(
2910b57cec5SDimitry Andric     Module *Mod, const Module::UnresolvedHeaderDirective &Header) {
2920b57cec5SDimitry Andric   if (Header.Kind == Module::HK_Excluded ||
2930b57cec5SDimitry Andric       llvm::sys::path::is_absolute(Header.FileName) ||
2940b57cec5SDimitry Andric       Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
2950b57cec5SDimitry Andric       !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
2960b57cec5SDimitry Andric       !isBuiltinHeader(Header.FileName))
2970b57cec5SDimitry Andric     return false;
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   // This is a system module with a top-level header. This header
3000b57cec5SDimitry Andric   // may have a counterpart (or replacement) in the set of headers
3010b57cec5SDimitry Andric   // supplied by Clang. Find that builtin header.
3020b57cec5SDimitry Andric   SmallString<128> Path;
3030b57cec5SDimitry Andric   llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
304*5f7ddb14SDimitry Andric   auto File = SourceMgr.getFileManager().getFile(Path);
3050b57cec5SDimitry Andric   if (!File)
3060b57cec5SDimitry Andric     return false;
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   auto Role = headerKindToRole(Header.Kind);
309*5f7ddb14SDimitry Andric   Module::Header H = {Header.FileName, std::string(Path.str()), *File};
3100b57cec5SDimitry Andric   addHeader(Mod, H, Role);
3110b57cec5SDimitry Andric   return true;
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric 
ModuleMap(SourceManager & SourceMgr,DiagnosticsEngine & Diags,const LangOptions & LangOpts,const TargetInfo * Target,HeaderSearch & HeaderInfo)3140b57cec5SDimitry Andric ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
3150b57cec5SDimitry Andric                      const LangOptions &LangOpts, const TargetInfo *Target,
3160b57cec5SDimitry Andric                      HeaderSearch &HeaderInfo)
3170b57cec5SDimitry Andric     : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
3180b57cec5SDimitry Andric       HeaderInfo(HeaderInfo) {
3190b57cec5SDimitry Andric   MMapLangOpts.LineComment = true;
3200b57cec5SDimitry Andric }
3210b57cec5SDimitry Andric 
~ModuleMap()3220b57cec5SDimitry Andric ModuleMap::~ModuleMap() {
3230b57cec5SDimitry Andric   for (auto &M : Modules)
3240b57cec5SDimitry Andric     delete M.getValue();
3250b57cec5SDimitry Andric   for (auto *M : ShadowModules)
3260b57cec5SDimitry Andric     delete M;
3270b57cec5SDimitry Andric }
3280b57cec5SDimitry Andric 
setTarget(const TargetInfo & Target)3290b57cec5SDimitry Andric void ModuleMap::setTarget(const TargetInfo &Target) {
3300b57cec5SDimitry Andric   assert((!this->Target || this->Target == &Target) &&
3310b57cec5SDimitry Andric          "Improper target override");
3320b57cec5SDimitry Andric   this->Target = &Target;
3330b57cec5SDimitry Andric }
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric /// "Sanitize" a filename so that it can be used as an identifier.
sanitizeFilenameAsIdentifier(StringRef Name,SmallVectorImpl<char> & Buffer)3360b57cec5SDimitry Andric static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
3370b57cec5SDimitry Andric                                               SmallVectorImpl<char> &Buffer) {
3380b57cec5SDimitry Andric   if (Name.empty())
3390b57cec5SDimitry Andric     return Name;
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric   if (!isValidIdentifier(Name)) {
3420b57cec5SDimitry Andric     // If we don't already have something with the form of an identifier,
3430b57cec5SDimitry Andric     // create a buffer with the sanitized name.
3440b57cec5SDimitry Andric     Buffer.clear();
3450b57cec5SDimitry Andric     if (isDigit(Name[0]))
3460b57cec5SDimitry Andric       Buffer.push_back('_');
3470b57cec5SDimitry Andric     Buffer.reserve(Buffer.size() + Name.size());
3480b57cec5SDimitry Andric     for (unsigned I = 0, N = Name.size(); I != N; ++I) {
3490b57cec5SDimitry Andric       if (isIdentifierBody(Name[I]))
3500b57cec5SDimitry Andric         Buffer.push_back(Name[I]);
3510b57cec5SDimitry Andric       else
3520b57cec5SDimitry Andric         Buffer.push_back('_');
3530b57cec5SDimitry Andric     }
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric     Name = StringRef(Buffer.data(), Buffer.size());
3560b57cec5SDimitry Andric   }
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric   while (llvm::StringSwitch<bool>(Name)
3590b57cec5SDimitry Andric #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
3600b57cec5SDimitry Andric #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
3610b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def"
3620b57cec5SDimitry Andric            .Default(false)) {
3630b57cec5SDimitry Andric     if (Name.data() != Buffer.data())
3640b57cec5SDimitry Andric       Buffer.append(Name.begin(), Name.end());
3650b57cec5SDimitry Andric     Buffer.push_back('_');
3660b57cec5SDimitry Andric     Name = StringRef(Buffer.data(), Buffer.size());
3670b57cec5SDimitry Andric   }
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric   return Name;
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric /// Determine whether the given file name is the name of a builtin
3730b57cec5SDimitry Andric /// header, supplied by Clang to replace, override, or augment existing system
3740b57cec5SDimitry Andric /// headers.
isBuiltinHeader(StringRef FileName)3750b57cec5SDimitry Andric bool ModuleMap::isBuiltinHeader(StringRef FileName) {
3760b57cec5SDimitry Andric   return llvm::StringSwitch<bool>(FileName)
3770b57cec5SDimitry Andric            .Case("float.h", true)
3780b57cec5SDimitry Andric            .Case("iso646.h", true)
3790b57cec5SDimitry Andric            .Case("limits.h", true)
3800b57cec5SDimitry Andric            .Case("stdalign.h", true)
3810b57cec5SDimitry Andric            .Case("stdarg.h", true)
3820b57cec5SDimitry Andric            .Case("stdatomic.h", true)
3830b57cec5SDimitry Andric            .Case("stdbool.h", true)
3840b57cec5SDimitry Andric            .Case("stddef.h", true)
3850b57cec5SDimitry Andric            .Case("stdint.h", true)
3860b57cec5SDimitry Andric            .Case("tgmath.h", true)
3870b57cec5SDimitry Andric            .Case("unwind.h", true)
3880b57cec5SDimitry Andric            .Default(false);
3890b57cec5SDimitry Andric }
3900b57cec5SDimitry Andric 
isBuiltinHeader(const FileEntry * File)3915ffd83dbSDimitry Andric bool ModuleMap::isBuiltinHeader(const FileEntry *File) {
3925ffd83dbSDimitry Andric   return File->getDir() == BuiltinIncludeDir &&
3935ffd83dbSDimitry Andric          ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()));
3945ffd83dbSDimitry Andric }
3955ffd83dbSDimitry Andric 
3960b57cec5SDimitry Andric ModuleMap::HeadersMap::iterator
findKnownHeader(const FileEntry * File)3970b57cec5SDimitry Andric ModuleMap::findKnownHeader(const FileEntry *File) {
3980b57cec5SDimitry Andric   resolveHeaderDirectives(File);
3990b57cec5SDimitry Andric   HeadersMap::iterator Known = Headers.find(File);
4000b57cec5SDimitry Andric   if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
4015ffd83dbSDimitry Andric       Known == Headers.end() && ModuleMap::isBuiltinHeader(File)) {
4020b57cec5SDimitry Andric     HeaderInfo.loadTopLevelSystemModules();
4030b57cec5SDimitry Andric     return Headers.find(File);
4040b57cec5SDimitry Andric   }
4050b57cec5SDimitry Andric   return Known;
4060b57cec5SDimitry Andric }
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric ModuleMap::KnownHeader
findHeaderInUmbrellaDirs(const FileEntry * File,SmallVectorImpl<const DirectoryEntry * > & IntermediateDirs)4090b57cec5SDimitry Andric ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
4100b57cec5SDimitry Andric                     SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
4110b57cec5SDimitry Andric   if (UmbrellaDirs.empty())
4120b57cec5SDimitry Andric     return {};
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   const DirectoryEntry *Dir = File->getDir();
4150b57cec5SDimitry Andric   assert(Dir && "file in no directory");
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric   // Note: as an egregious but useful hack we use the real path here, because
4180b57cec5SDimitry Andric   // frameworks moving from top-level frameworks to embedded frameworks tend
4190b57cec5SDimitry Andric   // to be symlinked from the top-level location to the embedded location,
4200b57cec5SDimitry Andric   // and we need to resolve lookups as if we had found the embedded location.
4210b57cec5SDimitry Andric   StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric   // Keep walking up the directory hierarchy, looking for a directory with
4240b57cec5SDimitry Andric   // an umbrella header.
4250b57cec5SDimitry Andric   do {
4260b57cec5SDimitry Andric     auto KnownDir = UmbrellaDirs.find(Dir);
4270b57cec5SDimitry Andric     if (KnownDir != UmbrellaDirs.end())
4280b57cec5SDimitry Andric       return KnownHeader(KnownDir->second, NormalHeader);
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric     IntermediateDirs.push_back(Dir);
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric     // Retrieve our parent path.
4330b57cec5SDimitry Andric     DirName = llvm::sys::path::parent_path(DirName);
4340b57cec5SDimitry Andric     if (DirName.empty())
4350b57cec5SDimitry Andric       break;
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric     // Resolve the parent path to a directory entry.
438a7dea167SDimitry Andric     if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName))
439a7dea167SDimitry Andric       Dir = *DirEntry;
440a7dea167SDimitry Andric     else
441a7dea167SDimitry Andric       Dir = nullptr;
4420b57cec5SDimitry Andric   } while (Dir);
4430b57cec5SDimitry Andric   return {};
4440b57cec5SDimitry Andric }
4450b57cec5SDimitry Andric 
violatesPrivateInclude(Module * RequestingModule,const FileEntry * IncFileEnt,ModuleMap::KnownHeader Header)4460b57cec5SDimitry Andric static bool violatesPrivateInclude(Module *RequestingModule,
4470b57cec5SDimitry Andric                                    const FileEntry *IncFileEnt,
4480b57cec5SDimitry Andric                                    ModuleMap::KnownHeader Header) {
4490b57cec5SDimitry Andric #ifndef NDEBUG
4500b57cec5SDimitry Andric   if (Header.getRole() & ModuleMap::PrivateHeader) {
4510b57cec5SDimitry Andric     // Check for consistency between the module header role
4520b57cec5SDimitry Andric     // as obtained from the lookup and as obtained from the module.
4530b57cec5SDimitry Andric     // This check is not cheap, so enable it only for debugging.
4540b57cec5SDimitry Andric     bool IsPrivate = false;
4550b57cec5SDimitry Andric     SmallVectorImpl<Module::Header> *HeaderList[] = {
4560b57cec5SDimitry Andric         &Header.getModule()->Headers[Module::HK_Private],
4570b57cec5SDimitry Andric         &Header.getModule()->Headers[Module::HK_PrivateTextual]};
4580b57cec5SDimitry Andric     for (auto *Hs : HeaderList)
4590b57cec5SDimitry Andric       IsPrivate |=
4600b57cec5SDimitry Andric           std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
4610b57cec5SDimitry Andric             return H.Entry == IncFileEnt;
4620b57cec5SDimitry Andric           }) != Hs->end();
4630b57cec5SDimitry Andric     assert(IsPrivate && "inconsistent headers and roles");
4640b57cec5SDimitry Andric   }
4650b57cec5SDimitry Andric #endif
4660b57cec5SDimitry Andric   return !Header.isAccessibleFrom(RequestingModule);
4670b57cec5SDimitry Andric }
4680b57cec5SDimitry Andric 
getTopLevelOrNull(Module * M)4690b57cec5SDimitry Andric static Module *getTopLevelOrNull(Module *M) {
4700b57cec5SDimitry Andric   return M ? M->getTopLevelModule() : nullptr;
4710b57cec5SDimitry Andric }
4720b57cec5SDimitry Andric 
diagnoseHeaderInclusion(Module * RequestingModule,bool RequestingModuleIsModuleInterface,SourceLocation FilenameLoc,StringRef Filename,const FileEntry * File)4730b57cec5SDimitry Andric void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
4740b57cec5SDimitry Andric                                         bool RequestingModuleIsModuleInterface,
4750b57cec5SDimitry Andric                                         SourceLocation FilenameLoc,
4760b57cec5SDimitry Andric                                         StringRef Filename,
4770b57cec5SDimitry Andric                                         const FileEntry *File) {
4780b57cec5SDimitry Andric   // No errors for indirect modules. This may be a bit of a problem for modules
4790b57cec5SDimitry Andric   // with no source files.
4800b57cec5SDimitry Andric   if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
4810b57cec5SDimitry Andric     return;
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric   if (RequestingModule) {
4840b57cec5SDimitry Andric     resolveUses(RequestingModule, /*Complain=*/false);
4850b57cec5SDimitry Andric     resolveHeaderDirectives(RequestingModule);
4860b57cec5SDimitry Andric   }
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric   bool Excluded = false;
4890b57cec5SDimitry Andric   Module *Private = nullptr;
4900b57cec5SDimitry Andric   Module *NotUsed = nullptr;
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric   HeadersMap::iterator Known = findKnownHeader(File);
4930b57cec5SDimitry Andric   if (Known != Headers.end()) {
4940b57cec5SDimitry Andric     for (const KnownHeader &Header : Known->second) {
4950b57cec5SDimitry Andric       // Remember private headers for later printing of a diagnostic.
4960b57cec5SDimitry Andric       if (violatesPrivateInclude(RequestingModule, File, Header)) {
4970b57cec5SDimitry Andric         Private = Header.getModule();
4980b57cec5SDimitry Andric         continue;
4990b57cec5SDimitry Andric       }
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric       // If uses need to be specified explicitly, we are only allowed to return
5020b57cec5SDimitry Andric       // modules that are explicitly used by the requesting module.
5030b57cec5SDimitry Andric       if (RequestingModule && LangOpts.ModulesDeclUse &&
5040b57cec5SDimitry Andric           !RequestingModule->directlyUses(Header.getModule())) {
5050b57cec5SDimitry Andric         NotUsed = Header.getModule();
5060b57cec5SDimitry Andric         continue;
5070b57cec5SDimitry Andric       }
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric       // We have found a module that we can happily use.
5100b57cec5SDimitry Andric       return;
5110b57cec5SDimitry Andric     }
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric     Excluded = true;
5140b57cec5SDimitry Andric   }
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric   // We have found a header, but it is private.
5170b57cec5SDimitry Andric   if (Private) {
5180b57cec5SDimitry Andric     Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
5190b57cec5SDimitry Andric         << Filename;
5200b57cec5SDimitry Andric     return;
5210b57cec5SDimitry Andric   }
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric   // We have found a module, but we don't use it.
5240b57cec5SDimitry Andric   if (NotUsed) {
5250b57cec5SDimitry Andric     Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
5260b57cec5SDimitry Andric         << RequestingModule->getTopLevelModule()->Name << Filename;
5270b57cec5SDimitry Andric     return;
5280b57cec5SDimitry Andric   }
5290b57cec5SDimitry Andric 
5300b57cec5SDimitry Andric   if (Excluded || isHeaderInUmbrellaDirs(File))
5310b57cec5SDimitry Andric     return;
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric   // At this point, only non-modular includes remain.
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric   if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
5360b57cec5SDimitry Andric     Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
5370b57cec5SDimitry Andric         << RequestingModule->getTopLevelModule()->Name << Filename;
5380b57cec5SDimitry Andric   } else if (RequestingModule && RequestingModuleIsModuleInterface &&
5390b57cec5SDimitry Andric              LangOpts.isCompilingModule()) {
5400b57cec5SDimitry Andric     // Do not diagnose when we are not compiling a module.
5410b57cec5SDimitry Andric     diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
5420b57cec5SDimitry Andric         diag::warn_non_modular_include_in_framework_module :
5430b57cec5SDimitry Andric         diag::warn_non_modular_include_in_module;
5440b57cec5SDimitry Andric     Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
5450b57cec5SDimitry Andric         << File->getName();
5460b57cec5SDimitry Andric   }
5470b57cec5SDimitry Andric }
5480b57cec5SDimitry Andric 
isBetterKnownHeader(const ModuleMap::KnownHeader & New,const ModuleMap::KnownHeader & Old)5490b57cec5SDimitry Andric static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
5500b57cec5SDimitry Andric                                 const ModuleMap::KnownHeader &Old) {
5510b57cec5SDimitry Andric   // Prefer available modules.
5525ffd83dbSDimitry Andric   // FIXME: Considering whether the module is available rather than merely
5535ffd83dbSDimitry Andric   // importable is non-hermetic and can result in surprising behavior for
5545ffd83dbSDimitry Andric   // prebuilt modules. Consider only checking for importability here.
5550b57cec5SDimitry Andric   if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
5560b57cec5SDimitry Andric     return true;
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric   // Prefer a public header over a private header.
5590b57cec5SDimitry Andric   if ((New.getRole() & ModuleMap::PrivateHeader) !=
5600b57cec5SDimitry Andric       (Old.getRole() & ModuleMap::PrivateHeader))
5610b57cec5SDimitry Andric     return !(New.getRole() & ModuleMap::PrivateHeader);
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric   // Prefer a non-textual header over a textual header.
5640b57cec5SDimitry Andric   if ((New.getRole() & ModuleMap::TextualHeader) !=
5650b57cec5SDimitry Andric       (Old.getRole() & ModuleMap::TextualHeader))
5660b57cec5SDimitry Andric     return !(New.getRole() & ModuleMap::TextualHeader);
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   // Don't have a reason to choose between these. Just keep the first one.
5690b57cec5SDimitry Andric   return false;
5700b57cec5SDimitry Andric }
5710b57cec5SDimitry Andric 
findModuleForHeader(const FileEntry * File,bool AllowTextual)5720b57cec5SDimitry Andric ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File,
5730b57cec5SDimitry Andric                                                       bool AllowTextual) {
5740b57cec5SDimitry Andric   auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
5750b57cec5SDimitry Andric     if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
5760b57cec5SDimitry Andric       return {};
5770b57cec5SDimitry Andric     return R;
5780b57cec5SDimitry Andric   };
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric   HeadersMap::iterator Known = findKnownHeader(File);
5810b57cec5SDimitry Andric   if (Known != Headers.end()) {
5820b57cec5SDimitry Andric     ModuleMap::KnownHeader Result;
5830b57cec5SDimitry Andric     // Iterate over all modules that 'File' is part of to find the best fit.
5840b57cec5SDimitry Andric     for (KnownHeader &H : Known->second) {
5850b57cec5SDimitry Andric       // Prefer a header from the source module over all others.
5860b57cec5SDimitry Andric       if (H.getModule()->getTopLevelModule() == SourceModule)
5870b57cec5SDimitry Andric         return MakeResult(H);
5880b57cec5SDimitry Andric       if (!Result || isBetterKnownHeader(H, Result))
5890b57cec5SDimitry Andric         Result = H;
5900b57cec5SDimitry Andric     }
5910b57cec5SDimitry Andric     return MakeResult(Result);
5920b57cec5SDimitry Andric   }
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric   return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
5950b57cec5SDimitry Andric }
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric ModuleMap::KnownHeader
findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry * File)5980b57cec5SDimitry Andric ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
5990b57cec5SDimitry Andric   assert(!Headers.count(File) && "already have a module for this header");
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
6020b57cec5SDimitry Andric   KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
6030b57cec5SDimitry Andric   if (H) {
6040b57cec5SDimitry Andric     Module *Result = H.getModule();
6050b57cec5SDimitry Andric 
6060b57cec5SDimitry Andric     // Search up the module stack until we find a module with an umbrella
6070b57cec5SDimitry Andric     // directory.
6080b57cec5SDimitry Andric     Module *UmbrellaModule = Result;
6090b57cec5SDimitry Andric     while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
6100b57cec5SDimitry Andric       UmbrellaModule = UmbrellaModule->Parent;
6110b57cec5SDimitry Andric 
6120b57cec5SDimitry Andric     if (UmbrellaModule->InferSubmodules) {
6130b57cec5SDimitry Andric       const FileEntry *UmbrellaModuleMap =
6140b57cec5SDimitry Andric           getModuleMapFileForUniquing(UmbrellaModule);
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric       // Infer submodules for each of the directories we found between
6170b57cec5SDimitry Andric       // the directory of the umbrella header and the directory where
6180b57cec5SDimitry Andric       // the actual header is located.
6190b57cec5SDimitry Andric       bool Explicit = UmbrellaModule->InferExplicitSubmodules;
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric       for (unsigned I = SkippedDirs.size(); I != 0; --I) {
6220b57cec5SDimitry Andric         // Find or create the module that corresponds to this directory name.
6230b57cec5SDimitry Andric         SmallString<32> NameBuf;
6240b57cec5SDimitry Andric         StringRef Name = sanitizeFilenameAsIdentifier(
6250b57cec5SDimitry Andric             llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
6260b57cec5SDimitry Andric         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
6270b57cec5SDimitry Andric                                     Explicit).first;
6280b57cec5SDimitry Andric         InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
6290b57cec5SDimitry Andric         Result->IsInferred = true;
6300b57cec5SDimitry Andric 
6310b57cec5SDimitry Andric         // Associate the module and the directory.
6320b57cec5SDimitry Andric         UmbrellaDirs[SkippedDirs[I-1]] = Result;
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric         // If inferred submodules export everything they import, add a
6350b57cec5SDimitry Andric         // wildcard to the set of exports.
6360b57cec5SDimitry Andric         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
6370b57cec5SDimitry Andric           Result->Exports.push_back(Module::ExportDecl(nullptr, true));
6380b57cec5SDimitry Andric       }
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric       // Infer a submodule with the same name as this header file.
6410b57cec5SDimitry Andric       SmallString<32> NameBuf;
6420b57cec5SDimitry Andric       StringRef Name = sanitizeFilenameAsIdentifier(
6430b57cec5SDimitry Andric                          llvm::sys::path::stem(File->getName()), NameBuf);
6440b57cec5SDimitry Andric       Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
6450b57cec5SDimitry Andric                                   Explicit).first;
6460b57cec5SDimitry Andric       InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
6470b57cec5SDimitry Andric       Result->IsInferred = true;
6480b57cec5SDimitry Andric       Result->addTopHeader(File);
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric       // If inferred submodules export everything they import, add a
6510b57cec5SDimitry Andric       // wildcard to the set of exports.
6520b57cec5SDimitry Andric       if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
6530b57cec5SDimitry Andric         Result->Exports.push_back(Module::ExportDecl(nullptr, true));
6540b57cec5SDimitry Andric     } else {
6550b57cec5SDimitry Andric       // Record each of the directories we stepped through as being part of
6560b57cec5SDimitry Andric       // the module we found, since the umbrella header covers them all.
6570b57cec5SDimitry Andric       for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
6580b57cec5SDimitry Andric         UmbrellaDirs[SkippedDirs[I]] = Result;
6590b57cec5SDimitry Andric     }
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric     KnownHeader Header(Result, NormalHeader);
6620b57cec5SDimitry Andric     Headers[File].push_back(Header);
6630b57cec5SDimitry Andric     return Header;
6640b57cec5SDimitry Andric   }
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric   return {};
6670b57cec5SDimitry Andric }
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric ArrayRef<ModuleMap::KnownHeader>
findAllModulesForHeader(const FileEntry * File)6705ffd83dbSDimitry Andric ModuleMap::findAllModulesForHeader(const FileEntry *File) {
6715ffd83dbSDimitry Andric   HeadersMap::iterator Known = findKnownHeader(File);
6725ffd83dbSDimitry Andric   if (Known != Headers.end())
6735ffd83dbSDimitry Andric     return Known->second;
6745ffd83dbSDimitry Andric 
6755ffd83dbSDimitry Andric   if (findOrCreateModuleForHeaderInUmbrellaDir(File))
6765ffd83dbSDimitry Andric     return Headers.find(File)->second;
6775ffd83dbSDimitry Andric 
6785ffd83dbSDimitry Andric   return None;
6795ffd83dbSDimitry Andric }
6805ffd83dbSDimitry Andric 
6815ffd83dbSDimitry Andric ArrayRef<ModuleMap::KnownHeader>
findResolvedModulesForHeader(const FileEntry * File) const6825ffd83dbSDimitry Andric ModuleMap::findResolvedModulesForHeader(const FileEntry *File) const {
6835ffd83dbSDimitry Andric   // FIXME: Is this necessary?
6840b57cec5SDimitry Andric   resolveHeaderDirectives(File);
6850b57cec5SDimitry Andric   auto It = Headers.find(File);
6860b57cec5SDimitry Andric   if (It == Headers.end())
6870b57cec5SDimitry Andric     return None;
6880b57cec5SDimitry Andric   return It->second;
6890b57cec5SDimitry Andric }
6900b57cec5SDimitry Andric 
isHeaderInUnavailableModule(const FileEntry * Header) const6910b57cec5SDimitry Andric bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
6920b57cec5SDimitry Andric   return isHeaderUnavailableInModule(Header, nullptr);
6930b57cec5SDimitry Andric }
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric bool
isHeaderUnavailableInModule(const FileEntry * Header,const Module * RequestingModule) const6960b57cec5SDimitry Andric ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
6970b57cec5SDimitry Andric                                        const Module *RequestingModule) const {
6980b57cec5SDimitry Andric   resolveHeaderDirectives(Header);
6990b57cec5SDimitry Andric   HeadersMap::const_iterator Known = Headers.find(Header);
7000b57cec5SDimitry Andric   if (Known != Headers.end()) {
7010b57cec5SDimitry Andric     for (SmallVectorImpl<KnownHeader>::const_iterator
7020b57cec5SDimitry Andric              I = Known->second.begin(),
7030b57cec5SDimitry Andric              E = Known->second.end();
7040b57cec5SDimitry Andric          I != E; ++I) {
7050b57cec5SDimitry Andric 
7060b57cec5SDimitry Andric       if (I->isAvailable() &&
7070b57cec5SDimitry Andric           (!RequestingModule ||
7080b57cec5SDimitry Andric            I->getModule()->isSubModuleOf(RequestingModule))) {
7090b57cec5SDimitry Andric         // When no requesting module is available, the caller is looking if a
7100b57cec5SDimitry Andric         // header is part a module by only looking into the module map. This is
7110b57cec5SDimitry Andric         // done by warn_uncovered_module_header checks; don't consider textual
7120b57cec5SDimitry Andric         // headers part of it in this mode, otherwise we get misleading warnings
7130b57cec5SDimitry Andric         // that a umbrella header is not including a textual header.
7140b57cec5SDimitry Andric         if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
7150b57cec5SDimitry Andric           continue;
7160b57cec5SDimitry Andric         return false;
7170b57cec5SDimitry Andric       }
7180b57cec5SDimitry Andric     }
7190b57cec5SDimitry Andric     return true;
7200b57cec5SDimitry Andric   }
7210b57cec5SDimitry Andric 
7220b57cec5SDimitry Andric   const DirectoryEntry *Dir = Header->getDir();
7230b57cec5SDimitry Andric   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
7240b57cec5SDimitry Andric   StringRef DirName = Dir->getName();
7250b57cec5SDimitry Andric 
7260b57cec5SDimitry Andric   auto IsUnavailable = [&](const Module *M) {
7270b57cec5SDimitry Andric     return !M->isAvailable() && (!RequestingModule ||
7280b57cec5SDimitry Andric                                  M->isSubModuleOf(RequestingModule));
7290b57cec5SDimitry Andric   };
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric   // Keep walking up the directory hierarchy, looking for a directory with
7320b57cec5SDimitry Andric   // an umbrella header.
7330b57cec5SDimitry Andric   do {
7340b57cec5SDimitry Andric     llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
7350b57cec5SDimitry Andric       = UmbrellaDirs.find(Dir);
7360b57cec5SDimitry Andric     if (KnownDir != UmbrellaDirs.end()) {
7370b57cec5SDimitry Andric       Module *Found = KnownDir->second;
7380b57cec5SDimitry Andric       if (IsUnavailable(Found))
7390b57cec5SDimitry Andric         return true;
7400b57cec5SDimitry Andric 
7410b57cec5SDimitry Andric       // Search up the module stack until we find a module with an umbrella
7420b57cec5SDimitry Andric       // directory.
7430b57cec5SDimitry Andric       Module *UmbrellaModule = Found;
7440b57cec5SDimitry Andric       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
7450b57cec5SDimitry Andric         UmbrellaModule = UmbrellaModule->Parent;
7460b57cec5SDimitry Andric 
7470b57cec5SDimitry Andric       if (UmbrellaModule->InferSubmodules) {
7480b57cec5SDimitry Andric         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
7490b57cec5SDimitry Andric           // Find or create the module that corresponds to this directory name.
7500b57cec5SDimitry Andric           SmallString<32> NameBuf;
7510b57cec5SDimitry Andric           StringRef Name = sanitizeFilenameAsIdentifier(
7520b57cec5SDimitry Andric                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
7530b57cec5SDimitry Andric                              NameBuf);
7540b57cec5SDimitry Andric           Found = lookupModuleQualified(Name, Found);
7550b57cec5SDimitry Andric           if (!Found)
7560b57cec5SDimitry Andric             return false;
7570b57cec5SDimitry Andric           if (IsUnavailable(Found))
7580b57cec5SDimitry Andric             return true;
7590b57cec5SDimitry Andric         }
7600b57cec5SDimitry Andric 
7610b57cec5SDimitry Andric         // Infer a submodule with the same name as this header file.
7620b57cec5SDimitry Andric         SmallString<32> NameBuf;
7630b57cec5SDimitry Andric         StringRef Name = sanitizeFilenameAsIdentifier(
7640b57cec5SDimitry Andric                            llvm::sys::path::stem(Header->getName()),
7650b57cec5SDimitry Andric                            NameBuf);
7660b57cec5SDimitry Andric         Found = lookupModuleQualified(Name, Found);
7670b57cec5SDimitry Andric         if (!Found)
7680b57cec5SDimitry Andric           return false;
7690b57cec5SDimitry Andric       }
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric       return IsUnavailable(Found);
7720b57cec5SDimitry Andric     }
7730b57cec5SDimitry Andric 
7740b57cec5SDimitry Andric     SkippedDirs.push_back(Dir);
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric     // Retrieve our parent path.
7770b57cec5SDimitry Andric     DirName = llvm::sys::path::parent_path(DirName);
7780b57cec5SDimitry Andric     if (DirName.empty())
7790b57cec5SDimitry Andric       break;
7800b57cec5SDimitry Andric 
7810b57cec5SDimitry Andric     // Resolve the parent path to a directory entry.
782a7dea167SDimitry Andric     if (auto DirEntry = SourceMgr.getFileManager().getDirectory(DirName))
783a7dea167SDimitry Andric       Dir = *DirEntry;
784a7dea167SDimitry Andric     else
785a7dea167SDimitry Andric       Dir = nullptr;
7860b57cec5SDimitry Andric   } while (Dir);
7870b57cec5SDimitry Andric 
7880b57cec5SDimitry Andric   return false;
7890b57cec5SDimitry Andric }
7900b57cec5SDimitry Andric 
findModule(StringRef Name) const7910b57cec5SDimitry Andric Module *ModuleMap::findModule(StringRef Name) const {
7920b57cec5SDimitry Andric   llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
7930b57cec5SDimitry Andric   if (Known != Modules.end())
7940b57cec5SDimitry Andric     return Known->getValue();
7950b57cec5SDimitry Andric 
7960b57cec5SDimitry Andric   return nullptr;
7970b57cec5SDimitry Andric }
7980b57cec5SDimitry Andric 
lookupModuleUnqualified(StringRef Name,Module * Context) const7990b57cec5SDimitry Andric Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
8000b57cec5SDimitry Andric                                            Module *Context) const {
8010b57cec5SDimitry Andric   for(; Context; Context = Context->Parent) {
8020b57cec5SDimitry Andric     if (Module *Sub = lookupModuleQualified(Name, Context))
8030b57cec5SDimitry Andric       return Sub;
8040b57cec5SDimitry Andric   }
8050b57cec5SDimitry Andric 
8060b57cec5SDimitry Andric   return findModule(Name);
8070b57cec5SDimitry Andric }
8080b57cec5SDimitry Andric 
lookupModuleQualified(StringRef Name,Module * Context) const8090b57cec5SDimitry Andric Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
8100b57cec5SDimitry Andric   if (!Context)
8110b57cec5SDimitry Andric     return findModule(Name);
8120b57cec5SDimitry Andric 
8130b57cec5SDimitry Andric   return Context->findSubmodule(Name);
8140b57cec5SDimitry Andric }
8150b57cec5SDimitry Andric 
findOrCreateModule(StringRef Name,Module * Parent,bool IsFramework,bool IsExplicit)8160b57cec5SDimitry Andric std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
8170b57cec5SDimitry Andric                                                         Module *Parent,
8180b57cec5SDimitry Andric                                                         bool IsFramework,
8190b57cec5SDimitry Andric                                                         bool IsExplicit) {
8200b57cec5SDimitry Andric   // Try to find an existing module with this name.
8210b57cec5SDimitry Andric   if (Module *Sub = lookupModuleQualified(Name, Parent))
8220b57cec5SDimitry Andric     return std::make_pair(Sub, false);
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric   // Create a new module with this name.
8250b57cec5SDimitry Andric   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
8260b57cec5SDimitry Andric                               IsExplicit, NumCreatedModules++);
8270b57cec5SDimitry Andric   if (!Parent) {
8280b57cec5SDimitry Andric     if (LangOpts.CurrentModule == Name)
8290b57cec5SDimitry Andric       SourceModule = Result;
8300b57cec5SDimitry Andric     Modules[Name] = Result;
8310b57cec5SDimitry Andric     ModuleScopeIDs[Result] = CurrentModuleScopeID;
8320b57cec5SDimitry Andric   }
8330b57cec5SDimitry Andric   return std::make_pair(Result, true);
8340b57cec5SDimitry Andric }
8350b57cec5SDimitry Andric 
createGlobalModuleFragmentForModuleUnit(SourceLocation Loc)8360b57cec5SDimitry Andric Module *ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc) {
8370b57cec5SDimitry Andric   PendingSubmodules.emplace_back(
8380b57cec5SDimitry Andric       new Module("<global>", Loc, nullptr, /*IsFramework*/ false,
8390b57cec5SDimitry Andric                  /*IsExplicit*/ true, NumCreatedModules++));
8400b57cec5SDimitry Andric   PendingSubmodules.back()->Kind = Module::GlobalModuleFragment;
8410b57cec5SDimitry Andric   return PendingSubmodules.back().get();
8420b57cec5SDimitry Andric }
8430b57cec5SDimitry Andric 
8440b57cec5SDimitry Andric Module *
createPrivateModuleFragmentForInterfaceUnit(Module * Parent,SourceLocation Loc)8450b57cec5SDimitry Andric ModuleMap::createPrivateModuleFragmentForInterfaceUnit(Module *Parent,
8460b57cec5SDimitry Andric                                                        SourceLocation Loc) {
8470b57cec5SDimitry Andric   auto *Result =
8480b57cec5SDimitry Andric       new Module("<private>", Loc, Parent, /*IsFramework*/ false,
8490b57cec5SDimitry Andric                  /*IsExplicit*/ true, NumCreatedModules++);
8500b57cec5SDimitry Andric   Result->Kind = Module::PrivateModuleFragment;
8510b57cec5SDimitry Andric   return Result;
8520b57cec5SDimitry Andric }
8530b57cec5SDimitry Andric 
createModuleForInterfaceUnit(SourceLocation Loc,StringRef Name,Module * GlobalModule)8540b57cec5SDimitry Andric Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
8550b57cec5SDimitry Andric                                                 StringRef Name,
8560b57cec5SDimitry Andric                                                 Module *GlobalModule) {
8570b57cec5SDimitry Andric   assert(LangOpts.CurrentModule == Name && "module name mismatch");
8580b57cec5SDimitry Andric   assert(!Modules[Name] && "redefining existing module");
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric   auto *Result =
8610b57cec5SDimitry Andric       new Module(Name, Loc, nullptr, /*IsFramework*/ false,
8620b57cec5SDimitry Andric                  /*IsExplicit*/ false, NumCreatedModules++);
8630b57cec5SDimitry Andric   Result->Kind = Module::ModuleInterfaceUnit;
8640b57cec5SDimitry Andric   Modules[Name] = SourceModule = Result;
8650b57cec5SDimitry Andric 
8660b57cec5SDimitry Andric   // Reparent the current global module fragment as a submodule of this module.
8670b57cec5SDimitry Andric   for (auto &Submodule : PendingSubmodules) {
8680b57cec5SDimitry Andric     Submodule->setParent(Result);
8690b57cec5SDimitry Andric     Submodule.release(); // now owned by parent
8700b57cec5SDimitry Andric   }
8710b57cec5SDimitry Andric   PendingSubmodules.clear();
8720b57cec5SDimitry Andric 
8730b57cec5SDimitry Andric   // Mark the main source file as being within the newly-created module so that
8740b57cec5SDimitry Andric   // declarations and macros are properly visibility-restricted to it.
8750b57cec5SDimitry Andric   auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
8760b57cec5SDimitry Andric   assert(MainFile && "no input file for module interface");
8770b57cec5SDimitry Andric   Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
8780b57cec5SDimitry Andric 
8790b57cec5SDimitry Andric   return Result;
8800b57cec5SDimitry Andric }
8810b57cec5SDimitry Andric 
createHeaderModule(StringRef Name,ArrayRef<Module::Header> Headers)8820b57cec5SDimitry Andric Module *ModuleMap::createHeaderModule(StringRef Name,
8830b57cec5SDimitry Andric                                       ArrayRef<Module::Header> Headers) {
8840b57cec5SDimitry Andric   assert(LangOpts.CurrentModule == Name && "module name mismatch");
8850b57cec5SDimitry Andric   assert(!Modules[Name] && "redefining existing module");
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric   auto *Result =
8880b57cec5SDimitry Andric       new Module(Name, SourceLocation(), nullptr, /*IsFramework*/ false,
8890b57cec5SDimitry Andric                  /*IsExplicit*/ false, NumCreatedModules++);
8900b57cec5SDimitry Andric   Result->Kind = Module::ModuleInterfaceUnit;
8910b57cec5SDimitry Andric   Modules[Name] = SourceModule = Result;
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   for (const Module::Header &H : Headers) {
8940b57cec5SDimitry Andric     auto *M = new Module(H.NameAsWritten, SourceLocation(), Result,
8950b57cec5SDimitry Andric                          /*IsFramework*/ false,
8960b57cec5SDimitry Andric                          /*IsExplicit*/ true, NumCreatedModules++);
8970b57cec5SDimitry Andric     // Header modules are implicitly 'export *'.
8980b57cec5SDimitry Andric     M->Exports.push_back(Module::ExportDecl(nullptr, true));
8990b57cec5SDimitry Andric     addHeader(M, H, NormalHeader);
9000b57cec5SDimitry Andric   }
9010b57cec5SDimitry Andric 
9020b57cec5SDimitry Andric   return Result;
9030b57cec5SDimitry Andric }
9040b57cec5SDimitry Andric 
9050b57cec5SDimitry Andric /// For a framework module, infer the framework against which we
9060b57cec5SDimitry Andric /// should link.
inferFrameworkLink(Module * Mod,const DirectoryEntry * FrameworkDir,FileManager & FileMgr)9070b57cec5SDimitry Andric static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
9080b57cec5SDimitry Andric                                FileManager &FileMgr) {
9090b57cec5SDimitry Andric   assert(Mod->IsFramework && "Can only infer linking for framework modules");
9100b57cec5SDimitry Andric   assert(!Mod->isSubFramework() &&
9110b57cec5SDimitry Andric          "Can only infer linking for top-level frameworks");
9120b57cec5SDimitry Andric 
9130b57cec5SDimitry Andric   SmallString<128> LibName;
9140b57cec5SDimitry Andric   LibName += FrameworkDir->getName();
9150b57cec5SDimitry Andric   llvm::sys::path::append(LibName, Mod->Name);
9160b57cec5SDimitry Andric 
9170b57cec5SDimitry Andric   // The library name of a framework has more than one possible extension since
9180b57cec5SDimitry Andric   // the introduction of the text-based dynamic library format. We need to check
9190b57cec5SDimitry Andric   // for both before we give up.
9200b57cec5SDimitry Andric   for (const char *extension : {"", ".tbd"}) {
9210b57cec5SDimitry Andric     llvm::sys::path::replace_extension(LibName, extension);
9220b57cec5SDimitry Andric     if (FileMgr.getFile(LibName)) {
9230b57cec5SDimitry Andric       Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
9240b57cec5SDimitry Andric                                                        /*IsFramework=*/true));
9250b57cec5SDimitry Andric       return;
9260b57cec5SDimitry Andric     }
9270b57cec5SDimitry Andric   }
9280b57cec5SDimitry Andric }
9290b57cec5SDimitry Andric 
inferFrameworkModule(const DirectoryEntry * FrameworkDir,bool IsSystem,Module * Parent)9300b57cec5SDimitry Andric Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
9310b57cec5SDimitry Andric                                         bool IsSystem, Module *Parent) {
9320b57cec5SDimitry Andric   Attributes Attrs;
9330b57cec5SDimitry Andric   Attrs.IsSystem = IsSystem;
9340b57cec5SDimitry Andric   return inferFrameworkModule(FrameworkDir, Attrs, Parent);
9350b57cec5SDimitry Andric }
9360b57cec5SDimitry Andric 
inferFrameworkModule(const DirectoryEntry * FrameworkDir,Attributes Attrs,Module * Parent)9370b57cec5SDimitry Andric Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
9380b57cec5SDimitry Andric                                         Attributes Attrs, Module *Parent) {
9390b57cec5SDimitry Andric   // Note: as an egregious but useful hack we use the real path here, because
9400b57cec5SDimitry Andric   // we might be looking at an embedded framework that symlinks out to a
9410b57cec5SDimitry Andric   // top-level framework, and we need to infer as if we were naming the
9420b57cec5SDimitry Andric   // top-level framework.
9430b57cec5SDimitry Andric   StringRef FrameworkDirName =
9440b57cec5SDimitry Andric       SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
9450b57cec5SDimitry Andric 
9460b57cec5SDimitry Andric   // In case this is a case-insensitive filesystem, use the canonical
9470b57cec5SDimitry Andric   // directory name as the ModuleName, since modules are case-sensitive.
9480b57cec5SDimitry Andric   // FIXME: we should be able to give a fix-it hint for the correct spelling.
9490b57cec5SDimitry Andric   SmallString<32> ModuleNameStorage;
9500b57cec5SDimitry Andric   StringRef ModuleName = sanitizeFilenameAsIdentifier(
9510b57cec5SDimitry Andric       llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
9520b57cec5SDimitry Andric 
9530b57cec5SDimitry Andric   // Check whether we've already found this module.
9540b57cec5SDimitry Andric   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
9550b57cec5SDimitry Andric     return Mod;
9560b57cec5SDimitry Andric 
9570b57cec5SDimitry Andric   FileManager &FileMgr = SourceMgr.getFileManager();
9580b57cec5SDimitry Andric 
9590b57cec5SDimitry Andric   // If the framework has a parent path from which we're allowed to infer
9600b57cec5SDimitry Andric   // a framework module, do so.
9610b57cec5SDimitry Andric   const FileEntry *ModuleMapFile = nullptr;
9620b57cec5SDimitry Andric   if (!Parent) {
9630b57cec5SDimitry Andric     // Determine whether we're allowed to infer a module map.
9640b57cec5SDimitry Andric     bool canInfer = false;
9650b57cec5SDimitry Andric     if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
9660b57cec5SDimitry Andric       // Figure out the parent path.
9670b57cec5SDimitry Andric       StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
968a7dea167SDimitry Andric       if (auto ParentDir = FileMgr.getDirectory(Parent)) {
9690b57cec5SDimitry Andric         // Check whether we have already looked into the parent directory
9700b57cec5SDimitry Andric         // for a module map.
9710b57cec5SDimitry Andric         llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
972a7dea167SDimitry Andric           inferred = InferredDirectories.find(*ParentDir);
9730b57cec5SDimitry Andric         if (inferred == InferredDirectories.end()) {
9740b57cec5SDimitry Andric           // We haven't looked here before. Load a module map, if there is
9750b57cec5SDimitry Andric           // one.
9760b57cec5SDimitry Andric           bool IsFrameworkDir = Parent.endswith(".framework");
9770b57cec5SDimitry Andric           if (const FileEntry *ModMapFile =
978a7dea167SDimitry Andric                 HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
979a7dea167SDimitry Andric             parseModuleMapFile(ModMapFile, Attrs.IsSystem, *ParentDir);
980a7dea167SDimitry Andric             inferred = InferredDirectories.find(*ParentDir);
9810b57cec5SDimitry Andric           }
9820b57cec5SDimitry Andric 
9830b57cec5SDimitry Andric           if (inferred == InferredDirectories.end())
9840b57cec5SDimitry Andric             inferred = InferredDirectories.insert(
985a7dea167SDimitry Andric                          std::make_pair(*ParentDir, InferredDirectory())).first;
9860b57cec5SDimitry Andric         }
9870b57cec5SDimitry Andric 
9880b57cec5SDimitry Andric         if (inferred->second.InferModules) {
9890b57cec5SDimitry Andric           // We're allowed to infer for this directory, but make sure it's okay
9900b57cec5SDimitry Andric           // to infer this particular module.
9910b57cec5SDimitry Andric           StringRef Name = llvm::sys::path::stem(FrameworkDirName);
9920b57cec5SDimitry Andric           canInfer = std::find(inferred->second.ExcludedModules.begin(),
9930b57cec5SDimitry Andric                                inferred->second.ExcludedModules.end(),
9940b57cec5SDimitry Andric                                Name) == inferred->second.ExcludedModules.end();
9950b57cec5SDimitry Andric 
9960b57cec5SDimitry Andric           Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
9970b57cec5SDimitry Andric           Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
9980b57cec5SDimitry Andric           Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
9990b57cec5SDimitry Andric           Attrs.NoUndeclaredIncludes |=
10000b57cec5SDimitry Andric               inferred->second.Attrs.NoUndeclaredIncludes;
10010b57cec5SDimitry Andric           ModuleMapFile = inferred->second.ModuleMapFile;
10020b57cec5SDimitry Andric         }
10030b57cec5SDimitry Andric       }
10040b57cec5SDimitry Andric     }
10050b57cec5SDimitry Andric 
10060b57cec5SDimitry Andric     // If we're not allowed to infer a framework module, don't.
10070b57cec5SDimitry Andric     if (!canInfer)
10080b57cec5SDimitry Andric       return nullptr;
10090b57cec5SDimitry Andric   } else
10100b57cec5SDimitry Andric     ModuleMapFile = getModuleMapFileForUniquing(Parent);
10110b57cec5SDimitry Andric 
10120b57cec5SDimitry Andric 
10130b57cec5SDimitry Andric   // Look for an umbrella header.
10140b57cec5SDimitry Andric   SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
10150b57cec5SDimitry Andric   llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
1016*5f7ddb14SDimitry Andric   auto UmbrellaHeader = FileMgr.getFile(UmbrellaName);
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric   // FIXME: If there's no umbrella header, we could probably scan the
10190b57cec5SDimitry Andric   // framework to load *everything*. But, it's not clear that this is a good
10200b57cec5SDimitry Andric   // idea.
10210b57cec5SDimitry Andric   if (!UmbrellaHeader)
10220b57cec5SDimitry Andric     return nullptr;
10230b57cec5SDimitry Andric 
10240b57cec5SDimitry Andric   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
10250b57cec5SDimitry Andric                               /*IsFramework=*/true, /*IsExplicit=*/false,
10260b57cec5SDimitry Andric                               NumCreatedModules++);
10270b57cec5SDimitry Andric   InferredModuleAllowedBy[Result] = ModuleMapFile;
10280b57cec5SDimitry Andric   Result->IsInferred = true;
10290b57cec5SDimitry Andric   if (!Parent) {
10300b57cec5SDimitry Andric     if (LangOpts.CurrentModule == ModuleName)
10310b57cec5SDimitry Andric       SourceModule = Result;
10320b57cec5SDimitry Andric     Modules[ModuleName] = Result;
10330b57cec5SDimitry Andric     ModuleScopeIDs[Result] = CurrentModuleScopeID;
10340b57cec5SDimitry Andric   }
10350b57cec5SDimitry Andric 
10360b57cec5SDimitry Andric   Result->IsSystem |= Attrs.IsSystem;
10370b57cec5SDimitry Andric   Result->IsExternC |= Attrs.IsExternC;
10380b57cec5SDimitry Andric   Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
10390b57cec5SDimitry Andric   Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
10400b57cec5SDimitry Andric   Result->Directory = FrameworkDir;
10410b57cec5SDimitry Andric 
1042*5f7ddb14SDimitry Andric   // Chop off the first framework bit, as that is implied.
1043*5f7ddb14SDimitry Andric   StringRef RelativePath = UmbrellaName.str().substr(
1044*5f7ddb14SDimitry Andric       Result->getTopLevelModule()->Directory->getName().size());
1045*5f7ddb14SDimitry Andric   RelativePath = llvm::sys::path::relative_path(RelativePath);
1046*5f7ddb14SDimitry Andric 
10470b57cec5SDimitry Andric   // umbrella header "umbrella-header-name"
1048*5f7ddb14SDimitry Andric   setUmbrellaHeader(Result, *UmbrellaHeader, ModuleName + ".h", RelativePath);
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric   // export *
10510b57cec5SDimitry Andric   Result->Exports.push_back(Module::ExportDecl(nullptr, true));
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric   // module * { export * }
10540b57cec5SDimitry Andric   Result->InferSubmodules = true;
10550b57cec5SDimitry Andric   Result->InferExportWildcard = true;
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric   // Look for subframeworks.
10580b57cec5SDimitry Andric   std::error_code EC;
10590b57cec5SDimitry Andric   SmallString<128> SubframeworksDirName
10600b57cec5SDimitry Andric     = StringRef(FrameworkDir->getName());
10610b57cec5SDimitry Andric   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
10620b57cec5SDimitry Andric   llvm::sys::path::native(SubframeworksDirName);
10630b57cec5SDimitry Andric   llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
10640b57cec5SDimitry Andric   for (llvm::vfs::directory_iterator
10650b57cec5SDimitry Andric            Dir = FS.dir_begin(SubframeworksDirName, EC),
10660b57cec5SDimitry Andric            DirEnd;
10670b57cec5SDimitry Andric        Dir != DirEnd && !EC; Dir.increment(EC)) {
10680b57cec5SDimitry Andric     if (!StringRef(Dir->path()).endswith(".framework"))
10690b57cec5SDimitry Andric       continue;
10700b57cec5SDimitry Andric 
1071a7dea167SDimitry Andric     if (auto SubframeworkDir =
10720b57cec5SDimitry Andric             FileMgr.getDirectory(Dir->path())) {
10730b57cec5SDimitry Andric       // Note: as an egregious but useful hack, we use the real path here and
10740b57cec5SDimitry Andric       // check whether it is actually a subdirectory of the parent directory.
10750b57cec5SDimitry Andric       // This will not be the case if the 'subframework' is actually a symlink
10760b57cec5SDimitry Andric       // out to a top-level framework.
1077a7dea167SDimitry Andric       StringRef SubframeworkDirName =
1078a7dea167SDimitry Andric           FileMgr.getCanonicalName(*SubframeworkDir);
10790b57cec5SDimitry Andric       bool FoundParent = false;
10800b57cec5SDimitry Andric       do {
10810b57cec5SDimitry Andric         // Get the parent directory name.
10820b57cec5SDimitry Andric         SubframeworkDirName
10830b57cec5SDimitry Andric           = llvm::sys::path::parent_path(SubframeworkDirName);
10840b57cec5SDimitry Andric         if (SubframeworkDirName.empty())
10850b57cec5SDimitry Andric           break;
10860b57cec5SDimitry Andric 
1087a7dea167SDimitry Andric         if (auto SubDir = FileMgr.getDirectory(SubframeworkDirName)) {
1088a7dea167SDimitry Andric           if (*SubDir == FrameworkDir) {
10890b57cec5SDimitry Andric             FoundParent = true;
10900b57cec5SDimitry Andric             break;
10910b57cec5SDimitry Andric           }
1092a7dea167SDimitry Andric         }
10930b57cec5SDimitry Andric       } while (true);
10940b57cec5SDimitry Andric 
10950b57cec5SDimitry Andric       if (!FoundParent)
10960b57cec5SDimitry Andric         continue;
10970b57cec5SDimitry Andric 
10980b57cec5SDimitry Andric       // FIXME: Do we want to warn about subframeworks without umbrella headers?
1099a7dea167SDimitry Andric       inferFrameworkModule(*SubframeworkDir, Attrs, Result);
11000b57cec5SDimitry Andric     }
11010b57cec5SDimitry Andric   }
11020b57cec5SDimitry Andric 
11030b57cec5SDimitry Andric   // If the module is a top-level framework, automatically link against the
11040b57cec5SDimitry Andric   // framework.
11050b57cec5SDimitry Andric   if (!Result->isSubFramework()) {
11060b57cec5SDimitry Andric     inferFrameworkLink(Result, FrameworkDir, FileMgr);
11070b57cec5SDimitry Andric   }
11080b57cec5SDimitry Andric 
11090b57cec5SDimitry Andric   return Result;
11100b57cec5SDimitry Andric }
11110b57cec5SDimitry Andric 
createShadowedModule(StringRef Name,bool IsFramework,Module * ShadowingModule)11120b57cec5SDimitry Andric Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
11130b57cec5SDimitry Andric                                         Module *ShadowingModule) {
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric   // Create a new module with this name.
11160b57cec5SDimitry Andric   Module *Result =
11170b57cec5SDimitry Andric       new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework,
11180b57cec5SDimitry Andric                  /*IsExplicit=*/false, NumCreatedModules++);
11190b57cec5SDimitry Andric   Result->ShadowingModule = ShadowingModule;
11205ffd83dbSDimitry Andric   Result->markUnavailable(/*Unimportable*/true);
11210b57cec5SDimitry Andric   ModuleScopeIDs[Result] = CurrentModuleScopeID;
11220b57cec5SDimitry Andric   ShadowModules.push_back(Result);
11230b57cec5SDimitry Andric 
11240b57cec5SDimitry Andric   return Result;
11250b57cec5SDimitry Andric }
11260b57cec5SDimitry Andric 
setUmbrellaHeader(Module * Mod,const FileEntry * UmbrellaHeader,const Twine & NameAsWritten,const Twine & PathRelativeToRootModuleDirectory)1127*5f7ddb14SDimitry Andric void ModuleMap::setUmbrellaHeader(
1128*5f7ddb14SDimitry Andric     Module *Mod, const FileEntry *UmbrellaHeader, const Twine &NameAsWritten,
1129*5f7ddb14SDimitry Andric     const Twine &PathRelativeToRootModuleDirectory) {
11300b57cec5SDimitry Andric   Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
1131*5f7ddb14SDimitry Andric   Mod->Umbrella = UmbrellaHeader;
11320b57cec5SDimitry Andric   Mod->UmbrellaAsWritten = NameAsWritten.str();
1133*5f7ddb14SDimitry Andric   Mod->UmbrellaRelativeToRootModuleDirectory =
1134*5f7ddb14SDimitry Andric       PathRelativeToRootModuleDirectory.str();
1135*5f7ddb14SDimitry Andric   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
11360b57cec5SDimitry Andric 
11370b57cec5SDimitry Andric   // Notify callbacks that we just added a new header.
11380b57cec5SDimitry Andric   for (const auto &Cb : Callbacks)
11390b57cec5SDimitry Andric     Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
11400b57cec5SDimitry Andric }
11410b57cec5SDimitry Andric 
setUmbrellaDir(Module * Mod,const DirectoryEntry * UmbrellaDir,const Twine & NameAsWritten,const Twine & PathRelativeToRootModuleDirectory)1142*5f7ddb14SDimitry Andric void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
1143*5f7ddb14SDimitry Andric                                const Twine &NameAsWritten,
1144*5f7ddb14SDimitry Andric                                const Twine &PathRelativeToRootModuleDirectory) {
1145*5f7ddb14SDimitry Andric   Mod->Umbrella = UmbrellaDir;
11460b57cec5SDimitry Andric   Mod->UmbrellaAsWritten = NameAsWritten.str();
1147*5f7ddb14SDimitry Andric   Mod->UmbrellaRelativeToRootModuleDirectory =
1148*5f7ddb14SDimitry Andric       PathRelativeToRootModuleDirectory.str();
11490b57cec5SDimitry Andric   UmbrellaDirs[UmbrellaDir] = Mod;
11500b57cec5SDimitry Andric }
11510b57cec5SDimitry Andric 
addUnresolvedHeader(Module * Mod,Module::UnresolvedHeaderDirective Header,bool & NeedsFramework)11520b57cec5SDimitry Andric void ModuleMap::addUnresolvedHeader(Module *Mod,
11530b57cec5SDimitry Andric                                     Module::UnresolvedHeaderDirective Header,
11540b57cec5SDimitry Andric                                     bool &NeedsFramework) {
11550b57cec5SDimitry Andric   // If there is a builtin counterpart to this file, add it now so it can
11560b57cec5SDimitry Andric   // wrap the system header.
11570b57cec5SDimitry Andric   if (resolveAsBuiltinHeader(Mod, Header)) {
11580b57cec5SDimitry Andric     // If we have both a builtin and system version of the file, the
11590b57cec5SDimitry Andric     // builtin version may want to inject macros into the system header, so
11600b57cec5SDimitry Andric     // force the system header to be treated as a textual header in this
11610b57cec5SDimitry Andric     // case.
11620b57cec5SDimitry Andric     Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole(
11630b57cec5SDimitry Andric         headerKindToRole(Header.Kind) | ModuleMap::TextualHeader));
11640b57cec5SDimitry Andric     Header.HasBuiltinHeader = true;
11650b57cec5SDimitry Andric   }
11660b57cec5SDimitry Andric 
11670b57cec5SDimitry Andric   // If possible, don't stat the header until we need to. This requires the
11680b57cec5SDimitry Andric   // user to have provided us with some stat information about the file.
11690b57cec5SDimitry Andric   // FIXME: Add support for lazily stat'ing umbrella headers and excluded
11700b57cec5SDimitry Andric   // headers.
11710b57cec5SDimitry Andric   if ((Header.Size || Header.ModTime) && !Header.IsUmbrella &&
11720b57cec5SDimitry Andric       Header.Kind != Module::HK_Excluded) {
11730b57cec5SDimitry Andric     // We expect more variation in mtime than size, so if we're given both,
11740b57cec5SDimitry Andric     // use the mtime as the key.
11750b57cec5SDimitry Andric     if (Header.ModTime)
11760b57cec5SDimitry Andric       LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
11770b57cec5SDimitry Andric     else
11780b57cec5SDimitry Andric       LazyHeadersBySize[*Header.Size].push_back(Mod);
11790b57cec5SDimitry Andric     Mod->UnresolvedHeaders.push_back(Header);
11800b57cec5SDimitry Andric     return;
11810b57cec5SDimitry Andric   }
11820b57cec5SDimitry Andric 
11830b57cec5SDimitry Andric   // We don't have stat information or can't defer looking this file up.
11840b57cec5SDimitry Andric   // Perform the lookup now.
11850b57cec5SDimitry Andric   resolveHeader(Mod, Header, NeedsFramework);
11860b57cec5SDimitry Andric }
11870b57cec5SDimitry Andric 
resolveHeaderDirectives(const FileEntry * File) const11880b57cec5SDimitry Andric void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const {
11890b57cec5SDimitry Andric   auto BySize = LazyHeadersBySize.find(File->getSize());
11900b57cec5SDimitry Andric   if (BySize != LazyHeadersBySize.end()) {
11910b57cec5SDimitry Andric     for (auto *M : BySize->second)
11920b57cec5SDimitry Andric       resolveHeaderDirectives(M);
11930b57cec5SDimitry Andric     LazyHeadersBySize.erase(BySize);
11940b57cec5SDimitry Andric   }
11950b57cec5SDimitry Andric 
11960b57cec5SDimitry Andric   auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
11970b57cec5SDimitry Andric   if (ByModTime != LazyHeadersByModTime.end()) {
11980b57cec5SDimitry Andric     for (auto *M : ByModTime->second)
11990b57cec5SDimitry Andric       resolveHeaderDirectives(M);
12000b57cec5SDimitry Andric     LazyHeadersByModTime.erase(ByModTime);
12010b57cec5SDimitry Andric   }
12020b57cec5SDimitry Andric }
12030b57cec5SDimitry Andric 
resolveHeaderDirectives(Module * Mod) const12040b57cec5SDimitry Andric void ModuleMap::resolveHeaderDirectives(Module *Mod) const {
12050b57cec5SDimitry Andric   bool NeedsFramework = false;
12060b57cec5SDimitry Andric   for (auto &Header : Mod->UnresolvedHeaders)
12070b57cec5SDimitry Andric     // This operation is logically const; we're just changing how we represent
12080b57cec5SDimitry Andric     // the header information for this file.
12090b57cec5SDimitry Andric     const_cast<ModuleMap*>(this)->resolveHeader(Mod, Header, NeedsFramework);
12100b57cec5SDimitry Andric   Mod->UnresolvedHeaders.clear();
12110b57cec5SDimitry Andric }
12120b57cec5SDimitry Andric 
addHeader(Module * Mod,Module::Header Header,ModuleHeaderRole Role,bool Imported)12130b57cec5SDimitry Andric void ModuleMap::addHeader(Module *Mod, Module::Header Header,
12140b57cec5SDimitry Andric                           ModuleHeaderRole Role, bool Imported) {
12150b57cec5SDimitry Andric   KnownHeader KH(Mod, Role);
12160b57cec5SDimitry Andric 
12170b57cec5SDimitry Andric   // Only add each header to the headers list once.
12180b57cec5SDimitry Andric   // FIXME: Should we diagnose if a header is listed twice in the
12190b57cec5SDimitry Andric   // same module definition?
12200b57cec5SDimitry Andric   auto &HeaderList = Headers[Header.Entry];
12210b57cec5SDimitry Andric   for (auto H : HeaderList)
12220b57cec5SDimitry Andric     if (H == KH)
12230b57cec5SDimitry Andric       return;
12240b57cec5SDimitry Andric 
12250b57cec5SDimitry Andric   HeaderList.push_back(KH);
12260b57cec5SDimitry Andric   Mod->Headers[headerRoleToKind(Role)].push_back(Header);
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric   bool isCompilingModuleHeader =
12290b57cec5SDimitry Andric       LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
12300b57cec5SDimitry Andric   if (!Imported || isCompilingModuleHeader) {
12310b57cec5SDimitry Andric     // When we import HeaderFileInfo, the external source is expected to
12320b57cec5SDimitry Andric     // set the isModuleHeader flag itself.
12330b57cec5SDimitry Andric     HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
12340b57cec5SDimitry Andric                                     isCompilingModuleHeader);
12350b57cec5SDimitry Andric   }
12360b57cec5SDimitry Andric 
12370b57cec5SDimitry Andric   // Notify callbacks that we just added a new header.
12380b57cec5SDimitry Andric   for (const auto &Cb : Callbacks)
12390b57cec5SDimitry Andric     Cb->moduleMapAddHeader(Header.Entry->getName());
12400b57cec5SDimitry Andric }
12410b57cec5SDimitry Andric 
excludeHeader(Module * Mod,Module::Header Header)12420b57cec5SDimitry Andric void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
12430b57cec5SDimitry Andric   // Add this as a known header so we won't implicitly add it to any
12440b57cec5SDimitry Andric   // umbrella directory module.
12450b57cec5SDimitry Andric   // FIXME: Should we only exclude it from umbrella modules within the
12460b57cec5SDimitry Andric   // specified module?
12470b57cec5SDimitry Andric   (void) Headers[Header.Entry];
12480b57cec5SDimitry Andric 
12490b57cec5SDimitry Andric   Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
12500b57cec5SDimitry Andric }
12510b57cec5SDimitry Andric 
12520b57cec5SDimitry Andric const FileEntry *
getContainingModuleMapFile(const Module * Module) const12530b57cec5SDimitry Andric ModuleMap::getContainingModuleMapFile(const Module *Module) const {
12540b57cec5SDimitry Andric   if (Module->DefinitionLoc.isInvalid())
12550b57cec5SDimitry Andric     return nullptr;
12560b57cec5SDimitry Andric 
12570b57cec5SDimitry Andric   return SourceMgr.getFileEntryForID(
12580b57cec5SDimitry Andric            SourceMgr.getFileID(Module->DefinitionLoc));
12590b57cec5SDimitry Andric }
12600b57cec5SDimitry Andric 
getModuleMapFileForUniquing(const Module * M) const12610b57cec5SDimitry Andric const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
12620b57cec5SDimitry Andric   if (M->IsInferred) {
12630b57cec5SDimitry Andric     assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
12640b57cec5SDimitry Andric     return InferredModuleAllowedBy.find(M)->second;
12650b57cec5SDimitry Andric   }
12660b57cec5SDimitry Andric   return getContainingModuleMapFile(M);
12670b57cec5SDimitry Andric }
12680b57cec5SDimitry Andric 
setInferredModuleAllowedBy(Module * M,const FileEntry * ModMap)12690b57cec5SDimitry Andric void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
12700b57cec5SDimitry Andric   assert(M->IsInferred && "module not inferred");
12710b57cec5SDimitry Andric   InferredModuleAllowedBy[M] = ModMap;
12720b57cec5SDimitry Andric }
12730b57cec5SDimitry Andric 
addAdditionalModuleMapFile(const Module * M,const FileEntry * ModuleMap)12745ffd83dbSDimitry Andric void ModuleMap::addAdditionalModuleMapFile(const Module *M,
12755ffd83dbSDimitry Andric                                            const FileEntry *ModuleMap) {
12765ffd83dbSDimitry Andric   AdditionalModMaps[M].insert(ModuleMap);
12775ffd83dbSDimitry Andric }
12785ffd83dbSDimitry Andric 
dump()12790b57cec5SDimitry Andric LLVM_DUMP_METHOD void ModuleMap::dump() {
12800b57cec5SDimitry Andric   llvm::errs() << "Modules:";
12810b57cec5SDimitry Andric   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
12820b57cec5SDimitry Andric                                         MEnd = Modules.end();
12830b57cec5SDimitry Andric        M != MEnd; ++M)
12840b57cec5SDimitry Andric     M->getValue()->print(llvm::errs(), 2);
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric   llvm::errs() << "Headers:";
12870b57cec5SDimitry Andric   for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
12880b57cec5SDimitry Andric        H != HEnd; ++H) {
12890b57cec5SDimitry Andric     llvm::errs() << "  \"" << H->first->getName() << "\" -> ";
12900b57cec5SDimitry Andric     for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
12910b57cec5SDimitry Andric                                                       E = H->second.end();
12920b57cec5SDimitry Andric          I != E; ++I) {
12930b57cec5SDimitry Andric       if (I != H->second.begin())
12940b57cec5SDimitry Andric         llvm::errs() << ",";
12950b57cec5SDimitry Andric       llvm::errs() << I->getModule()->getFullModuleName();
12960b57cec5SDimitry Andric     }
12970b57cec5SDimitry Andric     llvm::errs() << "\n";
12980b57cec5SDimitry Andric   }
12990b57cec5SDimitry Andric }
13000b57cec5SDimitry Andric 
resolveExports(Module * Mod,bool Complain)13010b57cec5SDimitry Andric bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
13020b57cec5SDimitry Andric   auto Unresolved = std::move(Mod->UnresolvedExports);
13030b57cec5SDimitry Andric   Mod->UnresolvedExports.clear();
13040b57cec5SDimitry Andric   for (auto &UE : Unresolved) {
13050b57cec5SDimitry Andric     Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
13060b57cec5SDimitry Andric     if (Export.getPointer() || Export.getInt())
13070b57cec5SDimitry Andric       Mod->Exports.push_back(Export);
13080b57cec5SDimitry Andric     else
13090b57cec5SDimitry Andric       Mod->UnresolvedExports.push_back(UE);
13100b57cec5SDimitry Andric   }
13110b57cec5SDimitry Andric   return !Mod->UnresolvedExports.empty();
13120b57cec5SDimitry Andric }
13130b57cec5SDimitry Andric 
resolveUses(Module * Mod,bool Complain)13140b57cec5SDimitry Andric bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
13150b57cec5SDimitry Andric   auto Unresolved = std::move(Mod->UnresolvedDirectUses);
13160b57cec5SDimitry Andric   Mod->UnresolvedDirectUses.clear();
13170b57cec5SDimitry Andric   for (auto &UDU : Unresolved) {
13180b57cec5SDimitry Andric     Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
13190b57cec5SDimitry Andric     if (DirectUse)
13200b57cec5SDimitry Andric       Mod->DirectUses.push_back(DirectUse);
13210b57cec5SDimitry Andric     else
13220b57cec5SDimitry Andric       Mod->UnresolvedDirectUses.push_back(UDU);
13230b57cec5SDimitry Andric   }
13240b57cec5SDimitry Andric   return !Mod->UnresolvedDirectUses.empty();
13250b57cec5SDimitry Andric }
13260b57cec5SDimitry Andric 
resolveConflicts(Module * Mod,bool Complain)13270b57cec5SDimitry Andric bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
13280b57cec5SDimitry Andric   auto Unresolved = std::move(Mod->UnresolvedConflicts);
13290b57cec5SDimitry Andric   Mod->UnresolvedConflicts.clear();
13300b57cec5SDimitry Andric   for (auto &UC : Unresolved) {
13310b57cec5SDimitry Andric     if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
13320b57cec5SDimitry Andric       Module::Conflict Conflict;
13330b57cec5SDimitry Andric       Conflict.Other = OtherMod;
13340b57cec5SDimitry Andric       Conflict.Message = UC.Message;
13350b57cec5SDimitry Andric       Mod->Conflicts.push_back(Conflict);
13360b57cec5SDimitry Andric     } else
13370b57cec5SDimitry Andric       Mod->UnresolvedConflicts.push_back(UC);
13380b57cec5SDimitry Andric   }
13390b57cec5SDimitry Andric   return !Mod->UnresolvedConflicts.empty();
13400b57cec5SDimitry Andric }
13410b57cec5SDimitry Andric 
13420b57cec5SDimitry Andric //----------------------------------------------------------------------------//
13430b57cec5SDimitry Andric // Module map file parser
13440b57cec5SDimitry Andric //----------------------------------------------------------------------------//
13450b57cec5SDimitry Andric 
13460b57cec5SDimitry Andric namespace clang {
13470b57cec5SDimitry Andric 
13480b57cec5SDimitry Andric   /// A token in a module map file.
13490b57cec5SDimitry Andric   struct MMToken {
13500b57cec5SDimitry Andric     enum TokenKind {
13510b57cec5SDimitry Andric       Comma,
13520b57cec5SDimitry Andric       ConfigMacros,
13530b57cec5SDimitry Andric       Conflict,
13540b57cec5SDimitry Andric       EndOfFile,
13550b57cec5SDimitry Andric       HeaderKeyword,
13560b57cec5SDimitry Andric       Identifier,
13570b57cec5SDimitry Andric       Exclaim,
13580b57cec5SDimitry Andric       ExcludeKeyword,
13590b57cec5SDimitry Andric       ExplicitKeyword,
13600b57cec5SDimitry Andric       ExportKeyword,
13610b57cec5SDimitry Andric       ExportAsKeyword,
13620b57cec5SDimitry Andric       ExternKeyword,
13630b57cec5SDimitry Andric       FrameworkKeyword,
13640b57cec5SDimitry Andric       LinkKeyword,
13650b57cec5SDimitry Andric       ModuleKeyword,
13660b57cec5SDimitry Andric       Period,
13670b57cec5SDimitry Andric       PrivateKeyword,
13680b57cec5SDimitry Andric       UmbrellaKeyword,
13690b57cec5SDimitry Andric       UseKeyword,
13700b57cec5SDimitry Andric       RequiresKeyword,
13710b57cec5SDimitry Andric       Star,
13720b57cec5SDimitry Andric       StringLiteral,
13730b57cec5SDimitry Andric       IntegerLiteral,
13740b57cec5SDimitry Andric       TextualKeyword,
13750b57cec5SDimitry Andric       LBrace,
13760b57cec5SDimitry Andric       RBrace,
13770b57cec5SDimitry Andric       LSquare,
13780b57cec5SDimitry Andric       RSquare
13790b57cec5SDimitry Andric     } Kind;
13800b57cec5SDimitry Andric 
1381*5f7ddb14SDimitry Andric     SourceLocation::UIntTy Location;
13820b57cec5SDimitry Andric     unsigned StringLength;
13830b57cec5SDimitry Andric     union {
13840b57cec5SDimitry Andric       // If Kind != IntegerLiteral.
13850b57cec5SDimitry Andric       const char *StringData;
13860b57cec5SDimitry Andric 
13870b57cec5SDimitry Andric       // If Kind == IntegerLiteral.
13880b57cec5SDimitry Andric       uint64_t IntegerValue;
13890b57cec5SDimitry Andric     };
13900b57cec5SDimitry Andric 
clearclang::MMToken13910b57cec5SDimitry Andric     void clear() {
13920b57cec5SDimitry Andric       Kind = EndOfFile;
13930b57cec5SDimitry Andric       Location = 0;
13940b57cec5SDimitry Andric       StringLength = 0;
13950b57cec5SDimitry Andric       StringData = nullptr;
13960b57cec5SDimitry Andric     }
13970b57cec5SDimitry Andric 
isclang::MMToken13980b57cec5SDimitry Andric     bool is(TokenKind K) const { return Kind == K; }
13990b57cec5SDimitry Andric 
getLocationclang::MMToken14000b57cec5SDimitry Andric     SourceLocation getLocation() const {
14010b57cec5SDimitry Andric       return SourceLocation::getFromRawEncoding(Location);
14020b57cec5SDimitry Andric     }
14030b57cec5SDimitry Andric 
getIntegerclang::MMToken14040b57cec5SDimitry Andric     uint64_t getInteger() const {
14050b57cec5SDimitry Andric       return Kind == IntegerLiteral ? IntegerValue : 0;
14060b57cec5SDimitry Andric     }
14070b57cec5SDimitry Andric 
getStringclang::MMToken14080b57cec5SDimitry Andric     StringRef getString() const {
14090b57cec5SDimitry Andric       return Kind == IntegerLiteral ? StringRef()
14100b57cec5SDimitry Andric                                     : StringRef(StringData, StringLength);
14110b57cec5SDimitry Andric     }
14120b57cec5SDimitry Andric   };
14130b57cec5SDimitry Andric 
14140b57cec5SDimitry Andric   class ModuleMapParser {
14150b57cec5SDimitry Andric     Lexer &L;
14160b57cec5SDimitry Andric     SourceManager &SourceMgr;
14170b57cec5SDimitry Andric 
14180b57cec5SDimitry Andric     /// Default target information, used only for string literal
14190b57cec5SDimitry Andric     /// parsing.
14200b57cec5SDimitry Andric     const TargetInfo *Target;
14210b57cec5SDimitry Andric 
14220b57cec5SDimitry Andric     DiagnosticsEngine &Diags;
14230b57cec5SDimitry Andric     ModuleMap &Map;
14240b57cec5SDimitry Andric 
14250b57cec5SDimitry Andric     /// The current module map file.
14260b57cec5SDimitry Andric     const FileEntry *ModuleMapFile;
14270b57cec5SDimitry Andric 
14280b57cec5SDimitry Andric     /// Source location of most recent parsed module declaration
14290b57cec5SDimitry Andric     SourceLocation CurrModuleDeclLoc;
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric     /// The directory that file names in this module map file should
14320b57cec5SDimitry Andric     /// be resolved relative to.
14330b57cec5SDimitry Andric     const DirectoryEntry *Directory;
14340b57cec5SDimitry Andric 
14350b57cec5SDimitry Andric     /// Whether this module map is in a system header directory.
14360b57cec5SDimitry Andric     bool IsSystem;
14370b57cec5SDimitry Andric 
14380b57cec5SDimitry Andric     /// Whether an error occurred.
14390b57cec5SDimitry Andric     bool HadError = false;
14400b57cec5SDimitry Andric 
14410b57cec5SDimitry Andric     /// Stores string data for the various string literals referenced
14420b57cec5SDimitry Andric     /// during parsing.
14430b57cec5SDimitry Andric     llvm::BumpPtrAllocator StringData;
14440b57cec5SDimitry Andric 
14450b57cec5SDimitry Andric     /// The current token.
14460b57cec5SDimitry Andric     MMToken Tok;
14470b57cec5SDimitry Andric 
14480b57cec5SDimitry Andric     /// The active module.
14490b57cec5SDimitry Andric     Module *ActiveModule = nullptr;
14500b57cec5SDimitry Andric 
14510b57cec5SDimitry Andric     /// Whether a module uses the 'requires excluded' hack to mark its
14520b57cec5SDimitry Andric     /// contents as 'textual'.
14530b57cec5SDimitry Andric     ///
14540b57cec5SDimitry Andric     /// On older Darwin SDK versions, 'requires excluded' is used to mark the
14550b57cec5SDimitry Andric     /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
14560b57cec5SDimitry Andric     /// non-modular headers.  For backwards compatibility, we continue to
14570b57cec5SDimitry Andric     /// support this idiom for just these modules, and map the headers to
14580b57cec5SDimitry Andric     /// 'textual' to match the original intent.
14590b57cec5SDimitry Andric     llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
14600b57cec5SDimitry Andric 
14610b57cec5SDimitry Andric     /// Consume the current token and return its location.
14620b57cec5SDimitry Andric     SourceLocation consumeToken();
14630b57cec5SDimitry Andric 
14640b57cec5SDimitry Andric     /// Skip tokens until we reach the a token with the given kind
14650b57cec5SDimitry Andric     /// (or the end of the file).
14660b57cec5SDimitry Andric     void skipUntil(MMToken::TokenKind K);
14670b57cec5SDimitry Andric 
14680b57cec5SDimitry Andric     using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>;
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric     bool parseModuleId(ModuleId &Id);
14710b57cec5SDimitry Andric     void parseModuleDecl();
14720b57cec5SDimitry Andric     void parseExternModuleDecl();
14730b57cec5SDimitry Andric     void parseRequiresDecl();
14740b57cec5SDimitry Andric     void parseHeaderDecl(MMToken::TokenKind, SourceLocation LeadingLoc);
14750b57cec5SDimitry Andric     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
14760b57cec5SDimitry Andric     void parseExportDecl();
14770b57cec5SDimitry Andric     void parseExportAsDecl();
14780b57cec5SDimitry Andric     void parseUseDecl();
14790b57cec5SDimitry Andric     void parseLinkDecl();
14800b57cec5SDimitry Andric     void parseConfigMacros();
14810b57cec5SDimitry Andric     void parseConflict();
14820b57cec5SDimitry Andric     void parseInferredModuleDecl(bool Framework, bool Explicit);
14830b57cec5SDimitry Andric 
14840b57cec5SDimitry Andric     /// Private modules are canonicalized as Foo_Private. Clang provides extra
14850b57cec5SDimitry Andric     /// module map search logic to find the appropriate private module when PCH
14860b57cec5SDimitry Andric     /// is used with implicit module maps. Warn when private modules are written
14870b57cec5SDimitry Andric     /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
14880b57cec5SDimitry Andric     void diagnosePrivateModules(SourceLocation ExplicitLoc,
14890b57cec5SDimitry Andric                                 SourceLocation FrameworkLoc);
14900b57cec5SDimitry Andric 
14910b57cec5SDimitry Andric     using Attributes = ModuleMap::Attributes;
14920b57cec5SDimitry Andric 
14930b57cec5SDimitry Andric     bool parseOptionalAttributes(Attributes &Attrs);
14940b57cec5SDimitry Andric 
14950b57cec5SDimitry Andric   public:
ModuleMapParser(Lexer & L,SourceManager & SourceMgr,const TargetInfo * Target,DiagnosticsEngine & Diags,ModuleMap & Map,const FileEntry * ModuleMapFile,const DirectoryEntry * Directory,bool IsSystem)14960b57cec5SDimitry Andric     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
14970b57cec5SDimitry Andric                              const TargetInfo *Target, DiagnosticsEngine &Diags,
14980b57cec5SDimitry Andric                              ModuleMap &Map, const FileEntry *ModuleMapFile,
14990b57cec5SDimitry Andric                              const DirectoryEntry *Directory, bool IsSystem)
15000b57cec5SDimitry Andric         : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
15010b57cec5SDimitry Andric           ModuleMapFile(ModuleMapFile), Directory(Directory),
15020b57cec5SDimitry Andric           IsSystem(IsSystem) {
15030b57cec5SDimitry Andric       Tok.clear();
15040b57cec5SDimitry Andric       consumeToken();
15050b57cec5SDimitry Andric     }
15060b57cec5SDimitry Andric 
15070b57cec5SDimitry Andric     bool parseModuleMapFile();
15080b57cec5SDimitry Andric 
terminatedByDirective()15090b57cec5SDimitry Andric     bool terminatedByDirective() { return false; }
getLocation()15100b57cec5SDimitry Andric     SourceLocation getLocation() { return Tok.getLocation(); }
15110b57cec5SDimitry Andric   };
15120b57cec5SDimitry Andric 
15130b57cec5SDimitry Andric } // namespace clang
15140b57cec5SDimitry Andric 
consumeToken()15150b57cec5SDimitry Andric SourceLocation ModuleMapParser::consumeToken() {
15160b57cec5SDimitry Andric   SourceLocation Result = Tok.getLocation();
15170b57cec5SDimitry Andric 
15180b57cec5SDimitry Andric retry:
15190b57cec5SDimitry Andric   Tok.clear();
15200b57cec5SDimitry Andric   Token LToken;
15210b57cec5SDimitry Andric   L.LexFromRawLexer(LToken);
15220b57cec5SDimitry Andric   Tok.Location = LToken.getLocation().getRawEncoding();
15230b57cec5SDimitry Andric   switch (LToken.getKind()) {
15240b57cec5SDimitry Andric   case tok::raw_identifier: {
15250b57cec5SDimitry Andric     StringRef RI = LToken.getRawIdentifier();
15260b57cec5SDimitry Andric     Tok.StringData = RI.data();
15270b57cec5SDimitry Andric     Tok.StringLength = RI.size();
15280b57cec5SDimitry Andric     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
15290b57cec5SDimitry Andric                  .Case("config_macros", MMToken::ConfigMacros)
15300b57cec5SDimitry Andric                  .Case("conflict", MMToken::Conflict)
15310b57cec5SDimitry Andric                  .Case("exclude", MMToken::ExcludeKeyword)
15320b57cec5SDimitry Andric                  .Case("explicit", MMToken::ExplicitKeyword)
15330b57cec5SDimitry Andric                  .Case("export", MMToken::ExportKeyword)
15340b57cec5SDimitry Andric                  .Case("export_as", MMToken::ExportAsKeyword)
15350b57cec5SDimitry Andric                  .Case("extern", MMToken::ExternKeyword)
15360b57cec5SDimitry Andric                  .Case("framework", MMToken::FrameworkKeyword)
15370b57cec5SDimitry Andric                  .Case("header", MMToken::HeaderKeyword)
15380b57cec5SDimitry Andric                  .Case("link", MMToken::LinkKeyword)
15390b57cec5SDimitry Andric                  .Case("module", MMToken::ModuleKeyword)
15400b57cec5SDimitry Andric                  .Case("private", MMToken::PrivateKeyword)
15410b57cec5SDimitry Andric                  .Case("requires", MMToken::RequiresKeyword)
15420b57cec5SDimitry Andric                  .Case("textual", MMToken::TextualKeyword)
15430b57cec5SDimitry Andric                  .Case("umbrella", MMToken::UmbrellaKeyword)
15440b57cec5SDimitry Andric                  .Case("use", MMToken::UseKeyword)
15450b57cec5SDimitry Andric                  .Default(MMToken::Identifier);
15460b57cec5SDimitry Andric     break;
15470b57cec5SDimitry Andric   }
15480b57cec5SDimitry Andric 
15490b57cec5SDimitry Andric   case tok::comma:
15500b57cec5SDimitry Andric     Tok.Kind = MMToken::Comma;
15510b57cec5SDimitry Andric     break;
15520b57cec5SDimitry Andric 
15530b57cec5SDimitry Andric   case tok::eof:
15540b57cec5SDimitry Andric     Tok.Kind = MMToken::EndOfFile;
15550b57cec5SDimitry Andric     break;
15560b57cec5SDimitry Andric 
15570b57cec5SDimitry Andric   case tok::l_brace:
15580b57cec5SDimitry Andric     Tok.Kind = MMToken::LBrace;
15590b57cec5SDimitry Andric     break;
15600b57cec5SDimitry Andric 
15610b57cec5SDimitry Andric   case tok::l_square:
15620b57cec5SDimitry Andric     Tok.Kind = MMToken::LSquare;
15630b57cec5SDimitry Andric     break;
15640b57cec5SDimitry Andric 
15650b57cec5SDimitry Andric   case tok::period:
15660b57cec5SDimitry Andric     Tok.Kind = MMToken::Period;
15670b57cec5SDimitry Andric     break;
15680b57cec5SDimitry Andric 
15690b57cec5SDimitry Andric   case tok::r_brace:
15700b57cec5SDimitry Andric     Tok.Kind = MMToken::RBrace;
15710b57cec5SDimitry Andric     break;
15720b57cec5SDimitry Andric 
15730b57cec5SDimitry Andric   case tok::r_square:
15740b57cec5SDimitry Andric     Tok.Kind = MMToken::RSquare;
15750b57cec5SDimitry Andric     break;
15760b57cec5SDimitry Andric 
15770b57cec5SDimitry Andric   case tok::star:
15780b57cec5SDimitry Andric     Tok.Kind = MMToken::Star;
15790b57cec5SDimitry Andric     break;
15800b57cec5SDimitry Andric 
15810b57cec5SDimitry Andric   case tok::exclaim:
15820b57cec5SDimitry Andric     Tok.Kind = MMToken::Exclaim;
15830b57cec5SDimitry Andric     break;
15840b57cec5SDimitry Andric 
15850b57cec5SDimitry Andric   case tok::string_literal: {
15860b57cec5SDimitry Andric     if (LToken.hasUDSuffix()) {
15870b57cec5SDimitry Andric       Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
15880b57cec5SDimitry Andric       HadError = true;
15890b57cec5SDimitry Andric       goto retry;
15900b57cec5SDimitry Andric     }
15910b57cec5SDimitry Andric 
15920b57cec5SDimitry Andric     // Parse the string literal.
15930b57cec5SDimitry Andric     LangOptions LangOpts;
15940b57cec5SDimitry Andric     StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
15950b57cec5SDimitry Andric     if (StringLiteral.hadError)
15960b57cec5SDimitry Andric       goto retry;
15970b57cec5SDimitry Andric 
15980b57cec5SDimitry Andric     // Copy the string literal into our string data allocator.
15990b57cec5SDimitry Andric     unsigned Length = StringLiteral.GetStringLength();
16000b57cec5SDimitry Andric     char *Saved = StringData.Allocate<char>(Length + 1);
16010b57cec5SDimitry Andric     memcpy(Saved, StringLiteral.GetString().data(), Length);
16020b57cec5SDimitry Andric     Saved[Length] = 0;
16030b57cec5SDimitry Andric 
16040b57cec5SDimitry Andric     // Form the token.
16050b57cec5SDimitry Andric     Tok.Kind = MMToken::StringLiteral;
16060b57cec5SDimitry Andric     Tok.StringData = Saved;
16070b57cec5SDimitry Andric     Tok.StringLength = Length;
16080b57cec5SDimitry Andric     break;
16090b57cec5SDimitry Andric   }
16100b57cec5SDimitry Andric 
16110b57cec5SDimitry Andric   case tok::numeric_constant: {
16120b57cec5SDimitry Andric     // We don't support any suffixes or other complications.
16130b57cec5SDimitry Andric     SmallString<32> SpellingBuffer;
16140b57cec5SDimitry Andric     SpellingBuffer.resize(LToken.getLength() + 1);
16150b57cec5SDimitry Andric     const char *Start = SpellingBuffer.data();
16160b57cec5SDimitry Andric     unsigned Length =
16170b57cec5SDimitry Andric         Lexer::getSpelling(LToken, Start, SourceMgr, L.getLangOpts());
16180b57cec5SDimitry Andric     uint64_t Value;
16190b57cec5SDimitry Andric     if (StringRef(Start, Length).getAsInteger(0, Value)) {
16200b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
16210b57cec5SDimitry Andric       HadError = true;
16220b57cec5SDimitry Andric       goto retry;
16230b57cec5SDimitry Andric     }
16240b57cec5SDimitry Andric 
16250b57cec5SDimitry Andric     Tok.Kind = MMToken::IntegerLiteral;
16260b57cec5SDimitry Andric     Tok.IntegerValue = Value;
16270b57cec5SDimitry Andric     break;
16280b57cec5SDimitry Andric   }
16290b57cec5SDimitry Andric 
16300b57cec5SDimitry Andric   case tok::comment:
16310b57cec5SDimitry Andric     goto retry;
16320b57cec5SDimitry Andric 
16330b57cec5SDimitry Andric   case tok::hash:
16340b57cec5SDimitry Andric     // A module map can be terminated prematurely by
16350b57cec5SDimitry Andric     //   #pragma clang module contents
16360b57cec5SDimitry Andric     // When building the module, we'll treat the rest of the file as the
16370b57cec5SDimitry Andric     // contents of the module.
16380b57cec5SDimitry Andric     {
16390b57cec5SDimitry Andric       auto NextIsIdent = [&](StringRef Str) -> bool {
16400b57cec5SDimitry Andric         L.LexFromRawLexer(LToken);
16410b57cec5SDimitry Andric         return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
16420b57cec5SDimitry Andric                LToken.getRawIdentifier() == Str;
16430b57cec5SDimitry Andric       };
16440b57cec5SDimitry Andric       if (NextIsIdent("pragma") && NextIsIdent("clang") &&
16450b57cec5SDimitry Andric           NextIsIdent("module") && NextIsIdent("contents")) {
16460b57cec5SDimitry Andric         Tok.Kind = MMToken::EndOfFile;
16470b57cec5SDimitry Andric         break;
16480b57cec5SDimitry Andric       }
16490b57cec5SDimitry Andric     }
16500b57cec5SDimitry Andric     LLVM_FALLTHROUGH;
16510b57cec5SDimitry Andric 
16520b57cec5SDimitry Andric   default:
16530b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
16540b57cec5SDimitry Andric     HadError = true;
16550b57cec5SDimitry Andric     goto retry;
16560b57cec5SDimitry Andric   }
16570b57cec5SDimitry Andric 
16580b57cec5SDimitry Andric   return Result;
16590b57cec5SDimitry Andric }
16600b57cec5SDimitry Andric 
skipUntil(MMToken::TokenKind K)16610b57cec5SDimitry Andric void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
16620b57cec5SDimitry Andric   unsigned braceDepth = 0;
16630b57cec5SDimitry Andric   unsigned squareDepth = 0;
16640b57cec5SDimitry Andric   do {
16650b57cec5SDimitry Andric     switch (Tok.Kind) {
16660b57cec5SDimitry Andric     case MMToken::EndOfFile:
16670b57cec5SDimitry Andric       return;
16680b57cec5SDimitry Andric 
16690b57cec5SDimitry Andric     case MMToken::LBrace:
16700b57cec5SDimitry Andric       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
16710b57cec5SDimitry Andric         return;
16720b57cec5SDimitry Andric 
16730b57cec5SDimitry Andric       ++braceDepth;
16740b57cec5SDimitry Andric       break;
16750b57cec5SDimitry Andric 
16760b57cec5SDimitry Andric     case MMToken::LSquare:
16770b57cec5SDimitry Andric       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
16780b57cec5SDimitry Andric         return;
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric       ++squareDepth;
16810b57cec5SDimitry Andric       break;
16820b57cec5SDimitry Andric 
16830b57cec5SDimitry Andric     case MMToken::RBrace:
16840b57cec5SDimitry Andric       if (braceDepth > 0)
16850b57cec5SDimitry Andric         --braceDepth;
16860b57cec5SDimitry Andric       else if (Tok.is(K))
16870b57cec5SDimitry Andric         return;
16880b57cec5SDimitry Andric       break;
16890b57cec5SDimitry Andric 
16900b57cec5SDimitry Andric     case MMToken::RSquare:
16910b57cec5SDimitry Andric       if (squareDepth > 0)
16920b57cec5SDimitry Andric         --squareDepth;
16930b57cec5SDimitry Andric       else if (Tok.is(K))
16940b57cec5SDimitry Andric         return;
16950b57cec5SDimitry Andric       break;
16960b57cec5SDimitry Andric 
16970b57cec5SDimitry Andric     default:
16980b57cec5SDimitry Andric       if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
16990b57cec5SDimitry Andric         return;
17000b57cec5SDimitry Andric       break;
17010b57cec5SDimitry Andric     }
17020b57cec5SDimitry Andric 
17030b57cec5SDimitry Andric    consumeToken();
17040b57cec5SDimitry Andric   } while (true);
17050b57cec5SDimitry Andric }
17060b57cec5SDimitry Andric 
17070b57cec5SDimitry Andric /// Parse a module-id.
17080b57cec5SDimitry Andric ///
17090b57cec5SDimitry Andric ///   module-id:
17100b57cec5SDimitry Andric ///     identifier
17110b57cec5SDimitry Andric ///     identifier '.' module-id
17120b57cec5SDimitry Andric ///
17130b57cec5SDimitry Andric /// \returns true if an error occurred, false otherwise.
parseModuleId(ModuleId & Id)17140b57cec5SDimitry Andric bool ModuleMapParser::parseModuleId(ModuleId &Id) {
17150b57cec5SDimitry Andric   Id.clear();
17160b57cec5SDimitry Andric   do {
17170b57cec5SDimitry Andric     if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
17185ffd83dbSDimitry Andric       Id.push_back(
17195ffd83dbSDimitry Andric           std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
17200b57cec5SDimitry Andric       consumeToken();
17210b57cec5SDimitry Andric     } else {
17220b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
17230b57cec5SDimitry Andric       return true;
17240b57cec5SDimitry Andric     }
17250b57cec5SDimitry Andric 
17260b57cec5SDimitry Andric     if (!Tok.is(MMToken::Period))
17270b57cec5SDimitry Andric       break;
17280b57cec5SDimitry Andric 
17290b57cec5SDimitry Andric     consumeToken();
17300b57cec5SDimitry Andric   } while (true);
17310b57cec5SDimitry Andric 
17320b57cec5SDimitry Andric   return false;
17330b57cec5SDimitry Andric }
17340b57cec5SDimitry Andric 
17350b57cec5SDimitry Andric namespace {
17360b57cec5SDimitry Andric 
17370b57cec5SDimitry Andric   /// Enumerates the known attributes.
17380b57cec5SDimitry Andric   enum AttributeKind {
17390b57cec5SDimitry Andric     /// An unknown attribute.
17400b57cec5SDimitry Andric     AT_unknown,
17410b57cec5SDimitry Andric 
17420b57cec5SDimitry Andric     /// The 'system' attribute.
17430b57cec5SDimitry Andric     AT_system,
17440b57cec5SDimitry Andric 
17450b57cec5SDimitry Andric     /// The 'extern_c' attribute.
17460b57cec5SDimitry Andric     AT_extern_c,
17470b57cec5SDimitry Andric 
17480b57cec5SDimitry Andric     /// The 'exhaustive' attribute.
17490b57cec5SDimitry Andric     AT_exhaustive,
17500b57cec5SDimitry Andric 
17510b57cec5SDimitry Andric     /// The 'no_undeclared_includes' attribute.
17520b57cec5SDimitry Andric     AT_no_undeclared_includes
17530b57cec5SDimitry Andric   };
17540b57cec5SDimitry Andric 
17550b57cec5SDimitry Andric } // namespace
17560b57cec5SDimitry Andric 
17570b57cec5SDimitry Andric /// Private modules are canonicalized as Foo_Private. Clang provides extra
17580b57cec5SDimitry Andric /// module map search logic to find the appropriate private module when PCH
17590b57cec5SDimitry Andric /// is used with implicit module maps. Warn when private modules are written
17600b57cec5SDimitry Andric /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
diagnosePrivateModules(SourceLocation ExplicitLoc,SourceLocation FrameworkLoc)17610b57cec5SDimitry Andric void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc,
17620b57cec5SDimitry Andric                                              SourceLocation FrameworkLoc) {
17630b57cec5SDimitry Andric   auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
17640b57cec5SDimitry Andric                              const Module *M, SourceRange ReplLoc) {
17650b57cec5SDimitry Andric     auto D = Diags.Report(ActiveModule->DefinitionLoc,
17660b57cec5SDimitry Andric                           diag::note_mmap_rename_top_level_private_module);
17670b57cec5SDimitry Andric     D << BadName << M->Name;
17680b57cec5SDimitry Andric     D << FixItHint::CreateReplacement(ReplLoc, Canonical);
17690b57cec5SDimitry Andric   };
17700b57cec5SDimitry Andric 
17710b57cec5SDimitry Andric   for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
17720b57cec5SDimitry Andric     auto const *M = E->getValue();
17730b57cec5SDimitry Andric     if (M->Directory != ActiveModule->Directory)
17740b57cec5SDimitry Andric       continue;
17750b57cec5SDimitry Andric 
17760b57cec5SDimitry Andric     SmallString<128> FullName(ActiveModule->getFullModuleName());
17770b57cec5SDimitry Andric     if (!FullName.startswith(M->Name) && !FullName.endswith("Private"))
17780b57cec5SDimitry Andric       continue;
17790b57cec5SDimitry Andric     SmallString<128> FixedPrivModDecl;
17800b57cec5SDimitry Andric     SmallString<128> Canonical(M->Name);
17810b57cec5SDimitry Andric     Canonical.append("_Private");
17820b57cec5SDimitry Andric 
17830b57cec5SDimitry Andric     // Foo.Private -> Foo_Private
17840b57cec5SDimitry Andric     if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
17850b57cec5SDimitry Andric         M->Name == ActiveModule->Parent->Name) {
17860b57cec5SDimitry Andric       Diags.Report(ActiveModule->DefinitionLoc,
17870b57cec5SDimitry Andric                    diag::warn_mmap_mismatched_private_submodule)
17880b57cec5SDimitry Andric           << FullName;
17890b57cec5SDimitry Andric 
17900b57cec5SDimitry Andric       SourceLocation FixItInitBegin = CurrModuleDeclLoc;
17910b57cec5SDimitry Andric       if (FrameworkLoc.isValid())
17920b57cec5SDimitry Andric         FixItInitBegin = FrameworkLoc;
17930b57cec5SDimitry Andric       if (ExplicitLoc.isValid())
17940b57cec5SDimitry Andric         FixItInitBegin = ExplicitLoc;
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric       if (FrameworkLoc.isValid() || ActiveModule->Parent->IsFramework)
17970b57cec5SDimitry Andric         FixedPrivModDecl.append("framework ");
17980b57cec5SDimitry Andric       FixedPrivModDecl.append("module ");
17990b57cec5SDimitry Andric       FixedPrivModDecl.append(Canonical);
18000b57cec5SDimitry Andric 
18010b57cec5SDimitry Andric       GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
18020b57cec5SDimitry Andric                       SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
18030b57cec5SDimitry Andric       continue;
18040b57cec5SDimitry Andric     }
18050b57cec5SDimitry Andric 
18060b57cec5SDimitry Andric     // FooPrivate and whatnots -> Foo_Private
18070b57cec5SDimitry Andric     if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
18080b57cec5SDimitry Andric         ActiveModule->Name != Canonical) {
18090b57cec5SDimitry Andric       Diags.Report(ActiveModule->DefinitionLoc,
18100b57cec5SDimitry Andric                    diag::warn_mmap_mismatched_private_module_name)
18110b57cec5SDimitry Andric           << ActiveModule->Name;
18120b57cec5SDimitry Andric       GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
18130b57cec5SDimitry Andric                       SourceRange(ActiveModule->DefinitionLoc));
18140b57cec5SDimitry Andric     }
18150b57cec5SDimitry Andric   }
18160b57cec5SDimitry Andric }
18170b57cec5SDimitry Andric 
18180b57cec5SDimitry Andric /// Parse a module declaration.
18190b57cec5SDimitry Andric ///
18200b57cec5SDimitry Andric ///   module-declaration:
18210b57cec5SDimitry Andric ///     'extern' 'module' module-id string-literal
18220b57cec5SDimitry Andric ///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
18230b57cec5SDimitry Andric ///       { module-member* }
18240b57cec5SDimitry Andric ///
18250b57cec5SDimitry Andric ///   module-member:
18260b57cec5SDimitry Andric ///     requires-declaration
18270b57cec5SDimitry Andric ///     header-declaration
18280b57cec5SDimitry Andric ///     submodule-declaration
18290b57cec5SDimitry Andric ///     export-declaration
18300b57cec5SDimitry Andric ///     export-as-declaration
18310b57cec5SDimitry Andric ///     link-declaration
18320b57cec5SDimitry Andric ///
18330b57cec5SDimitry Andric ///   submodule-declaration:
18340b57cec5SDimitry Andric ///     module-declaration
18350b57cec5SDimitry Andric ///     inferred-submodule-declaration
parseModuleDecl()18360b57cec5SDimitry Andric void ModuleMapParser::parseModuleDecl() {
18370b57cec5SDimitry Andric   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
18380b57cec5SDimitry Andric          Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
18390b57cec5SDimitry Andric   if (Tok.is(MMToken::ExternKeyword)) {
18400b57cec5SDimitry Andric     parseExternModuleDecl();
18410b57cec5SDimitry Andric     return;
18420b57cec5SDimitry Andric   }
18430b57cec5SDimitry Andric 
18440b57cec5SDimitry Andric   // Parse 'explicit' or 'framework' keyword, if present.
18450b57cec5SDimitry Andric   SourceLocation ExplicitLoc;
18460b57cec5SDimitry Andric   SourceLocation FrameworkLoc;
18470b57cec5SDimitry Andric   bool Explicit = false;
18480b57cec5SDimitry Andric   bool Framework = false;
18490b57cec5SDimitry Andric 
18500b57cec5SDimitry Andric   // Parse 'explicit' keyword, if present.
18510b57cec5SDimitry Andric   if (Tok.is(MMToken::ExplicitKeyword)) {
18520b57cec5SDimitry Andric     ExplicitLoc = consumeToken();
18530b57cec5SDimitry Andric     Explicit = true;
18540b57cec5SDimitry Andric   }
18550b57cec5SDimitry Andric 
18560b57cec5SDimitry Andric   // Parse 'framework' keyword, if present.
18570b57cec5SDimitry Andric   if (Tok.is(MMToken::FrameworkKeyword)) {
18580b57cec5SDimitry Andric     FrameworkLoc = consumeToken();
18590b57cec5SDimitry Andric     Framework = true;
18600b57cec5SDimitry Andric   }
18610b57cec5SDimitry Andric 
18620b57cec5SDimitry Andric   // Parse 'module' keyword.
18630b57cec5SDimitry Andric   if (!Tok.is(MMToken::ModuleKeyword)) {
18640b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
18650b57cec5SDimitry Andric     consumeToken();
18660b57cec5SDimitry Andric     HadError = true;
18670b57cec5SDimitry Andric     return;
18680b57cec5SDimitry Andric   }
18690b57cec5SDimitry Andric   CurrModuleDeclLoc = consumeToken(); // 'module' keyword
18700b57cec5SDimitry Andric 
18710b57cec5SDimitry Andric   // If we have a wildcard for the module name, this is an inferred submodule.
18720b57cec5SDimitry Andric   // Parse it.
18730b57cec5SDimitry Andric   if (Tok.is(MMToken::Star))
18740b57cec5SDimitry Andric     return parseInferredModuleDecl(Framework, Explicit);
18750b57cec5SDimitry Andric 
18760b57cec5SDimitry Andric   // Parse the module name.
18770b57cec5SDimitry Andric   ModuleId Id;
18780b57cec5SDimitry Andric   if (parseModuleId(Id)) {
18790b57cec5SDimitry Andric     HadError = true;
18800b57cec5SDimitry Andric     return;
18810b57cec5SDimitry Andric   }
18820b57cec5SDimitry Andric 
18830b57cec5SDimitry Andric   if (ActiveModule) {
18840b57cec5SDimitry Andric     if (Id.size() > 1) {
18850b57cec5SDimitry Andric       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
18860b57cec5SDimitry Andric         << SourceRange(Id.front().second, Id.back().second);
18870b57cec5SDimitry Andric 
18880b57cec5SDimitry Andric       HadError = true;
18890b57cec5SDimitry Andric       return;
18900b57cec5SDimitry Andric     }
18910b57cec5SDimitry Andric   } else if (Id.size() == 1 && Explicit) {
18920b57cec5SDimitry Andric     // Top-level modules can't be explicit.
18930b57cec5SDimitry Andric     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
18940b57cec5SDimitry Andric     Explicit = false;
18950b57cec5SDimitry Andric     ExplicitLoc = SourceLocation();
18960b57cec5SDimitry Andric     HadError = true;
18970b57cec5SDimitry Andric   }
18980b57cec5SDimitry Andric 
18990b57cec5SDimitry Andric   Module *PreviousActiveModule = ActiveModule;
19000b57cec5SDimitry Andric   if (Id.size() > 1) {
19010b57cec5SDimitry Andric     // This module map defines a submodule. Go find the module of which it
19020b57cec5SDimitry Andric     // is a submodule.
19030b57cec5SDimitry Andric     ActiveModule = nullptr;
19040b57cec5SDimitry Andric     const Module *TopLevelModule = nullptr;
19050b57cec5SDimitry Andric     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
19060b57cec5SDimitry Andric       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
19070b57cec5SDimitry Andric         if (I == 0)
19080b57cec5SDimitry Andric           TopLevelModule = Next;
19090b57cec5SDimitry Andric         ActiveModule = Next;
19100b57cec5SDimitry Andric         continue;
19110b57cec5SDimitry Andric       }
19120b57cec5SDimitry Andric 
1913af732203SDimitry Andric       Diags.Report(Id[I].second, diag::err_mmap_missing_parent_module)
1914af732203SDimitry Andric           << Id[I].first << (ActiveModule != nullptr)
1915af732203SDimitry Andric           << (ActiveModule
1916af732203SDimitry Andric                   ? ActiveModule->getTopLevelModule()->getFullModuleName()
1917af732203SDimitry Andric                   : "");
19180b57cec5SDimitry Andric       HadError = true;
19190b57cec5SDimitry Andric     }
19200b57cec5SDimitry Andric 
1921af732203SDimitry Andric     if (TopLevelModule &&
1922af732203SDimitry Andric         ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
19230b57cec5SDimitry Andric       assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
19240b57cec5SDimitry Andric              "submodule defined in same file as 'module *' that allowed its "
19250b57cec5SDimitry Andric              "top-level module");
19260b57cec5SDimitry Andric       Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
19270b57cec5SDimitry Andric     }
19280b57cec5SDimitry Andric   }
19290b57cec5SDimitry Andric 
19300b57cec5SDimitry Andric   StringRef ModuleName = Id.back().first;
19310b57cec5SDimitry Andric   SourceLocation ModuleNameLoc = Id.back().second;
19320b57cec5SDimitry Andric 
19330b57cec5SDimitry Andric   // Parse the optional attribute list.
19340b57cec5SDimitry Andric   Attributes Attrs;
19350b57cec5SDimitry Andric   if (parseOptionalAttributes(Attrs))
19360b57cec5SDimitry Andric     return;
19370b57cec5SDimitry Andric 
19380b57cec5SDimitry Andric   // Parse the opening brace.
19390b57cec5SDimitry Andric   if (!Tok.is(MMToken::LBrace)) {
19400b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
19410b57cec5SDimitry Andric       << ModuleName;
19420b57cec5SDimitry Andric     HadError = true;
19430b57cec5SDimitry Andric     return;
19440b57cec5SDimitry Andric   }
19450b57cec5SDimitry Andric   SourceLocation LBraceLoc = consumeToken();
19460b57cec5SDimitry Andric 
19470b57cec5SDimitry Andric   // Determine whether this (sub)module has already been defined.
19480b57cec5SDimitry Andric   Module *ShadowingModule = nullptr;
19490b57cec5SDimitry Andric   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
19500b57cec5SDimitry Andric     // We might see a (re)definition of a module that we already have a
19510b57cec5SDimitry Andric     // definition for in two cases:
19520b57cec5SDimitry Andric     //  - If we loaded one definition from an AST file and we've just found a
19530b57cec5SDimitry Andric     //    corresponding definition in a module map file, or
19540b57cec5SDimitry Andric     bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid();
19550b57cec5SDimitry Andric     //  - If we're building a (preprocessed) module and we've just loaded the
19560b57cec5SDimitry Andric     //    module map file from which it was created.
19570b57cec5SDimitry Andric     bool ParsedAsMainInput =
19580b57cec5SDimitry Andric         Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
19590b57cec5SDimitry Andric         Map.LangOpts.CurrentModule == ModuleName &&
19600b57cec5SDimitry Andric         SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
19610b57cec5SDimitry Andric             SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
19620b57cec5SDimitry Andric     if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
19630b57cec5SDimitry Andric       // Skip the module definition.
19640b57cec5SDimitry Andric       skipUntil(MMToken::RBrace);
19650b57cec5SDimitry Andric       if (Tok.is(MMToken::RBrace))
19660b57cec5SDimitry Andric         consumeToken();
19670b57cec5SDimitry Andric       else {
19680b57cec5SDimitry Andric         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
19690b57cec5SDimitry Andric         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
19700b57cec5SDimitry Andric         HadError = true;
19710b57cec5SDimitry Andric       }
19720b57cec5SDimitry Andric       return;
19730b57cec5SDimitry Andric     }
19740b57cec5SDimitry Andric 
19750b57cec5SDimitry Andric     if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
19760b57cec5SDimitry Andric       ShadowingModule = Existing;
19770b57cec5SDimitry Andric     } else {
19780b57cec5SDimitry Andric       // This is not a shawdowed module decl, it is an illegal redefinition.
19790b57cec5SDimitry Andric       Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
19800b57cec5SDimitry Andric           << ModuleName;
19810b57cec5SDimitry Andric       Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
19820b57cec5SDimitry Andric 
19830b57cec5SDimitry Andric       // Skip the module definition.
19840b57cec5SDimitry Andric       skipUntil(MMToken::RBrace);
19850b57cec5SDimitry Andric       if (Tok.is(MMToken::RBrace))
19860b57cec5SDimitry Andric         consumeToken();
19870b57cec5SDimitry Andric 
19880b57cec5SDimitry Andric       HadError = true;
19890b57cec5SDimitry Andric       return;
19900b57cec5SDimitry Andric     }
19910b57cec5SDimitry Andric   }
19920b57cec5SDimitry Andric 
19930b57cec5SDimitry Andric   // Start defining this module.
19940b57cec5SDimitry Andric   if (ShadowingModule) {
19950b57cec5SDimitry Andric     ActiveModule =
19960b57cec5SDimitry Andric         Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
19970b57cec5SDimitry Andric   } else {
19980b57cec5SDimitry Andric     ActiveModule =
19990b57cec5SDimitry Andric         Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
20000b57cec5SDimitry Andric             .first;
20010b57cec5SDimitry Andric   }
20020b57cec5SDimitry Andric 
20030b57cec5SDimitry Andric   ActiveModule->DefinitionLoc = ModuleNameLoc;
20040b57cec5SDimitry Andric   if (Attrs.IsSystem || IsSystem)
20050b57cec5SDimitry Andric     ActiveModule->IsSystem = true;
20060b57cec5SDimitry Andric   if (Attrs.IsExternC)
20070b57cec5SDimitry Andric     ActiveModule->IsExternC = true;
20080b57cec5SDimitry Andric   if (Attrs.NoUndeclaredIncludes ||
20090b57cec5SDimitry Andric       (!ActiveModule->Parent && ModuleName == "Darwin"))
20100b57cec5SDimitry Andric     ActiveModule->NoUndeclaredIncludes = true;
20110b57cec5SDimitry Andric   ActiveModule->Directory = Directory;
20120b57cec5SDimitry Andric 
20130b57cec5SDimitry Andric   StringRef MapFileName(ModuleMapFile->getName());
20140b57cec5SDimitry Andric   if (MapFileName.endswith("module.private.modulemap") ||
20150b57cec5SDimitry Andric       MapFileName.endswith("module_private.map")) {
20160b57cec5SDimitry Andric     ActiveModule->ModuleMapIsPrivate = true;
20170b57cec5SDimitry Andric   }
20180b57cec5SDimitry Andric 
20190b57cec5SDimitry Andric   // Private modules named as FooPrivate, Foo.Private or similar are likely a
20200b57cec5SDimitry Andric   // user error; provide warnings, notes and fixits to direct users to use
20210b57cec5SDimitry Andric   // Foo_Private instead.
20220b57cec5SDimitry Andric   SourceLocation StartLoc =
20230b57cec5SDimitry Andric       SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
20240b57cec5SDimitry Andric   if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
20250b57cec5SDimitry Andric       !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
20260b57cec5SDimitry Andric                        StartLoc) &&
20270b57cec5SDimitry Andric       !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
20280b57cec5SDimitry Andric                        StartLoc) &&
20290b57cec5SDimitry Andric       ActiveModule->ModuleMapIsPrivate)
20300b57cec5SDimitry Andric     diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
20310b57cec5SDimitry Andric 
20320b57cec5SDimitry Andric   bool Done = false;
20330b57cec5SDimitry Andric   do {
20340b57cec5SDimitry Andric     switch (Tok.Kind) {
20350b57cec5SDimitry Andric     case MMToken::EndOfFile:
20360b57cec5SDimitry Andric     case MMToken::RBrace:
20370b57cec5SDimitry Andric       Done = true;
20380b57cec5SDimitry Andric       break;
20390b57cec5SDimitry Andric 
20400b57cec5SDimitry Andric     case MMToken::ConfigMacros:
20410b57cec5SDimitry Andric       parseConfigMacros();
20420b57cec5SDimitry Andric       break;
20430b57cec5SDimitry Andric 
20440b57cec5SDimitry Andric     case MMToken::Conflict:
20450b57cec5SDimitry Andric       parseConflict();
20460b57cec5SDimitry Andric       break;
20470b57cec5SDimitry Andric 
20480b57cec5SDimitry Andric     case MMToken::ExplicitKeyword:
20490b57cec5SDimitry Andric     case MMToken::ExternKeyword:
20500b57cec5SDimitry Andric     case MMToken::FrameworkKeyword:
20510b57cec5SDimitry Andric     case MMToken::ModuleKeyword:
20520b57cec5SDimitry Andric       parseModuleDecl();
20530b57cec5SDimitry Andric       break;
20540b57cec5SDimitry Andric 
20550b57cec5SDimitry Andric     case MMToken::ExportKeyword:
20560b57cec5SDimitry Andric       parseExportDecl();
20570b57cec5SDimitry Andric       break;
20580b57cec5SDimitry Andric 
20590b57cec5SDimitry Andric     case MMToken::ExportAsKeyword:
20600b57cec5SDimitry Andric       parseExportAsDecl();
20610b57cec5SDimitry Andric       break;
20620b57cec5SDimitry Andric 
20630b57cec5SDimitry Andric     case MMToken::UseKeyword:
20640b57cec5SDimitry Andric       parseUseDecl();
20650b57cec5SDimitry Andric       break;
20660b57cec5SDimitry Andric 
20670b57cec5SDimitry Andric     case MMToken::RequiresKeyword:
20680b57cec5SDimitry Andric       parseRequiresDecl();
20690b57cec5SDimitry Andric       break;
20700b57cec5SDimitry Andric 
20710b57cec5SDimitry Andric     case MMToken::TextualKeyword:
20720b57cec5SDimitry Andric       parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
20730b57cec5SDimitry Andric       break;
20740b57cec5SDimitry Andric 
20750b57cec5SDimitry Andric     case MMToken::UmbrellaKeyword: {
20760b57cec5SDimitry Andric       SourceLocation UmbrellaLoc = consumeToken();
20770b57cec5SDimitry Andric       if (Tok.is(MMToken::HeaderKeyword))
20780b57cec5SDimitry Andric         parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
20790b57cec5SDimitry Andric       else
20800b57cec5SDimitry Andric         parseUmbrellaDirDecl(UmbrellaLoc);
20810b57cec5SDimitry Andric       break;
20820b57cec5SDimitry Andric     }
20830b57cec5SDimitry Andric 
20840b57cec5SDimitry Andric     case MMToken::ExcludeKeyword:
20850b57cec5SDimitry Andric       parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
20860b57cec5SDimitry Andric       break;
20870b57cec5SDimitry Andric 
20880b57cec5SDimitry Andric     case MMToken::PrivateKeyword:
20890b57cec5SDimitry Andric       parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
20900b57cec5SDimitry Andric       break;
20910b57cec5SDimitry Andric 
20920b57cec5SDimitry Andric     case MMToken::HeaderKeyword:
20930b57cec5SDimitry Andric       parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
20940b57cec5SDimitry Andric       break;
20950b57cec5SDimitry Andric 
20960b57cec5SDimitry Andric     case MMToken::LinkKeyword:
20970b57cec5SDimitry Andric       parseLinkDecl();
20980b57cec5SDimitry Andric       break;
20990b57cec5SDimitry Andric 
21000b57cec5SDimitry Andric     default:
21010b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
21020b57cec5SDimitry Andric       consumeToken();
21030b57cec5SDimitry Andric       break;
21040b57cec5SDimitry Andric     }
21050b57cec5SDimitry Andric   } while (!Done);
21060b57cec5SDimitry Andric 
21070b57cec5SDimitry Andric   if (Tok.is(MMToken::RBrace))
21080b57cec5SDimitry Andric     consumeToken();
21090b57cec5SDimitry Andric   else {
21100b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
21110b57cec5SDimitry Andric     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
21120b57cec5SDimitry Andric     HadError = true;
21130b57cec5SDimitry Andric   }
21140b57cec5SDimitry Andric 
21150b57cec5SDimitry Andric   // If the active module is a top-level framework, and there are no link
21160b57cec5SDimitry Andric   // libraries, automatically link against the framework.
21170b57cec5SDimitry Andric   if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
21180b57cec5SDimitry Andric       ActiveModule->LinkLibraries.empty()) {
21190b57cec5SDimitry Andric     inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
21200b57cec5SDimitry Andric   }
21210b57cec5SDimitry Andric 
21220b57cec5SDimitry Andric   // If the module meets all requirements but is still unavailable, mark the
21230b57cec5SDimitry Andric   // whole tree as unavailable to prevent it from building.
21245ffd83dbSDimitry Andric   if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
21250b57cec5SDimitry Andric       ActiveModule->Parent) {
21265ffd83dbSDimitry Andric     ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
21270b57cec5SDimitry Andric     ActiveModule->getTopLevelModule()->MissingHeaders.append(
21280b57cec5SDimitry Andric       ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
21290b57cec5SDimitry Andric   }
21300b57cec5SDimitry Andric 
21310b57cec5SDimitry Andric   // We're done parsing this module. Pop back to the previous module.
21320b57cec5SDimitry Andric   ActiveModule = PreviousActiveModule;
21330b57cec5SDimitry Andric }
21340b57cec5SDimitry Andric 
21350b57cec5SDimitry Andric /// Parse an extern module declaration.
21360b57cec5SDimitry Andric ///
21370b57cec5SDimitry Andric ///   extern module-declaration:
21380b57cec5SDimitry Andric ///     'extern' 'module' module-id string-literal
parseExternModuleDecl()21390b57cec5SDimitry Andric void ModuleMapParser::parseExternModuleDecl() {
21400b57cec5SDimitry Andric   assert(Tok.is(MMToken::ExternKeyword));
21410b57cec5SDimitry Andric   SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
21420b57cec5SDimitry Andric 
21430b57cec5SDimitry Andric   // Parse 'module' keyword.
21440b57cec5SDimitry Andric   if (!Tok.is(MMToken::ModuleKeyword)) {
21450b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
21460b57cec5SDimitry Andric     consumeToken();
21470b57cec5SDimitry Andric     HadError = true;
21480b57cec5SDimitry Andric     return;
21490b57cec5SDimitry Andric   }
21500b57cec5SDimitry Andric   consumeToken(); // 'module' keyword
21510b57cec5SDimitry Andric 
21520b57cec5SDimitry Andric   // Parse the module name.
21530b57cec5SDimitry Andric   ModuleId Id;
21540b57cec5SDimitry Andric   if (parseModuleId(Id)) {
21550b57cec5SDimitry Andric     HadError = true;
21560b57cec5SDimitry Andric     return;
21570b57cec5SDimitry Andric   }
21580b57cec5SDimitry Andric 
21590b57cec5SDimitry Andric   // Parse the referenced module map file name.
21600b57cec5SDimitry Andric   if (!Tok.is(MMToken::StringLiteral)) {
21610b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
21620b57cec5SDimitry Andric     HadError = true;
21630b57cec5SDimitry Andric     return;
21640b57cec5SDimitry Andric   }
21655ffd83dbSDimitry Andric   std::string FileName = std::string(Tok.getString());
21660b57cec5SDimitry Andric   consumeToken(); // filename
21670b57cec5SDimitry Andric 
21680b57cec5SDimitry Andric   StringRef FileNameRef = FileName;
21690b57cec5SDimitry Andric   SmallString<128> ModuleMapFileName;
21700b57cec5SDimitry Andric   if (llvm::sys::path::is_relative(FileNameRef)) {
21710b57cec5SDimitry Andric     ModuleMapFileName += Directory->getName();
21720b57cec5SDimitry Andric     llvm::sys::path::append(ModuleMapFileName, FileName);
21730b57cec5SDimitry Andric     FileNameRef = ModuleMapFileName;
21740b57cec5SDimitry Andric   }
2175a7dea167SDimitry Andric   if (auto File = SourceMgr.getFileManager().getFile(FileNameRef))
21760b57cec5SDimitry Andric     Map.parseModuleMapFile(
2177a7dea167SDimitry Andric         *File, /*IsSystem=*/false,
21780b57cec5SDimitry Andric         Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
21790b57cec5SDimitry Andric             ? Directory
2180a7dea167SDimitry Andric             : (*File)->getDir(),
21810b57cec5SDimitry Andric         FileID(), nullptr, ExternLoc);
21820b57cec5SDimitry Andric }
21830b57cec5SDimitry Andric 
21840b57cec5SDimitry Andric /// Whether to add the requirement \p Feature to the module \p M.
21850b57cec5SDimitry Andric ///
21860b57cec5SDimitry Andric /// This preserves backwards compatibility for two hacks in the Darwin system
21870b57cec5SDimitry Andric /// module map files:
21880b57cec5SDimitry Andric ///
21890b57cec5SDimitry Andric /// 1. The use of 'requires excluded' to make headers non-modular, which
21900b57cec5SDimitry Andric ///    should really be mapped to 'textual' now that we have this feature.  We
21910b57cec5SDimitry Andric ///    drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
21920b57cec5SDimitry Andric ///    true.  Later, this bit will be used to map all the headers inside this
21930b57cec5SDimitry Andric ///    module to 'textual'.
21940b57cec5SDimitry Andric ///
21950b57cec5SDimitry Andric ///    This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
21960b57cec5SDimitry Andric ///
21970b57cec5SDimitry Andric /// 2. Removes a bogus cplusplus requirement from IOKit.avc.  This requirement
21980b57cec5SDimitry Andric ///    was never correct and causes issues now that we check it, so drop it.
shouldAddRequirement(Module * M,StringRef Feature,bool & IsRequiresExcludedHack)21990b57cec5SDimitry Andric static bool shouldAddRequirement(Module *M, StringRef Feature,
22000b57cec5SDimitry Andric                                  bool &IsRequiresExcludedHack) {
22010b57cec5SDimitry Andric   if (Feature == "excluded" &&
22020b57cec5SDimitry Andric       (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
22030b57cec5SDimitry Andric        M->fullModuleNameIs({"Tcl", "Private"}))) {
22040b57cec5SDimitry Andric     IsRequiresExcludedHack = true;
22050b57cec5SDimitry Andric     return false;
22060b57cec5SDimitry Andric   } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
22070b57cec5SDimitry Andric     return false;
22080b57cec5SDimitry Andric   }
22090b57cec5SDimitry Andric 
22100b57cec5SDimitry Andric   return true;
22110b57cec5SDimitry Andric }
22120b57cec5SDimitry Andric 
22130b57cec5SDimitry Andric /// Parse a requires declaration.
22140b57cec5SDimitry Andric ///
22150b57cec5SDimitry Andric ///   requires-declaration:
22160b57cec5SDimitry Andric ///     'requires' feature-list
22170b57cec5SDimitry Andric ///
22180b57cec5SDimitry Andric ///   feature-list:
22190b57cec5SDimitry Andric ///     feature ',' feature-list
22200b57cec5SDimitry Andric ///     feature
22210b57cec5SDimitry Andric ///
22220b57cec5SDimitry Andric ///   feature:
22230b57cec5SDimitry Andric ///     '!'[opt] identifier
parseRequiresDecl()22240b57cec5SDimitry Andric void ModuleMapParser::parseRequiresDecl() {
22250b57cec5SDimitry Andric   assert(Tok.is(MMToken::RequiresKeyword));
22260b57cec5SDimitry Andric 
22270b57cec5SDimitry Andric   // Parse 'requires' keyword.
22280b57cec5SDimitry Andric   consumeToken();
22290b57cec5SDimitry Andric 
22300b57cec5SDimitry Andric   // Parse the feature-list.
22310b57cec5SDimitry Andric   do {
22320b57cec5SDimitry Andric     bool RequiredState = true;
22330b57cec5SDimitry Andric     if (Tok.is(MMToken::Exclaim)) {
22340b57cec5SDimitry Andric       RequiredState = false;
22350b57cec5SDimitry Andric       consumeToken();
22360b57cec5SDimitry Andric     }
22370b57cec5SDimitry Andric 
22380b57cec5SDimitry Andric     if (!Tok.is(MMToken::Identifier)) {
22390b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
22400b57cec5SDimitry Andric       HadError = true;
22410b57cec5SDimitry Andric       return;
22420b57cec5SDimitry Andric     }
22430b57cec5SDimitry Andric 
22440b57cec5SDimitry Andric     // Consume the feature name.
22455ffd83dbSDimitry Andric     std::string Feature = std::string(Tok.getString());
22460b57cec5SDimitry Andric     consumeToken();
22470b57cec5SDimitry Andric 
22480b57cec5SDimitry Andric     bool IsRequiresExcludedHack = false;
22490b57cec5SDimitry Andric     bool ShouldAddRequirement =
22500b57cec5SDimitry Andric         shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
22510b57cec5SDimitry Andric 
22520b57cec5SDimitry Andric     if (IsRequiresExcludedHack)
22530b57cec5SDimitry Andric       UsesRequiresExcludedHack.insert(ActiveModule);
22540b57cec5SDimitry Andric 
22550b57cec5SDimitry Andric     if (ShouldAddRequirement) {
22560b57cec5SDimitry Andric       // Add this feature.
22570b57cec5SDimitry Andric       ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
22580b57cec5SDimitry Andric                                    *Map.Target);
22590b57cec5SDimitry Andric     }
22600b57cec5SDimitry Andric 
22610b57cec5SDimitry Andric     if (!Tok.is(MMToken::Comma))
22620b57cec5SDimitry Andric       break;
22630b57cec5SDimitry Andric 
22640b57cec5SDimitry Andric     // Consume the comma.
22650b57cec5SDimitry Andric     consumeToken();
22660b57cec5SDimitry Andric   } while (true);
22670b57cec5SDimitry Andric }
22680b57cec5SDimitry Andric 
22690b57cec5SDimitry Andric /// Parse a header declaration.
22700b57cec5SDimitry Andric ///
22710b57cec5SDimitry Andric ///   header-declaration:
22720b57cec5SDimitry Andric ///     'textual'[opt] 'header' string-literal
22730b57cec5SDimitry Andric ///     'private' 'textual'[opt] 'header' string-literal
22740b57cec5SDimitry Andric ///     'exclude' 'header' string-literal
22750b57cec5SDimitry Andric ///     'umbrella' 'header' string-literal
22760b57cec5SDimitry Andric ///
22770b57cec5SDimitry Andric /// FIXME: Support 'private textual header'.
parseHeaderDecl(MMToken::TokenKind LeadingToken,SourceLocation LeadingLoc)22780b57cec5SDimitry Andric void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
22790b57cec5SDimitry Andric                                       SourceLocation LeadingLoc) {
22800b57cec5SDimitry Andric   // We've already consumed the first token.
22810b57cec5SDimitry Andric   ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
22820b57cec5SDimitry Andric   if (LeadingToken == MMToken::PrivateKeyword) {
22830b57cec5SDimitry Andric     Role = ModuleMap::PrivateHeader;
22840b57cec5SDimitry Andric     // 'private' may optionally be followed by 'textual'.
22850b57cec5SDimitry Andric     if (Tok.is(MMToken::TextualKeyword)) {
22860b57cec5SDimitry Andric       LeadingToken = Tok.Kind;
22870b57cec5SDimitry Andric       consumeToken();
22880b57cec5SDimitry Andric     }
22890b57cec5SDimitry Andric   }
22900b57cec5SDimitry Andric 
22910b57cec5SDimitry Andric   if (LeadingToken == MMToken::TextualKeyword)
22920b57cec5SDimitry Andric     Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
22930b57cec5SDimitry Andric 
22940b57cec5SDimitry Andric   if (UsesRequiresExcludedHack.count(ActiveModule)) {
22950b57cec5SDimitry Andric     // Mark this header 'textual' (see doc comment for
22960b57cec5SDimitry Andric     // Module::UsesRequiresExcludedHack).
22970b57cec5SDimitry Andric     Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
22980b57cec5SDimitry Andric   }
22990b57cec5SDimitry Andric 
23000b57cec5SDimitry Andric   if (LeadingToken != MMToken::HeaderKeyword) {
23010b57cec5SDimitry Andric     if (!Tok.is(MMToken::HeaderKeyword)) {
23020b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
23030b57cec5SDimitry Andric           << (LeadingToken == MMToken::PrivateKeyword ? "private" :
23040b57cec5SDimitry Andric               LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
23050b57cec5SDimitry Andric               LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
23060b57cec5SDimitry Andric       return;
23070b57cec5SDimitry Andric     }
23080b57cec5SDimitry Andric     consumeToken();
23090b57cec5SDimitry Andric   }
23100b57cec5SDimitry Andric 
23110b57cec5SDimitry Andric   // Parse the header name.
23120b57cec5SDimitry Andric   if (!Tok.is(MMToken::StringLiteral)) {
23130b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
23140b57cec5SDimitry Andric       << "header";
23150b57cec5SDimitry Andric     HadError = true;
23160b57cec5SDimitry Andric     return;
23170b57cec5SDimitry Andric   }
23180b57cec5SDimitry Andric   Module::UnresolvedHeaderDirective Header;
23195ffd83dbSDimitry Andric   Header.FileName = std::string(Tok.getString());
23200b57cec5SDimitry Andric   Header.FileNameLoc = consumeToken();
23210b57cec5SDimitry Andric   Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
23220b57cec5SDimitry Andric   Header.Kind =
23230b57cec5SDimitry Andric       (LeadingToken == MMToken::ExcludeKeyword ? Module::HK_Excluded
23240b57cec5SDimitry Andric                                                : Map.headerRoleToKind(Role));
23250b57cec5SDimitry Andric 
23260b57cec5SDimitry Andric   // Check whether we already have an umbrella.
23270b57cec5SDimitry Andric   if (Header.IsUmbrella && ActiveModule->Umbrella) {
23280b57cec5SDimitry Andric     Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
23290b57cec5SDimitry Andric       << ActiveModule->getFullModuleName();
23300b57cec5SDimitry Andric     HadError = true;
23310b57cec5SDimitry Andric     return;
23320b57cec5SDimitry Andric   }
23330b57cec5SDimitry Andric 
23340b57cec5SDimitry Andric   // If we were given stat information, parse it so we can skip looking for
23350b57cec5SDimitry Andric   // the file.
23360b57cec5SDimitry Andric   if (Tok.is(MMToken::LBrace)) {
23370b57cec5SDimitry Andric     SourceLocation LBraceLoc = consumeToken();
23380b57cec5SDimitry Andric 
23390b57cec5SDimitry Andric     while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) {
23400b57cec5SDimitry Andric       enum Attribute { Size, ModTime, Unknown };
23410b57cec5SDimitry Andric       StringRef Str = Tok.getString();
23420b57cec5SDimitry Andric       SourceLocation Loc = consumeToken();
23430b57cec5SDimitry Andric       switch (llvm::StringSwitch<Attribute>(Str)
23440b57cec5SDimitry Andric                   .Case("size", Size)
23450b57cec5SDimitry Andric                   .Case("mtime", ModTime)
23460b57cec5SDimitry Andric                   .Default(Unknown)) {
23470b57cec5SDimitry Andric       case Size:
23480b57cec5SDimitry Andric         if (Header.Size)
23490b57cec5SDimitry Andric           Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
23500b57cec5SDimitry Andric         if (!Tok.is(MMToken::IntegerLiteral)) {
23510b57cec5SDimitry Andric           Diags.Report(Tok.getLocation(),
23520b57cec5SDimitry Andric                        diag::err_mmap_invalid_header_attribute_value) << Str;
23530b57cec5SDimitry Andric           skipUntil(MMToken::RBrace);
23540b57cec5SDimitry Andric           break;
23550b57cec5SDimitry Andric         }
23560b57cec5SDimitry Andric         Header.Size = Tok.getInteger();
23570b57cec5SDimitry Andric         consumeToken();
23580b57cec5SDimitry Andric         break;
23590b57cec5SDimitry Andric 
23600b57cec5SDimitry Andric       case ModTime:
23610b57cec5SDimitry Andric         if (Header.ModTime)
23620b57cec5SDimitry Andric           Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
23630b57cec5SDimitry Andric         if (!Tok.is(MMToken::IntegerLiteral)) {
23640b57cec5SDimitry Andric           Diags.Report(Tok.getLocation(),
23650b57cec5SDimitry Andric                        diag::err_mmap_invalid_header_attribute_value) << Str;
23660b57cec5SDimitry Andric           skipUntil(MMToken::RBrace);
23670b57cec5SDimitry Andric           break;
23680b57cec5SDimitry Andric         }
23690b57cec5SDimitry Andric         Header.ModTime = Tok.getInteger();
23700b57cec5SDimitry Andric         consumeToken();
23710b57cec5SDimitry Andric         break;
23720b57cec5SDimitry Andric 
23730b57cec5SDimitry Andric       case Unknown:
23740b57cec5SDimitry Andric         Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
23750b57cec5SDimitry Andric         skipUntil(MMToken::RBrace);
23760b57cec5SDimitry Andric         break;
23770b57cec5SDimitry Andric       }
23780b57cec5SDimitry Andric     }
23790b57cec5SDimitry Andric 
23800b57cec5SDimitry Andric     if (Tok.is(MMToken::RBrace))
23810b57cec5SDimitry Andric       consumeToken();
23820b57cec5SDimitry Andric     else {
23830b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
23840b57cec5SDimitry Andric       Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
23850b57cec5SDimitry Andric       HadError = true;
23860b57cec5SDimitry Andric     }
23870b57cec5SDimitry Andric   }
23880b57cec5SDimitry Andric 
23890b57cec5SDimitry Andric   bool NeedsFramework = false;
23900b57cec5SDimitry Andric   Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
23910b57cec5SDimitry Andric 
23920b57cec5SDimitry Andric   if (NeedsFramework && ActiveModule)
23930b57cec5SDimitry Andric     Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
23940b57cec5SDimitry Andric       << ActiveModule->getFullModuleName()
23950b57cec5SDimitry Andric       << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module");
23960b57cec5SDimitry Andric }
23970b57cec5SDimitry Andric 
compareModuleHeaders(const Module::Header * A,const Module::Header * B)23980b57cec5SDimitry Andric static int compareModuleHeaders(const Module::Header *A,
23990b57cec5SDimitry Andric                                 const Module::Header *B) {
24000b57cec5SDimitry Andric   return A->NameAsWritten.compare(B->NameAsWritten);
24010b57cec5SDimitry Andric }
24020b57cec5SDimitry Andric 
24030b57cec5SDimitry Andric /// Parse an umbrella directory declaration.
24040b57cec5SDimitry Andric ///
24050b57cec5SDimitry Andric ///   umbrella-dir-declaration:
24060b57cec5SDimitry Andric ///     umbrella string-literal
parseUmbrellaDirDecl(SourceLocation UmbrellaLoc)24070b57cec5SDimitry Andric void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
24080b57cec5SDimitry Andric   // Parse the directory name.
24090b57cec5SDimitry Andric   if (!Tok.is(MMToken::StringLiteral)) {
24100b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
24110b57cec5SDimitry Andric       << "umbrella";
24120b57cec5SDimitry Andric     HadError = true;
24130b57cec5SDimitry Andric     return;
24140b57cec5SDimitry Andric   }
24150b57cec5SDimitry Andric 
24165ffd83dbSDimitry Andric   std::string DirName = std::string(Tok.getString());
2417*5f7ddb14SDimitry Andric   std::string DirNameAsWritten = DirName;
24180b57cec5SDimitry Andric   SourceLocation DirNameLoc = consumeToken();
24190b57cec5SDimitry Andric 
24200b57cec5SDimitry Andric   // Check whether we already have an umbrella.
24210b57cec5SDimitry Andric   if (ActiveModule->Umbrella) {
24220b57cec5SDimitry Andric     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
24230b57cec5SDimitry Andric       << ActiveModule->getFullModuleName();
24240b57cec5SDimitry Andric     HadError = true;
24250b57cec5SDimitry Andric     return;
24260b57cec5SDimitry Andric   }
24270b57cec5SDimitry Andric 
24280b57cec5SDimitry Andric   // Look for this file.
2429*5f7ddb14SDimitry Andric   const DirectoryEntry *Dir = nullptr;
2430a7dea167SDimitry Andric   if (llvm::sys::path::is_absolute(DirName)) {
2431*5f7ddb14SDimitry Andric     if (auto D = SourceMgr.getFileManager().getDirectory(DirName))
2432a7dea167SDimitry Andric       Dir = *D;
2433a7dea167SDimitry Andric   } else {
24340b57cec5SDimitry Andric     SmallString<128> PathName;
24350b57cec5SDimitry Andric     PathName = Directory->getName();
24360b57cec5SDimitry Andric     llvm::sys::path::append(PathName, DirName);
2437*5f7ddb14SDimitry Andric     if (auto D = SourceMgr.getFileManager().getDirectory(PathName))
2438a7dea167SDimitry Andric       Dir = *D;
24390b57cec5SDimitry Andric   }
24400b57cec5SDimitry Andric 
24410b57cec5SDimitry Andric   if (!Dir) {
24420b57cec5SDimitry Andric     Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
24430b57cec5SDimitry Andric       << DirName;
24440b57cec5SDimitry Andric     return;
24450b57cec5SDimitry Andric   }
24460b57cec5SDimitry Andric 
24470b57cec5SDimitry Andric   if (UsesRequiresExcludedHack.count(ActiveModule)) {
24480b57cec5SDimitry Andric     // Mark this header 'textual' (see doc comment for
24490b57cec5SDimitry Andric     // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
24500b57cec5SDimitry Andric     // directory is relatively expensive, in practice this only applies to the
24510b57cec5SDimitry Andric     // uncommonly used Tcl module on Darwin platforms.
24520b57cec5SDimitry Andric     std::error_code EC;
24530b57cec5SDimitry Andric     SmallVector<Module::Header, 6> Headers;
24540b57cec5SDimitry Andric     llvm::vfs::FileSystem &FS =
24550b57cec5SDimitry Andric         SourceMgr.getFileManager().getVirtualFileSystem();
24560b57cec5SDimitry Andric     for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
24570b57cec5SDimitry Andric          I != E && !EC; I.increment(EC)) {
2458*5f7ddb14SDimitry Andric       if (auto FE = SourceMgr.getFileManager().getFile(I->path())) {
2459*5f7ddb14SDimitry Andric         Module::Header Header = {"", std::string(I->path()), *FE};
24600b57cec5SDimitry Andric         Headers.push_back(std::move(Header));
24610b57cec5SDimitry Andric       }
24620b57cec5SDimitry Andric     }
24630b57cec5SDimitry Andric 
24640b57cec5SDimitry Andric     // Sort header paths so that the pcm doesn't depend on iteration order.
24650b57cec5SDimitry Andric     llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
24660b57cec5SDimitry Andric 
24670b57cec5SDimitry Andric     for (auto &Header : Headers)
24680b57cec5SDimitry Andric       Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
24690b57cec5SDimitry Andric     return;
24700b57cec5SDimitry Andric   }
24710b57cec5SDimitry Andric 
2472*5f7ddb14SDimitry Andric   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
24730b57cec5SDimitry Andric     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
24740b57cec5SDimitry Andric       << OwningModule->getFullModuleName();
24750b57cec5SDimitry Andric     HadError = true;
24760b57cec5SDimitry Andric     return;
24770b57cec5SDimitry Andric   }
24780b57cec5SDimitry Andric 
24790b57cec5SDimitry Andric   // Record this umbrella directory.
2480*5f7ddb14SDimitry Andric   Map.setUmbrellaDir(ActiveModule, Dir, DirNameAsWritten, DirName);
24810b57cec5SDimitry Andric }
24820b57cec5SDimitry Andric 
24830b57cec5SDimitry Andric /// Parse a module export declaration.
24840b57cec5SDimitry Andric ///
24850b57cec5SDimitry Andric ///   export-declaration:
24860b57cec5SDimitry Andric ///     'export' wildcard-module-id
24870b57cec5SDimitry Andric ///
24880b57cec5SDimitry Andric ///   wildcard-module-id:
24890b57cec5SDimitry Andric ///     identifier
24900b57cec5SDimitry Andric ///     '*'
24910b57cec5SDimitry Andric ///     identifier '.' wildcard-module-id
parseExportDecl()24920b57cec5SDimitry Andric void ModuleMapParser::parseExportDecl() {
24930b57cec5SDimitry Andric   assert(Tok.is(MMToken::ExportKeyword));
24940b57cec5SDimitry Andric   SourceLocation ExportLoc = consumeToken();
24950b57cec5SDimitry Andric 
24960b57cec5SDimitry Andric   // Parse the module-id with an optional wildcard at the end.
24970b57cec5SDimitry Andric   ModuleId ParsedModuleId;
24980b57cec5SDimitry Andric   bool Wildcard = false;
24990b57cec5SDimitry Andric   do {
25000b57cec5SDimitry Andric     // FIXME: Support string-literal module names here.
25010b57cec5SDimitry Andric     if (Tok.is(MMToken::Identifier)) {
25025ffd83dbSDimitry Andric       ParsedModuleId.push_back(
25035ffd83dbSDimitry Andric           std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
25040b57cec5SDimitry Andric       consumeToken();
25050b57cec5SDimitry Andric 
25060b57cec5SDimitry Andric       if (Tok.is(MMToken::Period)) {
25070b57cec5SDimitry Andric         consumeToken();
25080b57cec5SDimitry Andric         continue;
25090b57cec5SDimitry Andric       }
25100b57cec5SDimitry Andric 
25110b57cec5SDimitry Andric       break;
25120b57cec5SDimitry Andric     }
25130b57cec5SDimitry Andric 
25140b57cec5SDimitry Andric     if(Tok.is(MMToken::Star)) {
25150b57cec5SDimitry Andric       Wildcard = true;
25160b57cec5SDimitry Andric       consumeToken();
25170b57cec5SDimitry Andric       break;
25180b57cec5SDimitry Andric     }
25190b57cec5SDimitry Andric 
25200b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
25210b57cec5SDimitry Andric     HadError = true;
25220b57cec5SDimitry Andric     return;
25230b57cec5SDimitry Andric   } while (true);
25240b57cec5SDimitry Andric 
25250b57cec5SDimitry Andric   Module::UnresolvedExportDecl Unresolved = {
25260b57cec5SDimitry Andric     ExportLoc, ParsedModuleId, Wildcard
25270b57cec5SDimitry Andric   };
25280b57cec5SDimitry Andric   ActiveModule->UnresolvedExports.push_back(Unresolved);
25290b57cec5SDimitry Andric }
25300b57cec5SDimitry Andric 
25310b57cec5SDimitry Andric /// Parse a module export_as declaration.
25320b57cec5SDimitry Andric ///
25330b57cec5SDimitry Andric ///   export-as-declaration:
25340b57cec5SDimitry Andric ///     'export_as' identifier
parseExportAsDecl()25350b57cec5SDimitry Andric void ModuleMapParser::parseExportAsDecl() {
25360b57cec5SDimitry Andric   assert(Tok.is(MMToken::ExportAsKeyword));
25370b57cec5SDimitry Andric   consumeToken();
25380b57cec5SDimitry Andric 
25390b57cec5SDimitry Andric   if (!Tok.is(MMToken::Identifier)) {
25400b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
25410b57cec5SDimitry Andric     HadError = true;
25420b57cec5SDimitry Andric     return;
25430b57cec5SDimitry Andric   }
25440b57cec5SDimitry Andric 
25450b57cec5SDimitry Andric   if (ActiveModule->Parent) {
25460b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);
25470b57cec5SDimitry Andric     consumeToken();
25480b57cec5SDimitry Andric     return;
25490b57cec5SDimitry Andric   }
25500b57cec5SDimitry Andric 
25510b57cec5SDimitry Andric   if (!ActiveModule->ExportAsModule.empty()) {
25520b57cec5SDimitry Andric     if (ActiveModule->ExportAsModule == Tok.getString()) {
25530b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as)
25540b57cec5SDimitry Andric         << ActiveModule->Name << Tok.getString();
25550b57cec5SDimitry Andric     } else {
25560b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as)
25570b57cec5SDimitry Andric         << ActiveModule->Name << ActiveModule->ExportAsModule
25580b57cec5SDimitry Andric         << Tok.getString();
25590b57cec5SDimitry Andric     }
25600b57cec5SDimitry Andric   }
25610b57cec5SDimitry Andric 
25625ffd83dbSDimitry Andric   ActiveModule->ExportAsModule = std::string(Tok.getString());
25630b57cec5SDimitry Andric   Map.addLinkAsDependency(ActiveModule);
25640b57cec5SDimitry Andric 
25650b57cec5SDimitry Andric   consumeToken();
25660b57cec5SDimitry Andric }
25670b57cec5SDimitry Andric 
25680b57cec5SDimitry Andric /// Parse a module use declaration.
25690b57cec5SDimitry Andric ///
25700b57cec5SDimitry Andric ///   use-declaration:
25710b57cec5SDimitry Andric ///     'use' wildcard-module-id
parseUseDecl()25720b57cec5SDimitry Andric void ModuleMapParser::parseUseDecl() {
25730b57cec5SDimitry Andric   assert(Tok.is(MMToken::UseKeyword));
25740b57cec5SDimitry Andric   auto KWLoc = consumeToken();
25750b57cec5SDimitry Andric   // Parse the module-id.
25760b57cec5SDimitry Andric   ModuleId ParsedModuleId;
25770b57cec5SDimitry Andric   parseModuleId(ParsedModuleId);
25780b57cec5SDimitry Andric 
25790b57cec5SDimitry Andric   if (ActiveModule->Parent)
25800b57cec5SDimitry Andric     Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
25810b57cec5SDimitry Andric   else
25820b57cec5SDimitry Andric     ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
25830b57cec5SDimitry Andric }
25840b57cec5SDimitry Andric 
25850b57cec5SDimitry Andric /// Parse a link declaration.
25860b57cec5SDimitry Andric ///
25870b57cec5SDimitry Andric ///   module-declaration:
25880b57cec5SDimitry Andric ///     'link' 'framework'[opt] string-literal
parseLinkDecl()25890b57cec5SDimitry Andric void ModuleMapParser::parseLinkDecl() {
25900b57cec5SDimitry Andric   assert(Tok.is(MMToken::LinkKeyword));
25910b57cec5SDimitry Andric   SourceLocation LinkLoc = consumeToken();
25920b57cec5SDimitry Andric 
25930b57cec5SDimitry Andric   // Parse the optional 'framework' keyword.
25940b57cec5SDimitry Andric   bool IsFramework = false;
25950b57cec5SDimitry Andric   if (Tok.is(MMToken::FrameworkKeyword)) {
25960b57cec5SDimitry Andric     consumeToken();
25970b57cec5SDimitry Andric     IsFramework = true;
25980b57cec5SDimitry Andric   }
25990b57cec5SDimitry Andric 
26000b57cec5SDimitry Andric   // Parse the library name
26010b57cec5SDimitry Andric   if (!Tok.is(MMToken::StringLiteral)) {
26020b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
26030b57cec5SDimitry Andric       << IsFramework << SourceRange(LinkLoc);
26040b57cec5SDimitry Andric     HadError = true;
26050b57cec5SDimitry Andric     return;
26060b57cec5SDimitry Andric   }
26070b57cec5SDimitry Andric 
26085ffd83dbSDimitry Andric   std::string LibraryName = std::string(Tok.getString());
26090b57cec5SDimitry Andric   consumeToken();
26100b57cec5SDimitry Andric   ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
26110b57cec5SDimitry Andric                                                             IsFramework));
26120b57cec5SDimitry Andric }
26130b57cec5SDimitry Andric 
26140b57cec5SDimitry Andric /// Parse a configuration macro declaration.
26150b57cec5SDimitry Andric ///
26160b57cec5SDimitry Andric ///   module-declaration:
26170b57cec5SDimitry Andric ///     'config_macros' attributes[opt] config-macro-list?
26180b57cec5SDimitry Andric ///
26190b57cec5SDimitry Andric ///   config-macro-list:
26200b57cec5SDimitry Andric ///     identifier (',' identifier)?
parseConfigMacros()26210b57cec5SDimitry Andric void ModuleMapParser::parseConfigMacros() {
26220b57cec5SDimitry Andric   assert(Tok.is(MMToken::ConfigMacros));
26230b57cec5SDimitry Andric   SourceLocation ConfigMacrosLoc = consumeToken();
26240b57cec5SDimitry Andric 
26250b57cec5SDimitry Andric   // Only top-level modules can have configuration macros.
26260b57cec5SDimitry Andric   if (ActiveModule->Parent) {
26270b57cec5SDimitry Andric     Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
26280b57cec5SDimitry Andric   }
26290b57cec5SDimitry Andric 
26300b57cec5SDimitry Andric   // Parse the optional attributes.
26310b57cec5SDimitry Andric   Attributes Attrs;
26320b57cec5SDimitry Andric   if (parseOptionalAttributes(Attrs))
26330b57cec5SDimitry Andric     return;
26340b57cec5SDimitry Andric 
26350b57cec5SDimitry Andric   if (Attrs.IsExhaustive && !ActiveModule->Parent) {
26360b57cec5SDimitry Andric     ActiveModule->ConfigMacrosExhaustive = true;
26370b57cec5SDimitry Andric   }
26380b57cec5SDimitry Andric 
26390b57cec5SDimitry Andric   // If we don't have an identifier, we're done.
26400b57cec5SDimitry Andric   // FIXME: Support macros with the same name as a keyword here.
26410b57cec5SDimitry Andric   if (!Tok.is(MMToken::Identifier))
26420b57cec5SDimitry Andric     return;
26430b57cec5SDimitry Andric 
26440b57cec5SDimitry Andric   // Consume the first identifier.
26450b57cec5SDimitry Andric   if (!ActiveModule->Parent) {
26460b57cec5SDimitry Andric     ActiveModule->ConfigMacros.push_back(Tok.getString().str());
26470b57cec5SDimitry Andric   }
26480b57cec5SDimitry Andric   consumeToken();
26490b57cec5SDimitry Andric 
26500b57cec5SDimitry Andric   do {
26510b57cec5SDimitry Andric     // If there's a comma, consume it.
26520b57cec5SDimitry Andric     if (!Tok.is(MMToken::Comma))
26530b57cec5SDimitry Andric       break;
26540b57cec5SDimitry Andric     consumeToken();
26550b57cec5SDimitry Andric 
26560b57cec5SDimitry Andric     // We expect to see a macro name here.
26570b57cec5SDimitry Andric     // FIXME: Support macros with the same name as a keyword here.
26580b57cec5SDimitry Andric     if (!Tok.is(MMToken::Identifier)) {
26590b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
26600b57cec5SDimitry Andric       break;
26610b57cec5SDimitry Andric     }
26620b57cec5SDimitry Andric 
26630b57cec5SDimitry Andric     // Consume the macro name.
26640b57cec5SDimitry Andric     if (!ActiveModule->Parent) {
26650b57cec5SDimitry Andric       ActiveModule->ConfigMacros.push_back(Tok.getString().str());
26660b57cec5SDimitry Andric     }
26670b57cec5SDimitry Andric     consumeToken();
26680b57cec5SDimitry Andric   } while (true);
26690b57cec5SDimitry Andric }
26700b57cec5SDimitry Andric 
26710b57cec5SDimitry Andric /// Format a module-id into a string.
formatModuleId(const ModuleId & Id)26720b57cec5SDimitry Andric static std::string formatModuleId(const ModuleId &Id) {
26730b57cec5SDimitry Andric   std::string result;
26740b57cec5SDimitry Andric   {
26750b57cec5SDimitry Andric     llvm::raw_string_ostream OS(result);
26760b57cec5SDimitry Andric 
26770b57cec5SDimitry Andric     for (unsigned I = 0, N = Id.size(); I != N; ++I) {
26780b57cec5SDimitry Andric       if (I)
26790b57cec5SDimitry Andric         OS << ".";
26800b57cec5SDimitry Andric       OS << Id[I].first;
26810b57cec5SDimitry Andric     }
26820b57cec5SDimitry Andric   }
26830b57cec5SDimitry Andric 
26840b57cec5SDimitry Andric   return result;
26850b57cec5SDimitry Andric }
26860b57cec5SDimitry Andric 
26870b57cec5SDimitry Andric /// Parse a conflict declaration.
26880b57cec5SDimitry Andric ///
26890b57cec5SDimitry Andric ///   module-declaration:
26900b57cec5SDimitry Andric ///     'conflict' module-id ',' string-literal
parseConflict()26910b57cec5SDimitry Andric void ModuleMapParser::parseConflict() {
26920b57cec5SDimitry Andric   assert(Tok.is(MMToken::Conflict));
26930b57cec5SDimitry Andric   SourceLocation ConflictLoc = consumeToken();
26940b57cec5SDimitry Andric   Module::UnresolvedConflict Conflict;
26950b57cec5SDimitry Andric 
26960b57cec5SDimitry Andric   // Parse the module-id.
26970b57cec5SDimitry Andric   if (parseModuleId(Conflict.Id))
26980b57cec5SDimitry Andric     return;
26990b57cec5SDimitry Andric 
27000b57cec5SDimitry Andric   // Parse the ','.
27010b57cec5SDimitry Andric   if (!Tok.is(MMToken::Comma)) {
27020b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
27030b57cec5SDimitry Andric       << SourceRange(ConflictLoc);
27040b57cec5SDimitry Andric     return;
27050b57cec5SDimitry Andric   }
27060b57cec5SDimitry Andric   consumeToken();
27070b57cec5SDimitry Andric 
27080b57cec5SDimitry Andric   // Parse the message.
27090b57cec5SDimitry Andric   if (!Tok.is(MMToken::StringLiteral)) {
27100b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
27110b57cec5SDimitry Andric       << formatModuleId(Conflict.Id);
27120b57cec5SDimitry Andric     return;
27130b57cec5SDimitry Andric   }
27140b57cec5SDimitry Andric   Conflict.Message = Tok.getString().str();
27150b57cec5SDimitry Andric   consumeToken();
27160b57cec5SDimitry Andric 
27170b57cec5SDimitry Andric   // Add this unresolved conflict.
27180b57cec5SDimitry Andric   ActiveModule->UnresolvedConflicts.push_back(Conflict);
27190b57cec5SDimitry Andric }
27200b57cec5SDimitry Andric 
27210b57cec5SDimitry Andric /// Parse an inferred module declaration (wildcard modules).
27220b57cec5SDimitry Andric ///
27230b57cec5SDimitry Andric ///   module-declaration:
27240b57cec5SDimitry Andric ///     'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
27250b57cec5SDimitry Andric ///       { inferred-module-member* }
27260b57cec5SDimitry Andric ///
27270b57cec5SDimitry Andric ///   inferred-module-member:
27280b57cec5SDimitry Andric ///     'export' '*'
27290b57cec5SDimitry Andric ///     'exclude' identifier
parseInferredModuleDecl(bool Framework,bool Explicit)27300b57cec5SDimitry Andric void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
27310b57cec5SDimitry Andric   assert(Tok.is(MMToken::Star));
27320b57cec5SDimitry Andric   SourceLocation StarLoc = consumeToken();
27330b57cec5SDimitry Andric   bool Failed = false;
27340b57cec5SDimitry Andric 
27350b57cec5SDimitry Andric   // Inferred modules must be submodules.
27360b57cec5SDimitry Andric   if (!ActiveModule && !Framework) {
27370b57cec5SDimitry Andric     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
27380b57cec5SDimitry Andric     Failed = true;
27390b57cec5SDimitry Andric   }
27400b57cec5SDimitry Andric 
27410b57cec5SDimitry Andric   if (ActiveModule) {
27420b57cec5SDimitry Andric     // Inferred modules must have umbrella directories.
27430b57cec5SDimitry Andric     if (!Failed && ActiveModule->IsAvailable &&
27440b57cec5SDimitry Andric         !ActiveModule->getUmbrellaDir()) {
27450b57cec5SDimitry Andric       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
27460b57cec5SDimitry Andric       Failed = true;
27470b57cec5SDimitry Andric     }
27480b57cec5SDimitry Andric 
27490b57cec5SDimitry Andric     // Check for redefinition of an inferred module.
27500b57cec5SDimitry Andric     if (!Failed && ActiveModule->InferSubmodules) {
27510b57cec5SDimitry Andric       Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
27520b57cec5SDimitry Andric       if (ActiveModule->InferredSubmoduleLoc.isValid())
27530b57cec5SDimitry Andric         Diags.Report(ActiveModule->InferredSubmoduleLoc,
27540b57cec5SDimitry Andric                      diag::note_mmap_prev_definition);
27550b57cec5SDimitry Andric       Failed = true;
27560b57cec5SDimitry Andric     }
27570b57cec5SDimitry Andric 
27580b57cec5SDimitry Andric     // Check for the 'framework' keyword, which is not permitted here.
27590b57cec5SDimitry Andric     if (Framework) {
27600b57cec5SDimitry Andric       Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
27610b57cec5SDimitry Andric       Framework = false;
27620b57cec5SDimitry Andric     }
27630b57cec5SDimitry Andric   } else if (Explicit) {
27640b57cec5SDimitry Andric     Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
27650b57cec5SDimitry Andric     Explicit = false;
27660b57cec5SDimitry Andric   }
27670b57cec5SDimitry Andric 
27680b57cec5SDimitry Andric   // If there were any problems with this inferred submodule, skip its body.
27690b57cec5SDimitry Andric   if (Failed) {
27700b57cec5SDimitry Andric     if (Tok.is(MMToken::LBrace)) {
27710b57cec5SDimitry Andric       consumeToken();
27720b57cec5SDimitry Andric       skipUntil(MMToken::RBrace);
27730b57cec5SDimitry Andric       if (Tok.is(MMToken::RBrace))
27740b57cec5SDimitry Andric         consumeToken();
27750b57cec5SDimitry Andric     }
27760b57cec5SDimitry Andric     HadError = true;
27770b57cec5SDimitry Andric     return;
27780b57cec5SDimitry Andric   }
27790b57cec5SDimitry Andric 
27800b57cec5SDimitry Andric   // Parse optional attributes.
27810b57cec5SDimitry Andric   Attributes Attrs;
27820b57cec5SDimitry Andric   if (parseOptionalAttributes(Attrs))
27830b57cec5SDimitry Andric     return;
27840b57cec5SDimitry Andric 
27850b57cec5SDimitry Andric   if (ActiveModule) {
27860b57cec5SDimitry Andric     // Note that we have an inferred submodule.
27870b57cec5SDimitry Andric     ActiveModule->InferSubmodules = true;
27880b57cec5SDimitry Andric     ActiveModule->InferredSubmoduleLoc = StarLoc;
27890b57cec5SDimitry Andric     ActiveModule->InferExplicitSubmodules = Explicit;
27900b57cec5SDimitry Andric   } else {
27910b57cec5SDimitry Andric     // We'll be inferring framework modules for this directory.
27920b57cec5SDimitry Andric     Map.InferredDirectories[Directory].InferModules = true;
27930b57cec5SDimitry Andric     Map.InferredDirectories[Directory].Attrs = Attrs;
27940b57cec5SDimitry Andric     Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
27950b57cec5SDimitry Andric     // FIXME: Handle the 'framework' keyword.
27960b57cec5SDimitry Andric   }
27970b57cec5SDimitry Andric 
27980b57cec5SDimitry Andric   // Parse the opening brace.
27990b57cec5SDimitry Andric   if (!Tok.is(MMToken::LBrace)) {
28000b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
28010b57cec5SDimitry Andric     HadError = true;
28020b57cec5SDimitry Andric     return;
28030b57cec5SDimitry Andric   }
28040b57cec5SDimitry Andric   SourceLocation LBraceLoc = consumeToken();
28050b57cec5SDimitry Andric 
28060b57cec5SDimitry Andric   // Parse the body of the inferred submodule.
28070b57cec5SDimitry Andric   bool Done = false;
28080b57cec5SDimitry Andric   do {
28090b57cec5SDimitry Andric     switch (Tok.Kind) {
28100b57cec5SDimitry Andric     case MMToken::EndOfFile:
28110b57cec5SDimitry Andric     case MMToken::RBrace:
28120b57cec5SDimitry Andric       Done = true;
28130b57cec5SDimitry Andric       break;
28140b57cec5SDimitry Andric 
28150b57cec5SDimitry Andric     case MMToken::ExcludeKeyword:
28160b57cec5SDimitry Andric       if (ActiveModule) {
28170b57cec5SDimitry Andric         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
28180b57cec5SDimitry Andric           << (ActiveModule != nullptr);
28190b57cec5SDimitry Andric         consumeToken();
28200b57cec5SDimitry Andric         break;
28210b57cec5SDimitry Andric       }
28220b57cec5SDimitry Andric 
28230b57cec5SDimitry Andric       consumeToken();
28240b57cec5SDimitry Andric       // FIXME: Support string-literal module names here.
28250b57cec5SDimitry Andric       if (!Tok.is(MMToken::Identifier)) {
28260b57cec5SDimitry Andric         Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
28270b57cec5SDimitry Andric         break;
28280b57cec5SDimitry Andric       }
28290b57cec5SDimitry Andric 
28305ffd83dbSDimitry Andric       Map.InferredDirectories[Directory].ExcludedModules.push_back(
28315ffd83dbSDimitry Andric           std::string(Tok.getString()));
28320b57cec5SDimitry Andric       consumeToken();
28330b57cec5SDimitry Andric       break;
28340b57cec5SDimitry Andric 
28350b57cec5SDimitry Andric     case MMToken::ExportKeyword:
28360b57cec5SDimitry Andric       if (!ActiveModule) {
28370b57cec5SDimitry Andric         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
28380b57cec5SDimitry Andric           << (ActiveModule != nullptr);
28390b57cec5SDimitry Andric         consumeToken();
28400b57cec5SDimitry Andric         break;
28410b57cec5SDimitry Andric       }
28420b57cec5SDimitry Andric 
28430b57cec5SDimitry Andric       consumeToken();
28440b57cec5SDimitry Andric       if (Tok.is(MMToken::Star))
28450b57cec5SDimitry Andric         ActiveModule->InferExportWildcard = true;
28460b57cec5SDimitry Andric       else
28470b57cec5SDimitry Andric         Diags.Report(Tok.getLocation(),
28480b57cec5SDimitry Andric                      diag::err_mmap_expected_export_wildcard);
28490b57cec5SDimitry Andric       consumeToken();
28500b57cec5SDimitry Andric       break;
28510b57cec5SDimitry Andric 
28520b57cec5SDimitry Andric     case MMToken::ExplicitKeyword:
28530b57cec5SDimitry Andric     case MMToken::ModuleKeyword:
28540b57cec5SDimitry Andric     case MMToken::HeaderKeyword:
28550b57cec5SDimitry Andric     case MMToken::PrivateKeyword:
28560b57cec5SDimitry Andric     case MMToken::UmbrellaKeyword:
28570b57cec5SDimitry Andric     default:
28580b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
28590b57cec5SDimitry Andric           << (ActiveModule != nullptr);
28600b57cec5SDimitry Andric       consumeToken();
28610b57cec5SDimitry Andric       break;
28620b57cec5SDimitry Andric     }
28630b57cec5SDimitry Andric   } while (!Done);
28640b57cec5SDimitry Andric 
28650b57cec5SDimitry Andric   if (Tok.is(MMToken::RBrace))
28660b57cec5SDimitry Andric     consumeToken();
28670b57cec5SDimitry Andric   else {
28680b57cec5SDimitry Andric     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
28690b57cec5SDimitry Andric     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
28700b57cec5SDimitry Andric     HadError = true;
28710b57cec5SDimitry Andric   }
28720b57cec5SDimitry Andric }
28730b57cec5SDimitry Andric 
28740b57cec5SDimitry Andric /// Parse optional attributes.
28750b57cec5SDimitry Andric ///
28760b57cec5SDimitry Andric ///   attributes:
28770b57cec5SDimitry Andric ///     attribute attributes
28780b57cec5SDimitry Andric ///     attribute
28790b57cec5SDimitry Andric ///
28800b57cec5SDimitry Andric ///   attribute:
28810b57cec5SDimitry Andric ///     [ identifier ]
28820b57cec5SDimitry Andric ///
28830b57cec5SDimitry Andric /// \param Attrs Will be filled in with the parsed attributes.
28840b57cec5SDimitry Andric ///
28850b57cec5SDimitry Andric /// \returns true if an error occurred, false otherwise.
parseOptionalAttributes(Attributes & Attrs)28860b57cec5SDimitry Andric bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
28870b57cec5SDimitry Andric   bool HadError = false;
28880b57cec5SDimitry Andric 
28890b57cec5SDimitry Andric   while (Tok.is(MMToken::LSquare)) {
28900b57cec5SDimitry Andric     // Consume the '['.
28910b57cec5SDimitry Andric     SourceLocation LSquareLoc = consumeToken();
28920b57cec5SDimitry Andric 
28930b57cec5SDimitry Andric     // Check whether we have an attribute name here.
28940b57cec5SDimitry Andric     if (!Tok.is(MMToken::Identifier)) {
28950b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
28960b57cec5SDimitry Andric       skipUntil(MMToken::RSquare);
28970b57cec5SDimitry Andric       if (Tok.is(MMToken::RSquare))
28980b57cec5SDimitry Andric         consumeToken();
28990b57cec5SDimitry Andric       HadError = true;
29000b57cec5SDimitry Andric     }
29010b57cec5SDimitry Andric 
29020b57cec5SDimitry Andric     // Decode the attribute name.
29030b57cec5SDimitry Andric     AttributeKind Attribute
29040b57cec5SDimitry Andric       = llvm::StringSwitch<AttributeKind>(Tok.getString())
29050b57cec5SDimitry Andric           .Case("exhaustive", AT_exhaustive)
29060b57cec5SDimitry Andric           .Case("extern_c", AT_extern_c)
29070b57cec5SDimitry Andric           .Case("no_undeclared_includes", AT_no_undeclared_includes)
29080b57cec5SDimitry Andric           .Case("system", AT_system)
29090b57cec5SDimitry Andric           .Default(AT_unknown);
29100b57cec5SDimitry Andric     switch (Attribute) {
29110b57cec5SDimitry Andric     case AT_unknown:
29120b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
29130b57cec5SDimitry Andric         << Tok.getString();
29140b57cec5SDimitry Andric       break;
29150b57cec5SDimitry Andric 
29160b57cec5SDimitry Andric     case AT_system:
29170b57cec5SDimitry Andric       Attrs.IsSystem = true;
29180b57cec5SDimitry Andric       break;
29190b57cec5SDimitry Andric 
29200b57cec5SDimitry Andric     case AT_extern_c:
29210b57cec5SDimitry Andric       Attrs.IsExternC = true;
29220b57cec5SDimitry Andric       break;
29230b57cec5SDimitry Andric 
29240b57cec5SDimitry Andric     case AT_exhaustive:
29250b57cec5SDimitry Andric       Attrs.IsExhaustive = true;
29260b57cec5SDimitry Andric       break;
29270b57cec5SDimitry Andric 
29280b57cec5SDimitry Andric     case AT_no_undeclared_includes:
29290b57cec5SDimitry Andric       Attrs.NoUndeclaredIncludes = true;
29300b57cec5SDimitry Andric       break;
29310b57cec5SDimitry Andric     }
29320b57cec5SDimitry Andric     consumeToken();
29330b57cec5SDimitry Andric 
29340b57cec5SDimitry Andric     // Consume the ']'.
29350b57cec5SDimitry Andric     if (!Tok.is(MMToken::RSquare)) {
29360b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
29370b57cec5SDimitry Andric       Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
29380b57cec5SDimitry Andric       skipUntil(MMToken::RSquare);
29390b57cec5SDimitry Andric       HadError = true;
29400b57cec5SDimitry Andric     }
29410b57cec5SDimitry Andric 
29420b57cec5SDimitry Andric     if (Tok.is(MMToken::RSquare))
29430b57cec5SDimitry Andric       consumeToken();
29440b57cec5SDimitry Andric   }
29450b57cec5SDimitry Andric 
29460b57cec5SDimitry Andric   return HadError;
29470b57cec5SDimitry Andric }
29480b57cec5SDimitry Andric 
29490b57cec5SDimitry Andric /// Parse a module map file.
29500b57cec5SDimitry Andric ///
29510b57cec5SDimitry Andric ///   module-map-file:
29520b57cec5SDimitry Andric ///     module-declaration*
parseModuleMapFile()29530b57cec5SDimitry Andric bool ModuleMapParser::parseModuleMapFile() {
29540b57cec5SDimitry Andric   do {
29550b57cec5SDimitry Andric     switch (Tok.Kind) {
29560b57cec5SDimitry Andric     case MMToken::EndOfFile:
29570b57cec5SDimitry Andric       return HadError;
29580b57cec5SDimitry Andric 
29590b57cec5SDimitry Andric     case MMToken::ExplicitKeyword:
29600b57cec5SDimitry Andric     case MMToken::ExternKeyword:
29610b57cec5SDimitry Andric     case MMToken::ModuleKeyword:
29620b57cec5SDimitry Andric     case MMToken::FrameworkKeyword:
29630b57cec5SDimitry Andric       parseModuleDecl();
29640b57cec5SDimitry Andric       break;
29650b57cec5SDimitry Andric 
29660b57cec5SDimitry Andric     case MMToken::Comma:
29670b57cec5SDimitry Andric     case MMToken::ConfigMacros:
29680b57cec5SDimitry Andric     case MMToken::Conflict:
29690b57cec5SDimitry Andric     case MMToken::Exclaim:
29700b57cec5SDimitry Andric     case MMToken::ExcludeKeyword:
29710b57cec5SDimitry Andric     case MMToken::ExportKeyword:
29720b57cec5SDimitry Andric     case MMToken::ExportAsKeyword:
29730b57cec5SDimitry Andric     case MMToken::HeaderKeyword:
29740b57cec5SDimitry Andric     case MMToken::Identifier:
29750b57cec5SDimitry Andric     case MMToken::LBrace:
29760b57cec5SDimitry Andric     case MMToken::LinkKeyword:
29770b57cec5SDimitry Andric     case MMToken::LSquare:
29780b57cec5SDimitry Andric     case MMToken::Period:
29790b57cec5SDimitry Andric     case MMToken::PrivateKeyword:
29800b57cec5SDimitry Andric     case MMToken::RBrace:
29810b57cec5SDimitry Andric     case MMToken::RSquare:
29820b57cec5SDimitry Andric     case MMToken::RequiresKeyword:
29830b57cec5SDimitry Andric     case MMToken::Star:
29840b57cec5SDimitry Andric     case MMToken::StringLiteral:
29850b57cec5SDimitry Andric     case MMToken::IntegerLiteral:
29860b57cec5SDimitry Andric     case MMToken::TextualKeyword:
29870b57cec5SDimitry Andric     case MMToken::UmbrellaKeyword:
29880b57cec5SDimitry Andric     case MMToken::UseKeyword:
29890b57cec5SDimitry Andric       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
29900b57cec5SDimitry Andric       HadError = true;
29910b57cec5SDimitry Andric       consumeToken();
29920b57cec5SDimitry Andric       break;
29930b57cec5SDimitry Andric     }
29940b57cec5SDimitry Andric   } while (true);
29950b57cec5SDimitry Andric }
29960b57cec5SDimitry Andric 
parseModuleMapFile(const FileEntry * File,bool IsSystem,const DirectoryEntry * Dir,FileID ID,unsigned * Offset,SourceLocation ExternModuleLoc)29970b57cec5SDimitry Andric bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
29980b57cec5SDimitry Andric                                    const DirectoryEntry *Dir, FileID ID,
29990b57cec5SDimitry Andric                                    unsigned *Offset,
30000b57cec5SDimitry Andric                                    SourceLocation ExternModuleLoc) {
30010b57cec5SDimitry Andric   assert(Target && "Missing target information");
30020b57cec5SDimitry Andric   llvm::DenseMap<const FileEntry *, bool>::iterator Known
30030b57cec5SDimitry Andric     = ParsedModuleMap.find(File);
30040b57cec5SDimitry Andric   if (Known != ParsedModuleMap.end())
30050b57cec5SDimitry Andric     return Known->second;
30060b57cec5SDimitry Andric 
30070b57cec5SDimitry Andric   // If the module map file wasn't already entered, do so now.
30080b57cec5SDimitry Andric   if (ID.isInvalid()) {
30090b57cec5SDimitry Andric     auto FileCharacter =
30100b57cec5SDimitry Andric         IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
30110b57cec5SDimitry Andric     ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
30120b57cec5SDimitry Andric   }
30130b57cec5SDimitry Andric 
30140b57cec5SDimitry Andric   assert(Target && "Missing target information");
3015af732203SDimitry Andric   llvm::Optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
30160b57cec5SDimitry Andric   if (!Buffer)
30170b57cec5SDimitry Andric     return ParsedModuleMap[File] = true;
30180b57cec5SDimitry Andric   assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
30190b57cec5SDimitry Andric          "invalid buffer offset");
30200b57cec5SDimitry Andric 
30210b57cec5SDimitry Andric   // Parse this module map file.
30220b57cec5SDimitry Andric   Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
30230b57cec5SDimitry Andric           Buffer->getBufferStart(),
30240b57cec5SDimitry Andric           Buffer->getBufferStart() + (Offset ? *Offset : 0),
30250b57cec5SDimitry Andric           Buffer->getBufferEnd());
30260b57cec5SDimitry Andric   SourceLocation Start = L.getSourceLocation();
30270b57cec5SDimitry Andric   ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
30280b57cec5SDimitry Andric                          IsSystem);
30290b57cec5SDimitry Andric   bool Result = Parser.parseModuleMapFile();
30300b57cec5SDimitry Andric   ParsedModuleMap[File] = Result;
30310b57cec5SDimitry Andric 
30320b57cec5SDimitry Andric   if (Offset) {
30330b57cec5SDimitry Andric     auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation());
30340b57cec5SDimitry Andric     assert(Loc.first == ID && "stopped in a different file?");
30350b57cec5SDimitry Andric     *Offset = Loc.second;
30360b57cec5SDimitry Andric   }
30370b57cec5SDimitry Andric 
30380b57cec5SDimitry Andric   // Notify callbacks that we parsed it.
30390b57cec5SDimitry Andric   for (const auto &Cb : Callbacks)
30400b57cec5SDimitry Andric     Cb->moduleMapFileRead(Start, *File, IsSystem);
30410b57cec5SDimitry Andric 
30420b57cec5SDimitry Andric   return Result;
30430b57cec5SDimitry Andric }
3044