10b57cec5SDimitry Andric //===- Module.cpp - Describe a module -------------------------------------===//
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 Module class, which describes a module in the source
100b57cec5SDimitry Andric // code.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "clang/Basic/Module.h"
150b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h"
160b57cec5SDimitry Andric #include "clang/Basic/FileManager.h"
170b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
180b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
190b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
200b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
210b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
220b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h"
230b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
240b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
250b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
260b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
270b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
280b57cec5SDimitry Andric #include <algorithm>
290b57cec5SDimitry Andric #include <cassert>
300b57cec5SDimitry Andric #include <functional>
310b57cec5SDimitry Andric #include <string>
320b57cec5SDimitry Andric #include <utility>
330b57cec5SDimitry Andric #include <vector>
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric using namespace clang;
360b57cec5SDimitry Andric 
Module(StringRef Name,SourceLocation DefinitionLoc,Module * Parent,bool IsFramework,bool IsExplicit,unsigned VisibilityID)370b57cec5SDimitry Andric Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
380b57cec5SDimitry Andric                bool IsFramework, bool IsExplicit, unsigned VisibilityID)
390b57cec5SDimitry Andric     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
405ffd83dbSDimitry Andric       VisibilityID(VisibilityID), IsUnimportable(false),
410b57cec5SDimitry Andric       HasIncompatibleModuleFile(false), IsAvailable(true),
420b57cec5SDimitry Andric       IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
430b57cec5SDimitry Andric       IsSystem(false), IsExternC(false), IsInferred(false),
440b57cec5SDimitry Andric       InferSubmodules(false), InferExplicitSubmodules(false),
450b57cec5SDimitry Andric       InferExportWildcard(false), ConfigMacrosExhaustive(false),
460b57cec5SDimitry Andric       NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
475f757f3fSDimitry Andric       NamedModuleHasInit(true), NameVisibility(Hidden) {
480b57cec5SDimitry Andric   if (Parent) {
495ffd83dbSDimitry Andric     IsAvailable = Parent->isAvailable();
505ffd83dbSDimitry Andric     IsUnimportable = Parent->isUnimportable();
515ffd83dbSDimitry Andric     IsSystem = Parent->IsSystem;
525ffd83dbSDimitry Andric     IsExternC = Parent->IsExternC;
535ffd83dbSDimitry Andric     NoUndeclaredIncludes = Parent->NoUndeclaredIncludes;
545ffd83dbSDimitry Andric     ModuleMapIsPrivate = Parent->ModuleMapIsPrivate;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
570b57cec5SDimitry Andric     Parent->SubModules.push_back(this);
580b57cec5SDimitry Andric   }
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric 
~Module()610b57cec5SDimitry Andric Module::~Module() {
6206c3fb27SDimitry Andric   for (auto *Submodule : SubModules) {
6306c3fb27SDimitry Andric     delete Submodule;
640b57cec5SDimitry Andric   }
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
isPlatformEnvironment(const TargetInfo & Target,StringRef Feature)670b57cec5SDimitry Andric static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
680b57cec5SDimitry Andric   StringRef Platform = Target.getPlatformName();
690b57cec5SDimitry Andric   StringRef Env = Target.getTriple().getEnvironmentName();
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   // Attempt to match platform and environment.
720b57cec5SDimitry Andric   if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
730b57cec5SDimitry Andric       Env == Feature)
740b57cec5SDimitry Andric     return true;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
77e8d8bef9SDimitry Andric     auto Pos = LHS.find('-');
780b57cec5SDimitry Andric     if (Pos == StringRef::npos)
790b57cec5SDimitry Andric       return false;
800b57cec5SDimitry Andric     SmallString<128> NewLHS = LHS.slice(0, Pos);
810b57cec5SDimitry Andric     NewLHS += LHS.slice(Pos+1, LHS.size());
820b57cec5SDimitry Andric     return NewLHS == RHS;
830b57cec5SDimitry Andric   };
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
860b57cec5SDimitry Andric   // Darwin has different but equivalent variants for simulators, example:
870b57cec5SDimitry Andric   //   1. x86_64-apple-ios-simulator
880b57cec5SDimitry Andric   //   2. x86_64-apple-iossimulator
890b57cec5SDimitry Andric   // where both are valid examples of the same platform+environment but in the
900b57cec5SDimitry Andric   // variant (2) the simulator is hardcoded as part of the platform name. Both
910b57cec5SDimitry Andric   // forms above should match for "iossimulator" requirement.
925f757f3fSDimitry Andric   if (Target.getTriple().isOSDarwin() && PlatformEnv.ends_with("simulator"))
930b57cec5SDimitry Andric     return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric   return PlatformEnv == Feature;
960b57cec5SDimitry Andric }
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric /// Determine whether a translation unit built using the current
990b57cec5SDimitry Andric /// language options has the given feature.
hasFeature(StringRef Feature,const LangOptions & LangOpts,const TargetInfo & Target)1000b57cec5SDimitry Andric static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
1010b57cec5SDimitry Andric                        const TargetInfo &Target) {
1020b57cec5SDimitry Andric   bool HasFeature = llvm::StringSwitch<bool>(Feature)
1030b57cec5SDimitry Andric                         .Case("altivec", LangOpts.AltiVec)
1040b57cec5SDimitry Andric                         .Case("blocks", LangOpts.Blocks)
1050b57cec5SDimitry Andric                         .Case("coroutines", LangOpts.Coroutines)
1060b57cec5SDimitry Andric                         .Case("cplusplus", LangOpts.CPlusPlus)
1070b57cec5SDimitry Andric                         .Case("cplusplus11", LangOpts.CPlusPlus11)
1080b57cec5SDimitry Andric                         .Case("cplusplus14", LangOpts.CPlusPlus14)
1090b57cec5SDimitry Andric                         .Case("cplusplus17", LangOpts.CPlusPlus17)
11006c3fb27SDimitry Andric                         .Case("cplusplus20", LangOpts.CPlusPlus20)
11106c3fb27SDimitry Andric                         .Case("cplusplus23", LangOpts.CPlusPlus23)
11206c3fb27SDimitry Andric                         .Case("cplusplus26", LangOpts.CPlusPlus26)
1130b57cec5SDimitry Andric                         .Case("c99", LangOpts.C99)
1140b57cec5SDimitry Andric                         .Case("c11", LangOpts.C11)
1150b57cec5SDimitry Andric                         .Case("c17", LangOpts.C17)
1165f757f3fSDimitry Andric                         .Case("c23", LangOpts.C23)
1170b57cec5SDimitry Andric                         .Case("freestanding", LangOpts.Freestanding)
1180b57cec5SDimitry Andric                         .Case("gnuinlineasm", LangOpts.GNUAsm)
1190b57cec5SDimitry Andric                         .Case("objc", LangOpts.ObjC)
1200b57cec5SDimitry Andric                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
1210b57cec5SDimitry Andric                         .Case("opencl", LangOpts.OpenCL)
1220b57cec5SDimitry Andric                         .Case("tls", Target.isTLSSupported())
1230b57cec5SDimitry Andric                         .Case("zvector", LangOpts.ZVector)
1240b57cec5SDimitry Andric                         .Default(Target.hasFeature(Feature) ||
1250b57cec5SDimitry Andric                                  isPlatformEnvironment(Target, Feature));
1260b57cec5SDimitry Andric   if (!HasFeature)
127349cc55cSDimitry Andric     HasFeature = llvm::is_contained(LangOpts.ModuleFeatures, Feature);
1280b57cec5SDimitry Andric   return HasFeature;
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric 
isUnimportable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,Module * & ShadowingModule) const1315ffd83dbSDimitry Andric bool Module::isUnimportable(const LangOptions &LangOpts,
1325ffd83dbSDimitry Andric                             const TargetInfo &Target, Requirement &Req,
1335ffd83dbSDimitry Andric                             Module *&ShadowingModule) const {
1345ffd83dbSDimitry Andric   if (!IsUnimportable)
1355ffd83dbSDimitry Andric     return false;
1365ffd83dbSDimitry Andric 
1375ffd83dbSDimitry Andric   for (const Module *Current = this; Current; Current = Current->Parent) {
1385ffd83dbSDimitry Andric     if (Current->ShadowingModule) {
1395ffd83dbSDimitry Andric       ShadowingModule = Current->ShadowingModule;
1405ffd83dbSDimitry Andric       return true;
1415ffd83dbSDimitry Andric     }
1425ffd83dbSDimitry Andric     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
1435ffd83dbSDimitry Andric       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
1445ffd83dbSDimitry Andric               Current->Requirements[I].second) {
1455ffd83dbSDimitry Andric         Req = Current->Requirements[I];
1465ffd83dbSDimitry Andric         return true;
1475ffd83dbSDimitry Andric       }
1485ffd83dbSDimitry Andric     }
1495ffd83dbSDimitry Andric   }
1505ffd83dbSDimitry Andric 
1515ffd83dbSDimitry Andric   llvm_unreachable("could not find a reason why module is unimportable");
1525ffd83dbSDimitry Andric }
1535ffd83dbSDimitry Andric 
154bdd1243dSDimitry Andric // The -fmodule-name option tells the compiler to textually include headers in
155bdd1243dSDimitry Andric // the specified module, meaning Clang won't build the specified module. This
156bdd1243dSDimitry Andric // is useful in a number of situations, for instance, when building a library
157bdd1243dSDimitry Andric // that vends a module map, one might want to avoid hitting intermediate build
158bdd1243dSDimitry Andric // products containing the module map or avoid finding the system installed
159bdd1243dSDimitry Andric // modulemap for that library.
isForBuilding(const LangOptions & LangOpts) const160bdd1243dSDimitry Andric bool Module::isForBuilding(const LangOptions &LangOpts) const {
161bdd1243dSDimitry Andric   StringRef TopLevelName = getTopLevelModuleName();
162bdd1243dSDimitry Andric   StringRef CurrentModule = LangOpts.CurrentModule;
163bdd1243dSDimitry Andric 
1645f757f3fSDimitry Andric   // When building the implementation of framework Foo, we want to make sure
1655f757f3fSDimitry Andric   // that Foo *and* Foo_Private are textually included and no modules are built
1665f757f3fSDimitry Andric   // for either.
1675f757f3fSDimitry Andric   if (!LangOpts.isCompilingModule() && getTopLevelModule()->IsFramework &&
168bdd1243dSDimitry Andric       CurrentModule == LangOpts.ModuleName &&
1695f757f3fSDimitry Andric       !CurrentModule.ends_with("_Private") &&
1705f757f3fSDimitry Andric       TopLevelName.ends_with("_Private"))
171bdd1243dSDimitry Andric     TopLevelName = TopLevelName.drop_back(8);
172bdd1243dSDimitry Andric 
173bdd1243dSDimitry Andric   return TopLevelName == CurrentModule;
174bdd1243dSDimitry Andric }
175bdd1243dSDimitry Andric 
isAvailable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,UnresolvedHeaderDirective & MissingHeader,Module * & ShadowingModule) const1760b57cec5SDimitry Andric bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
1770b57cec5SDimitry Andric                          Requirement &Req,
1780b57cec5SDimitry Andric                          UnresolvedHeaderDirective &MissingHeader,
1790b57cec5SDimitry Andric                          Module *&ShadowingModule) const {
1800b57cec5SDimitry Andric   if (IsAvailable)
1810b57cec5SDimitry Andric     return true;
1820b57cec5SDimitry Andric 
1835ffd83dbSDimitry Andric   if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
1845ffd83dbSDimitry Andric     return false;
1855ffd83dbSDimitry Andric 
1865ffd83dbSDimitry Andric   // FIXME: All missing headers are listed on the top-level module. Should we
1875ffd83dbSDimitry Andric   // just look there?
1880b57cec5SDimitry Andric   for (const Module *Current = this; Current; Current = Current->Parent) {
1890b57cec5SDimitry Andric     if (!Current->MissingHeaders.empty()) {
1900b57cec5SDimitry Andric       MissingHeader = Current->MissingHeaders.front();
1910b57cec5SDimitry Andric       return false;
1920b57cec5SDimitry Andric     }
1930b57cec5SDimitry Andric   }
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric   llvm_unreachable("could not find a reason why module is unavailable");
1960b57cec5SDimitry Andric }
1970b57cec5SDimitry Andric 
isSubModuleOf(const Module * Other) const1980b57cec5SDimitry Andric bool Module::isSubModuleOf(const Module *Other) const {
199e8d8bef9SDimitry Andric   for (auto *Parent = this; Parent; Parent = Parent->Parent) {
200e8d8bef9SDimitry Andric     if (Parent == Other)
2010b57cec5SDimitry Andric       return true;
202e8d8bef9SDimitry Andric   }
2030b57cec5SDimitry Andric   return false;
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
getTopLevelModule() const2060b57cec5SDimitry Andric const Module *Module::getTopLevelModule() const {
2070b57cec5SDimitry Andric   const Module *Result = this;
2080b57cec5SDimitry Andric   while (Result->Parent)
2090b57cec5SDimitry Andric     Result = Result->Parent;
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   return Result;
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric 
getModuleNameFromComponent(const std::pair<std::string,SourceLocation> & IdComponent)2140b57cec5SDimitry Andric static StringRef getModuleNameFromComponent(
2150b57cec5SDimitry Andric     const std::pair<std::string, SourceLocation> &IdComponent) {
2160b57cec5SDimitry Andric   return IdComponent.first;
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric 
getModuleNameFromComponent(StringRef R)2190b57cec5SDimitry Andric static StringRef getModuleNameFromComponent(StringRef R) { return R; }
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric template<typename InputIter>
printModuleId(raw_ostream & OS,InputIter Begin,InputIter End,bool AllowStringLiterals=true)2220b57cec5SDimitry Andric static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
2230b57cec5SDimitry Andric                           bool AllowStringLiterals = true) {
2240b57cec5SDimitry Andric   for (InputIter It = Begin; It != End; ++It) {
2250b57cec5SDimitry Andric     if (It != Begin)
2260b57cec5SDimitry Andric       OS << ".";
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric     StringRef Name = getModuleNameFromComponent(*It);
229349cc55cSDimitry Andric     if (!AllowStringLiterals || isValidAsciiIdentifier(Name))
2300b57cec5SDimitry Andric       OS << Name;
2310b57cec5SDimitry Andric     else {
2320b57cec5SDimitry Andric       OS << '"';
2330b57cec5SDimitry Andric       OS.write_escaped(Name);
2340b57cec5SDimitry Andric       OS << '"';
2350b57cec5SDimitry Andric     }
2360b57cec5SDimitry Andric   }
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric template<typename Container>
printModuleId(raw_ostream & OS,const Container & C)2400b57cec5SDimitry Andric static void printModuleId(raw_ostream &OS, const Container &C) {
2410b57cec5SDimitry Andric   return printModuleId(OS, C.begin(), C.end());
2420b57cec5SDimitry Andric }
2430b57cec5SDimitry Andric 
getFullModuleName(bool AllowStringLiterals) const2440b57cec5SDimitry Andric std::string Module::getFullModuleName(bool AllowStringLiterals) const {
2450b57cec5SDimitry Andric   SmallVector<StringRef, 2> Names;
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   // Build up the set of module names (from innermost to outermost).
2480b57cec5SDimitry Andric   for (const Module *M = this; M; M = M->Parent)
2490b57cec5SDimitry Andric     Names.push_back(M->Name);
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   std::string Result;
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric   llvm::raw_string_ostream Out(Result);
2540b57cec5SDimitry Andric   printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
2550b57cec5SDimitry Andric   Out.flush();
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric   return Result;
2580b57cec5SDimitry Andric }
2590b57cec5SDimitry Andric 
fullModuleNameIs(ArrayRef<StringRef> nameParts) const2600b57cec5SDimitry Andric bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
2610b57cec5SDimitry Andric   for (const Module *M = this; M; M = M->Parent) {
2620b57cec5SDimitry Andric     if (nameParts.empty() || M->Name != nameParts.back())
2630b57cec5SDimitry Andric       return false;
2640b57cec5SDimitry Andric     nameParts = nameParts.drop_back();
2650b57cec5SDimitry Andric   }
2660b57cec5SDimitry Andric   return nameParts.empty();
2670b57cec5SDimitry Andric }
2680b57cec5SDimitry Andric 
getEffectiveUmbrellaDir() const26906c3fb27SDimitry Andric OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const {
2705f757f3fSDimitry Andric   if (const auto *Hdr = std::get_if<FileEntryRef>(&Umbrella))
2715f757f3fSDimitry Andric     return Hdr->getDir();
2725f757f3fSDimitry Andric   if (const auto *Dir = std::get_if<DirectoryEntryRef>(&Umbrella))
2735f757f3fSDimitry Andric     return *Dir;
27406c3fb27SDimitry Andric   return std::nullopt;
2755ffd83dbSDimitry Andric }
2765ffd83dbSDimitry Andric 
addTopHeader(FileEntryRef File)27706c3fb27SDimitry Andric void Module::addTopHeader(FileEntryRef File) {
2785ffd83dbSDimitry Andric   assert(File);
2795ffd83dbSDimitry Andric   TopHeaders.insert(File);
2800b57cec5SDimitry Andric }
2810b57cec5SDimitry Andric 
getTopHeaders(FileManager & FileMgr)28206c3fb27SDimitry Andric ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) {
2830b57cec5SDimitry Andric   if (!TopHeaderNames.empty()) {
28406c3fb27SDimitry Andric     for (StringRef TopHeaderName : TopHeaderNames)
28506c3fb27SDimitry Andric       if (auto FE = FileMgr.getOptionalFileRef(TopHeaderName))
286a7dea167SDimitry Andric         TopHeaders.insert(*FE);
2870b57cec5SDimitry Andric     TopHeaderNames.clear();
2880b57cec5SDimitry Andric   }
2890b57cec5SDimitry Andric 
290bdd1243dSDimitry Andric   return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end());
2910b57cec5SDimitry Andric }
2920b57cec5SDimitry Andric 
directlyUses(const Module * Requested)29381ad6265SDimitry Andric bool Module::directlyUses(const Module *Requested) {
2940b57cec5SDimitry Andric   auto *Top = getTopLevelModule();
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   // A top-level module implicitly uses itself.
2970b57cec5SDimitry Andric   if (Requested->isSubModuleOf(Top))
2980b57cec5SDimitry Andric     return true;
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   for (auto *Use : Top->DirectUses)
3010b57cec5SDimitry Andric     if (Requested->isSubModuleOf(Use))
3020b57cec5SDimitry Andric       return true;
3030b57cec5SDimitry Andric 
304439352acSDimitry Andric   // Anyone is allowed to use our builtin stddef.h and its accompanying modules.
305439352acSDimitry Andric   if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) ||
306439352acSDimitry Andric       Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"}))
3070b57cec5SDimitry Andric     return true;
3080b57cec5SDimitry Andric 
30981ad6265SDimitry Andric   if (NoUndeclaredIncludes)
31081ad6265SDimitry Andric     UndeclaredUses.insert(Requested);
31181ad6265SDimitry Andric 
3120b57cec5SDimitry Andric   return false;
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric 
addRequirement(StringRef Feature,bool RequiredState,const LangOptions & LangOpts,const TargetInfo & Target)3150b57cec5SDimitry Andric void Module::addRequirement(StringRef Feature, bool RequiredState,
3160b57cec5SDimitry Andric                             const LangOptions &LangOpts,
3170b57cec5SDimitry Andric                             const TargetInfo &Target) {
3185ffd83dbSDimitry Andric   Requirements.push_back(Requirement(std::string(Feature), RequiredState));
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   // If this feature is currently available, we're done.
3210b57cec5SDimitry Andric   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
3220b57cec5SDimitry Andric     return;
3230b57cec5SDimitry Andric 
3245ffd83dbSDimitry Andric   markUnavailable(/*Unimportable*/true);
3250b57cec5SDimitry Andric }
3260b57cec5SDimitry Andric 
markUnavailable(bool Unimportable)3275ffd83dbSDimitry Andric void Module::markUnavailable(bool Unimportable) {
3285ffd83dbSDimitry Andric   auto needUpdate = [Unimportable](Module *M) {
3295ffd83dbSDimitry Andric     return M->IsAvailable || (!M->IsUnimportable && Unimportable);
3300b57cec5SDimitry Andric   };
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric   if (!needUpdate(this))
3330b57cec5SDimitry Andric     return;
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric   SmallVector<Module *, 2> Stack;
3360b57cec5SDimitry Andric   Stack.push_back(this);
3370b57cec5SDimitry Andric   while (!Stack.empty()) {
3380b57cec5SDimitry Andric     Module *Current = Stack.back();
3390b57cec5SDimitry Andric     Stack.pop_back();
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric     if (!needUpdate(Current))
3420b57cec5SDimitry Andric       continue;
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric     Current->IsAvailable = false;
3455ffd83dbSDimitry Andric     Current->IsUnimportable |= Unimportable;
34606c3fb27SDimitry Andric     for (auto *Submodule : Current->submodules()) {
34706c3fb27SDimitry Andric       if (needUpdate(Submodule))
34806c3fb27SDimitry Andric         Stack.push_back(Submodule);
3490b57cec5SDimitry Andric     }
3500b57cec5SDimitry Andric   }
3510b57cec5SDimitry Andric }
3520b57cec5SDimitry Andric 
findSubmodule(StringRef Name) const3530b57cec5SDimitry Andric Module *Module::findSubmodule(StringRef Name) const {
3540b57cec5SDimitry Andric   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
3550b57cec5SDimitry Andric   if (Pos == SubModuleIndex.end())
3560b57cec5SDimitry Andric     return nullptr;
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric   return SubModules[Pos->getValue()];
3590b57cec5SDimitry Andric }
3600b57cec5SDimitry Andric 
findOrInferSubmodule(StringRef Name)3610b57cec5SDimitry Andric Module *Module::findOrInferSubmodule(StringRef Name) {
3620b57cec5SDimitry Andric   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
3630b57cec5SDimitry Andric   if (Pos != SubModuleIndex.end())
3640b57cec5SDimitry Andric     return SubModules[Pos->getValue()];
3650b57cec5SDimitry Andric   if (!InferSubmodules)
3660b57cec5SDimitry Andric     return nullptr;
3670b57cec5SDimitry Andric   Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
3680b57cec5SDimitry Andric   Result->InferExplicitSubmodules = InferExplicitSubmodules;
3690b57cec5SDimitry Andric   Result->InferSubmodules = InferSubmodules;
3700b57cec5SDimitry Andric   Result->InferExportWildcard = InferExportWildcard;
3710b57cec5SDimitry Andric   if (Result->InferExportWildcard)
3720b57cec5SDimitry Andric     Result->Exports.push_back(Module::ExportDecl(nullptr, true));
3730b57cec5SDimitry Andric   return Result;
3740b57cec5SDimitry Andric }
3750b57cec5SDimitry Andric 
getGlobalModuleFragment() const3765f757f3fSDimitry Andric Module *Module::getGlobalModuleFragment() const {
3775f757f3fSDimitry Andric   assert(isNamedModuleUnit() && "We should only query the global module "
3785f757f3fSDimitry Andric                                 "fragment from the C++ 20 Named modules");
3795f757f3fSDimitry Andric 
3805f757f3fSDimitry Andric   for (auto *SubModule : SubModules)
3815f757f3fSDimitry Andric     if (SubModule->isExplicitGlobalModule())
3825f757f3fSDimitry Andric       return SubModule;
3835f757f3fSDimitry Andric 
3845f757f3fSDimitry Andric   return nullptr;
3855f757f3fSDimitry Andric }
3865f757f3fSDimitry Andric 
getPrivateModuleFragment() const3875f757f3fSDimitry Andric Module *Module::getPrivateModuleFragment() const {
3885f757f3fSDimitry Andric   assert(isNamedModuleUnit() && "We should only query the private module "
3895f757f3fSDimitry Andric                                 "fragment from the C++ 20 Named modules");
3905f757f3fSDimitry Andric 
3915f757f3fSDimitry Andric   for (auto *SubModule : SubModules)
3925f757f3fSDimitry Andric     if (SubModule->isPrivateModule())
3935f757f3fSDimitry Andric       return SubModule;
3945f757f3fSDimitry Andric 
3955f757f3fSDimitry Andric   return nullptr;
3965f757f3fSDimitry Andric }
3975f757f3fSDimitry Andric 
getExportedModules(SmallVectorImpl<Module * > & Exported) const3980b57cec5SDimitry Andric void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
3990b57cec5SDimitry Andric   // All non-explicit submodules are exported.
4000b57cec5SDimitry Andric   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
4010b57cec5SDimitry Andric                                              E = SubModules.end();
4020b57cec5SDimitry Andric        I != E; ++I) {
4030b57cec5SDimitry Andric     Module *Mod = *I;
4040b57cec5SDimitry Andric     if (!Mod->IsExplicit)
4050b57cec5SDimitry Andric       Exported.push_back(Mod);
4060b57cec5SDimitry Andric   }
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric   // Find re-exported modules by filtering the list of imported modules.
4090b57cec5SDimitry Andric   bool AnyWildcard = false;
4100b57cec5SDimitry Andric   bool UnrestrictedWildcard = false;
4110b57cec5SDimitry Andric   SmallVector<Module *, 4> WildcardRestrictions;
4120b57cec5SDimitry Andric   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
4130b57cec5SDimitry Andric     Module *Mod = Exports[I].getPointer();
4140b57cec5SDimitry Andric     if (!Exports[I].getInt()) {
4150b57cec5SDimitry Andric       // Export a named module directly; no wildcards involved.
4160b57cec5SDimitry Andric       Exported.push_back(Mod);
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric       continue;
4190b57cec5SDimitry Andric     }
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric     // Wildcard export: export all of the imported modules that match
4220b57cec5SDimitry Andric     // the given pattern.
4230b57cec5SDimitry Andric     AnyWildcard = true;
4240b57cec5SDimitry Andric     if (UnrestrictedWildcard)
4250b57cec5SDimitry Andric       continue;
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric     if (Module *Restriction = Exports[I].getPointer())
4280b57cec5SDimitry Andric       WildcardRestrictions.push_back(Restriction);
4290b57cec5SDimitry Andric     else {
4300b57cec5SDimitry Andric       WildcardRestrictions.clear();
4310b57cec5SDimitry Andric       UnrestrictedWildcard = true;
4320b57cec5SDimitry Andric     }
4330b57cec5SDimitry Andric   }
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   // If there were any wildcards, push any imported modules that were
4360b57cec5SDimitry Andric   // re-exported by the wildcard restriction.
4370b57cec5SDimitry Andric   if (!AnyWildcard)
4380b57cec5SDimitry Andric     return;
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
4410b57cec5SDimitry Andric     Module *Mod = Imports[I];
4420b57cec5SDimitry Andric     bool Acceptable = UnrestrictedWildcard;
4430b57cec5SDimitry Andric     if (!Acceptable) {
4440b57cec5SDimitry Andric       // Check whether this module meets one of the restrictions.
4450b57cec5SDimitry Andric       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
4460b57cec5SDimitry Andric         Module *Restriction = WildcardRestrictions[R];
4470b57cec5SDimitry Andric         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
4480b57cec5SDimitry Andric           Acceptable = true;
4490b57cec5SDimitry Andric           break;
4500b57cec5SDimitry Andric         }
4510b57cec5SDimitry Andric       }
4520b57cec5SDimitry Andric     }
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric     if (!Acceptable)
4550b57cec5SDimitry Andric       continue;
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric     Exported.push_back(Mod);
4580b57cec5SDimitry Andric   }
4590b57cec5SDimitry Andric }
4600b57cec5SDimitry Andric 
buildVisibleModulesCache() const4610b57cec5SDimitry Andric void Module::buildVisibleModulesCache() const {
4620b57cec5SDimitry Andric   assert(VisibleModulesCache.empty() && "cache does not need building");
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric   // This module is visible to itself.
4650b57cec5SDimitry Andric   VisibleModulesCache.insert(this);
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric   // Every imported module is visible.
4680b57cec5SDimitry Andric   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
4690b57cec5SDimitry Andric   while (!Stack.empty()) {
4700b57cec5SDimitry Andric     Module *CurrModule = Stack.pop_back_val();
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric     // Every module transitively exported by an imported module is visible.
4730b57cec5SDimitry Andric     if (VisibleModulesCache.insert(CurrModule).second)
4740b57cec5SDimitry Andric       CurrModule->getExportedModules(Stack);
4750b57cec5SDimitry Andric   }
4760b57cec5SDimitry Andric }
4770b57cec5SDimitry Andric 
print(raw_ostream & OS,unsigned Indent,bool Dump) const478fe6060f1SDimitry Andric void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
4790b57cec5SDimitry Andric   OS.indent(Indent);
4800b57cec5SDimitry Andric   if (IsFramework)
4810b57cec5SDimitry Andric     OS << "framework ";
4820b57cec5SDimitry Andric   if (IsExplicit)
4830b57cec5SDimitry Andric     OS << "explicit ";
4840b57cec5SDimitry Andric   OS << "module ";
4850b57cec5SDimitry Andric   printModuleId(OS, &Name, &Name + 1);
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric   if (IsSystem || IsExternC) {
4880b57cec5SDimitry Andric     OS.indent(Indent + 2);
4890b57cec5SDimitry Andric     if (IsSystem)
4900b57cec5SDimitry Andric       OS << " [system]";
4910b57cec5SDimitry Andric     if (IsExternC)
4920b57cec5SDimitry Andric       OS << " [extern_c]";
4930b57cec5SDimitry Andric   }
4940b57cec5SDimitry Andric 
4950b57cec5SDimitry Andric   OS << " {\n";
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric   if (!Requirements.empty()) {
4980b57cec5SDimitry Andric     OS.indent(Indent + 2);
4990b57cec5SDimitry Andric     OS << "requires ";
5000b57cec5SDimitry Andric     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
5010b57cec5SDimitry Andric       if (I)
5020b57cec5SDimitry Andric         OS << ", ";
5030b57cec5SDimitry Andric       if (!Requirements[I].second)
5040b57cec5SDimitry Andric         OS << "!";
5050b57cec5SDimitry Andric       OS << Requirements[I].first;
5060b57cec5SDimitry Andric     }
5070b57cec5SDimitry Andric     OS << "\n";
5080b57cec5SDimitry Andric   }
5090b57cec5SDimitry Andric 
51006c3fb27SDimitry Andric   if (std::optional<Header> H = getUmbrellaHeaderAsWritten()) {
5110b57cec5SDimitry Andric     OS.indent(Indent + 2);
5120b57cec5SDimitry Andric     OS << "umbrella header \"";
51306c3fb27SDimitry Andric     OS.write_escaped(H->NameAsWritten);
5140b57cec5SDimitry Andric     OS << "\"\n";
51506c3fb27SDimitry Andric   } else if (std::optional<DirectoryName> D = getUmbrellaDirAsWritten()) {
5160b57cec5SDimitry Andric     OS.indent(Indent + 2);
5170b57cec5SDimitry Andric     OS << "umbrella \"";
51806c3fb27SDimitry Andric     OS.write_escaped(D->NameAsWritten);
5190b57cec5SDimitry Andric     OS << "\"\n";
5200b57cec5SDimitry Andric   }
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
5230b57cec5SDimitry Andric     OS.indent(Indent + 2);
5240b57cec5SDimitry Andric     OS << "config_macros ";
5250b57cec5SDimitry Andric     if (ConfigMacrosExhaustive)
5260b57cec5SDimitry Andric       OS << "[exhaustive]";
5270b57cec5SDimitry Andric     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
5280b57cec5SDimitry Andric       if (I)
5290b57cec5SDimitry Andric         OS << ", ";
5300b57cec5SDimitry Andric       OS << ConfigMacros[I];
5310b57cec5SDimitry Andric     }
5320b57cec5SDimitry Andric     OS << "\n";
5330b57cec5SDimitry Andric   }
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric   struct {
5360b57cec5SDimitry Andric     StringRef Prefix;
5370b57cec5SDimitry Andric     HeaderKind Kind;
5380b57cec5SDimitry Andric   } Kinds[] = {{"", HK_Normal},
5390b57cec5SDimitry Andric                {"textual ", HK_Textual},
5400b57cec5SDimitry Andric                {"private ", HK_Private},
5410b57cec5SDimitry Andric                {"private textual ", HK_PrivateTextual},
5420b57cec5SDimitry Andric                {"exclude ", HK_Excluded}};
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric   for (auto &K : Kinds) {
5450b57cec5SDimitry Andric     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
5460b57cec5SDimitry Andric     for (auto &H : Headers[K.Kind]) {
5470b57cec5SDimitry Andric       OS.indent(Indent + 2);
5480b57cec5SDimitry Andric       OS << K.Prefix << "header \"";
5490b57cec5SDimitry Andric       OS.write_escaped(H.NameAsWritten);
55006c3fb27SDimitry Andric       OS << "\" { size " << H.Entry.getSize()
55106c3fb27SDimitry Andric          << " mtime " << H.Entry.getModificationTime() << " }\n";
5520b57cec5SDimitry Andric     }
5530b57cec5SDimitry Andric   }
5540b57cec5SDimitry Andric   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
5550b57cec5SDimitry Andric     for (auto &U : *Unresolved) {
5560b57cec5SDimitry Andric       OS.indent(Indent + 2);
5570b57cec5SDimitry Andric       OS << Kinds[U.Kind].Prefix << "header \"";
5580b57cec5SDimitry Andric       OS.write_escaped(U.FileName);
5590b57cec5SDimitry Andric       OS << "\"";
5600b57cec5SDimitry Andric       if (U.Size || U.ModTime) {
5610b57cec5SDimitry Andric         OS << " {";
5620b57cec5SDimitry Andric         if (U.Size)
5630b57cec5SDimitry Andric           OS << " size " << *U.Size;
5640b57cec5SDimitry Andric         if (U.ModTime)
5650b57cec5SDimitry Andric           OS << " mtime " << *U.ModTime;
5660b57cec5SDimitry Andric         OS << " }";
5670b57cec5SDimitry Andric       }
5680b57cec5SDimitry Andric       OS << "\n";
5690b57cec5SDimitry Andric     }
5700b57cec5SDimitry Andric   }
5710b57cec5SDimitry Andric 
5720b57cec5SDimitry Andric   if (!ExportAsModule.empty()) {
5730b57cec5SDimitry Andric     OS.indent(Indent + 2);
5740b57cec5SDimitry Andric     OS << "export_as" << ExportAsModule << "\n";
5750b57cec5SDimitry Andric   }
5760b57cec5SDimitry Andric 
57706c3fb27SDimitry Andric   for (auto *Submodule : submodules())
5780b57cec5SDimitry Andric     // Print inferred subframework modules so that we don't need to re-infer
5790b57cec5SDimitry Andric     // them (requires expensive directory iteration + stat calls) when we build
5800b57cec5SDimitry Andric     // the module. Regular inferred submodules are OK, as we need to look at all
5810b57cec5SDimitry Andric     // those header files anyway.
58206c3fb27SDimitry Andric     if (!Submodule->IsInferred || Submodule->IsFramework)
58306c3fb27SDimitry Andric       Submodule->print(OS, Indent + 2, Dump);
5840b57cec5SDimitry Andric 
5850b57cec5SDimitry Andric   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
5860b57cec5SDimitry Andric     OS.indent(Indent + 2);
5870b57cec5SDimitry Andric     OS << "export ";
5880b57cec5SDimitry Andric     if (Module *Restriction = Exports[I].getPointer()) {
5890b57cec5SDimitry Andric       OS << Restriction->getFullModuleName(true);
5900b57cec5SDimitry Andric       if (Exports[I].getInt())
5910b57cec5SDimitry Andric         OS << ".*";
5920b57cec5SDimitry Andric     } else {
5930b57cec5SDimitry Andric       OS << "*";
5940b57cec5SDimitry Andric     }
5950b57cec5SDimitry Andric     OS << "\n";
5960b57cec5SDimitry Andric   }
5970b57cec5SDimitry Andric 
5980b57cec5SDimitry Andric   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
5990b57cec5SDimitry Andric     OS.indent(Indent + 2);
6000b57cec5SDimitry Andric     OS << "export ";
6010b57cec5SDimitry Andric     printModuleId(OS, UnresolvedExports[I].Id);
6020b57cec5SDimitry Andric     if (UnresolvedExports[I].Wildcard)
6030b57cec5SDimitry Andric       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
6040b57cec5SDimitry Andric     OS << "\n";
6050b57cec5SDimitry Andric   }
6060b57cec5SDimitry Andric 
607fe6060f1SDimitry Andric   if (Dump) {
608fe6060f1SDimitry Andric     for (Module *M : Imports) {
609fe6060f1SDimitry Andric       OS.indent(Indent + 2);
610fe6060f1SDimitry Andric       llvm::errs() << "import " << M->getFullModuleName() << "\n";
611fe6060f1SDimitry Andric     }
612fe6060f1SDimitry Andric   }
613fe6060f1SDimitry Andric 
6140b57cec5SDimitry Andric   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
6150b57cec5SDimitry Andric     OS.indent(Indent + 2);
6160b57cec5SDimitry Andric     OS << "use ";
6170b57cec5SDimitry Andric     OS << DirectUses[I]->getFullModuleName(true);
6180b57cec5SDimitry Andric     OS << "\n";
6190b57cec5SDimitry Andric   }
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
6220b57cec5SDimitry Andric     OS.indent(Indent + 2);
6230b57cec5SDimitry Andric     OS << "use ";
6240b57cec5SDimitry Andric     printModuleId(OS, UnresolvedDirectUses[I]);
6250b57cec5SDimitry Andric     OS << "\n";
6260b57cec5SDimitry Andric   }
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
6290b57cec5SDimitry Andric     OS.indent(Indent + 2);
6300b57cec5SDimitry Andric     OS << "link ";
6310b57cec5SDimitry Andric     if (LinkLibraries[I].IsFramework)
6320b57cec5SDimitry Andric       OS << "framework ";
6330b57cec5SDimitry Andric     OS << "\"";
6340b57cec5SDimitry Andric     OS.write_escaped(LinkLibraries[I].Library);
6350b57cec5SDimitry Andric     OS << "\"";
6360b57cec5SDimitry Andric   }
6370b57cec5SDimitry Andric 
6380b57cec5SDimitry Andric   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
6390b57cec5SDimitry Andric     OS.indent(Indent + 2);
6400b57cec5SDimitry Andric     OS << "conflict ";
6410b57cec5SDimitry Andric     printModuleId(OS, UnresolvedConflicts[I].Id);
6420b57cec5SDimitry Andric     OS << ", \"";
6430b57cec5SDimitry Andric     OS.write_escaped(UnresolvedConflicts[I].Message);
6440b57cec5SDimitry Andric     OS << "\"\n";
6450b57cec5SDimitry Andric   }
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
6480b57cec5SDimitry Andric     OS.indent(Indent + 2);
6490b57cec5SDimitry Andric     OS << "conflict ";
6500b57cec5SDimitry Andric     OS << Conflicts[I].Other->getFullModuleName(true);
6510b57cec5SDimitry Andric     OS << ", \"";
6520b57cec5SDimitry Andric     OS.write_escaped(Conflicts[I].Message);
6530b57cec5SDimitry Andric     OS << "\"\n";
6540b57cec5SDimitry Andric   }
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric   if (InferSubmodules) {
6570b57cec5SDimitry Andric     OS.indent(Indent + 2);
6580b57cec5SDimitry Andric     if (InferExplicitSubmodules)
6590b57cec5SDimitry Andric       OS << "explicit ";
6600b57cec5SDimitry Andric     OS << "module * {\n";
6610b57cec5SDimitry Andric     if (InferExportWildcard) {
6620b57cec5SDimitry Andric       OS.indent(Indent + 4);
6630b57cec5SDimitry Andric       OS << "export *\n";
6640b57cec5SDimitry Andric     }
6650b57cec5SDimitry Andric     OS.indent(Indent + 2);
6660b57cec5SDimitry Andric     OS << "}\n";
6670b57cec5SDimitry Andric   }
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric   OS.indent(Indent);
6700b57cec5SDimitry Andric   OS << "}\n";
6710b57cec5SDimitry Andric }
6720b57cec5SDimitry Andric 
dump() const6730b57cec5SDimitry Andric LLVM_DUMP_METHOD void Module::dump() const {
674fe6060f1SDimitry Andric   print(llvm::errs(), 0, true);
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric 
setVisible(Module * M,SourceLocation Loc,VisibleCallback Vis,ConflictCallback Cb)6770b57cec5SDimitry Andric void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
6780b57cec5SDimitry Andric                                   VisibleCallback Vis, ConflictCallback Cb) {
679bdd1243dSDimitry Andric   // We can't import a global module fragment so the location can be invalid.
680bdd1243dSDimitry Andric   assert((M->isGlobalModule() || Loc.isValid()) &&
681bdd1243dSDimitry Andric          "setVisible expects a valid import location");
6820b57cec5SDimitry Andric   if (isVisible(M))
6830b57cec5SDimitry Andric     return;
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric   ++Generation;
6860b57cec5SDimitry Andric 
6870b57cec5SDimitry Andric   struct Visiting {
6880b57cec5SDimitry Andric     Module *M;
6890b57cec5SDimitry Andric     Visiting *ExportedBy;
6900b57cec5SDimitry Andric   };
6910b57cec5SDimitry Andric 
6920b57cec5SDimitry Andric   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
6930b57cec5SDimitry Andric     // Nothing to do for a module that's already visible.
6940b57cec5SDimitry Andric     unsigned ID = V.M->getVisibilityID();
6950b57cec5SDimitry Andric     if (ImportLocs.size() <= ID)
6960b57cec5SDimitry Andric       ImportLocs.resize(ID + 1);
6970b57cec5SDimitry Andric     else if (ImportLocs[ID].isValid())
6980b57cec5SDimitry Andric       return;
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric     ImportLocs[ID] = Loc;
701bdd1243dSDimitry Andric     Vis(V.M);
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric     // Make any exported modules visible.
7040b57cec5SDimitry Andric     SmallVector<Module *, 16> Exports;
7050b57cec5SDimitry Andric     V.M->getExportedModules(Exports);
7060b57cec5SDimitry Andric     for (Module *E : Exports) {
7075ffd83dbSDimitry Andric       // Don't import non-importable modules.
7085ffd83dbSDimitry Andric       if (!E->isUnimportable())
7090b57cec5SDimitry Andric         VisitModule({E, &V});
7100b57cec5SDimitry Andric     }
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric     for (auto &C : V.M->Conflicts) {
7130b57cec5SDimitry Andric       if (isVisible(C.Other)) {
7140b57cec5SDimitry Andric         llvm::SmallVector<Module*, 8> Path;
7150b57cec5SDimitry Andric         for (Visiting *I = &V; I; I = I->ExportedBy)
7160b57cec5SDimitry Andric           Path.push_back(I->M);
7170b57cec5SDimitry Andric         Cb(Path, C.Other, C.Message);
7180b57cec5SDimitry Andric       }
7190b57cec5SDimitry Andric     }
7200b57cec5SDimitry Andric   };
7210b57cec5SDimitry Andric   VisitModule({M, nullptr});
7220b57cec5SDimitry Andric }
7235ffd83dbSDimitry Andric 
makeTransitiveImportsVisible(Module * M,SourceLocation Loc,VisibleCallback Vis,ConflictCallback Cb)72406c3fb27SDimitry Andric void VisibleModuleSet::makeTransitiveImportsVisible(Module *M,
72506c3fb27SDimitry Andric                                                     SourceLocation Loc,
72606c3fb27SDimitry Andric                                                     VisibleCallback Vis,
72706c3fb27SDimitry Andric                                                     ConflictCallback Cb) {
72806c3fb27SDimitry Andric   for (auto *I : M->Imports)
72906c3fb27SDimitry Andric     setVisible(I, Loc, Vis, Cb);
73006c3fb27SDimitry Andric }
73106c3fb27SDimitry Andric 
ASTSourceDescriptor(Module & M)7325ffd83dbSDimitry Andric ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
7335ffd83dbSDimitry Andric     : Signature(M.Signature), ClangModule(&M) {
7345ffd83dbSDimitry Andric   if (M.Directory)
7355ffd83dbSDimitry Andric     Path = M.Directory->getName();
736e8d8bef9SDimitry Andric   if (auto File = M.getASTFile())
7375ffd83dbSDimitry Andric     ASTFile = File->getName();
7385ffd83dbSDimitry Andric }
7395ffd83dbSDimitry Andric 
getModuleName() const7405ffd83dbSDimitry Andric std::string ASTSourceDescriptor::getModuleName() const {
7415ffd83dbSDimitry Andric   if (ClangModule)
7425ffd83dbSDimitry Andric     return ClangModule->Name;
7435ffd83dbSDimitry Andric   else
7445ffd83dbSDimitry Andric     return std::string(PCHModuleName);
7455ffd83dbSDimitry Andric }
746