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),
47af732203SDimitry Andric       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() {
620b57cec5SDimitry Andric   for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
630b57cec5SDimitry Andric        I != IEnd; ++I) {
640b57cec5SDimitry Andric     delete *I;
650b57cec5SDimitry Andric   }
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
isPlatformEnvironment(const TargetInfo & Target,StringRef Feature)680b57cec5SDimitry Andric static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
690b57cec5SDimitry Andric   StringRef Platform = Target.getPlatformName();
700b57cec5SDimitry Andric   StringRef Env = Target.getTriple().getEnvironmentName();
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric   // Attempt to match platform and environment.
730b57cec5SDimitry Andric   if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
740b57cec5SDimitry Andric       Env == Feature)
750b57cec5SDimitry Andric     return true;
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric   auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
78af732203SDimitry Andric     auto Pos = LHS.find('-');
790b57cec5SDimitry Andric     if (Pos == StringRef::npos)
800b57cec5SDimitry Andric       return false;
810b57cec5SDimitry Andric     SmallString<128> NewLHS = LHS.slice(0, Pos);
820b57cec5SDimitry Andric     NewLHS += LHS.slice(Pos+1, LHS.size());
830b57cec5SDimitry Andric     return NewLHS == RHS;
840b57cec5SDimitry Andric   };
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
870b57cec5SDimitry Andric   // Darwin has different but equivalent variants for simulators, example:
880b57cec5SDimitry Andric   //   1. x86_64-apple-ios-simulator
890b57cec5SDimitry Andric   //   2. x86_64-apple-iossimulator
900b57cec5SDimitry Andric   // where both are valid examples of the same platform+environment but in the
910b57cec5SDimitry Andric   // variant (2) the simulator is hardcoded as part of the platform name. Both
920b57cec5SDimitry Andric   // forms above should match for "iossimulator" requirement.
930b57cec5SDimitry Andric   if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator"))
940b57cec5SDimitry Andric     return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   return PlatformEnv == Feature;
970b57cec5SDimitry Andric }
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric /// Determine whether a translation unit built using the current
1000b57cec5SDimitry Andric /// language options has the given feature.
hasFeature(StringRef Feature,const LangOptions & LangOpts,const TargetInfo & Target)1010b57cec5SDimitry Andric static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
1020b57cec5SDimitry Andric                        const TargetInfo &Target) {
1030b57cec5SDimitry Andric   bool HasFeature = llvm::StringSwitch<bool>(Feature)
1040b57cec5SDimitry Andric                         .Case("altivec", LangOpts.AltiVec)
1050b57cec5SDimitry Andric                         .Case("blocks", LangOpts.Blocks)
1060b57cec5SDimitry Andric                         .Case("coroutines", LangOpts.Coroutines)
1070b57cec5SDimitry Andric                         .Case("cplusplus", LangOpts.CPlusPlus)
1080b57cec5SDimitry Andric                         .Case("cplusplus11", LangOpts.CPlusPlus11)
1090b57cec5SDimitry Andric                         .Case("cplusplus14", LangOpts.CPlusPlus14)
1100b57cec5SDimitry Andric                         .Case("cplusplus17", LangOpts.CPlusPlus17)
1110b57cec5SDimitry Andric                         .Case("c99", LangOpts.C99)
1120b57cec5SDimitry Andric                         .Case("c11", LangOpts.C11)
1130b57cec5SDimitry Andric                         .Case("c17", LangOpts.C17)
1140b57cec5SDimitry Andric                         .Case("freestanding", LangOpts.Freestanding)
1150b57cec5SDimitry Andric                         .Case("gnuinlineasm", LangOpts.GNUAsm)
1160b57cec5SDimitry Andric                         .Case("objc", LangOpts.ObjC)
1170b57cec5SDimitry Andric                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
1180b57cec5SDimitry Andric                         .Case("opencl", LangOpts.OpenCL)
1190b57cec5SDimitry Andric                         .Case("tls", Target.isTLSSupported())
1200b57cec5SDimitry Andric                         .Case("zvector", LangOpts.ZVector)
1210b57cec5SDimitry Andric                         .Default(Target.hasFeature(Feature) ||
1220b57cec5SDimitry Andric                                  isPlatformEnvironment(Target, Feature));
1230b57cec5SDimitry Andric   if (!HasFeature)
1240b57cec5SDimitry Andric     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
1250b57cec5SDimitry Andric                            LangOpts.ModuleFeatures.end(),
1260b57cec5SDimitry Andric                            Feature) != LangOpts.ModuleFeatures.end();
1270b57cec5SDimitry Andric   return HasFeature;
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric 
isUnimportable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,Module * & ShadowingModule) const1305ffd83dbSDimitry Andric bool Module::isUnimportable(const LangOptions &LangOpts,
1315ffd83dbSDimitry Andric                             const TargetInfo &Target, Requirement &Req,
1325ffd83dbSDimitry Andric                             Module *&ShadowingModule) const {
1335ffd83dbSDimitry Andric   if (!IsUnimportable)
1345ffd83dbSDimitry Andric     return false;
1355ffd83dbSDimitry Andric 
1365ffd83dbSDimitry Andric   for (const Module *Current = this; Current; Current = Current->Parent) {
1375ffd83dbSDimitry Andric     if (Current->ShadowingModule) {
1385ffd83dbSDimitry Andric       ShadowingModule = Current->ShadowingModule;
1395ffd83dbSDimitry Andric       return true;
1405ffd83dbSDimitry Andric     }
1415ffd83dbSDimitry Andric     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
1425ffd83dbSDimitry Andric       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
1435ffd83dbSDimitry Andric               Current->Requirements[I].second) {
1445ffd83dbSDimitry Andric         Req = Current->Requirements[I];
1455ffd83dbSDimitry Andric         return true;
1465ffd83dbSDimitry Andric       }
1475ffd83dbSDimitry Andric     }
1485ffd83dbSDimitry Andric   }
1495ffd83dbSDimitry Andric 
1505ffd83dbSDimitry Andric   llvm_unreachable("could not find a reason why module is unimportable");
1515ffd83dbSDimitry Andric }
1525ffd83dbSDimitry Andric 
isAvailable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,UnresolvedHeaderDirective & MissingHeader,Module * & ShadowingModule) const1530b57cec5SDimitry Andric bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
1540b57cec5SDimitry Andric                          Requirement &Req,
1550b57cec5SDimitry Andric                          UnresolvedHeaderDirective &MissingHeader,
1560b57cec5SDimitry Andric                          Module *&ShadowingModule) const {
1570b57cec5SDimitry Andric   if (IsAvailable)
1580b57cec5SDimitry Andric     return true;
1590b57cec5SDimitry Andric 
1605ffd83dbSDimitry Andric   if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
1615ffd83dbSDimitry Andric     return false;
1625ffd83dbSDimitry Andric 
1635ffd83dbSDimitry Andric   // FIXME: All missing headers are listed on the top-level module. Should we
1645ffd83dbSDimitry Andric   // just look there?
1650b57cec5SDimitry Andric   for (const Module *Current = this; Current; Current = Current->Parent) {
1660b57cec5SDimitry Andric     if (!Current->MissingHeaders.empty()) {
1670b57cec5SDimitry Andric       MissingHeader = Current->MissingHeaders.front();
1680b57cec5SDimitry Andric       return false;
1690b57cec5SDimitry Andric     }
1700b57cec5SDimitry Andric   }
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   llvm_unreachable("could not find a reason why module is unavailable");
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
isSubModuleOf(const Module * Other) const1750b57cec5SDimitry Andric bool Module::isSubModuleOf(const Module *Other) const {
176af732203SDimitry Andric   for (auto *Parent = this; Parent; Parent = Parent->Parent) {
177af732203SDimitry Andric     if (Parent == Other)
1780b57cec5SDimitry Andric       return true;
179af732203SDimitry Andric   }
1800b57cec5SDimitry Andric   return false;
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric 
getTopLevelModule() const1830b57cec5SDimitry Andric const Module *Module::getTopLevelModule() const {
1840b57cec5SDimitry Andric   const Module *Result = this;
1850b57cec5SDimitry Andric   while (Result->Parent)
1860b57cec5SDimitry Andric     Result = Result->Parent;
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric   return Result;
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric 
getModuleNameFromComponent(const std::pair<std::string,SourceLocation> & IdComponent)1910b57cec5SDimitry Andric static StringRef getModuleNameFromComponent(
1920b57cec5SDimitry Andric     const std::pair<std::string, SourceLocation> &IdComponent) {
1930b57cec5SDimitry Andric   return IdComponent.first;
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric 
getModuleNameFromComponent(StringRef R)1960b57cec5SDimitry Andric static StringRef getModuleNameFromComponent(StringRef R) { return R; }
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric template<typename InputIter>
printModuleId(raw_ostream & OS,InputIter Begin,InputIter End,bool AllowStringLiterals=true)1990b57cec5SDimitry Andric static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
2000b57cec5SDimitry Andric                           bool AllowStringLiterals = true) {
2010b57cec5SDimitry Andric   for (InputIter It = Begin; It != End; ++It) {
2020b57cec5SDimitry Andric     if (It != Begin)
2030b57cec5SDimitry Andric       OS << ".";
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric     StringRef Name = getModuleNameFromComponent(*It);
2060b57cec5SDimitry Andric     if (!AllowStringLiterals || isValidIdentifier(Name))
2070b57cec5SDimitry Andric       OS << Name;
2080b57cec5SDimitry Andric     else {
2090b57cec5SDimitry Andric       OS << '"';
2100b57cec5SDimitry Andric       OS.write_escaped(Name);
2110b57cec5SDimitry Andric       OS << '"';
2120b57cec5SDimitry Andric     }
2130b57cec5SDimitry Andric   }
2140b57cec5SDimitry Andric }
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric template<typename Container>
printModuleId(raw_ostream & OS,const Container & C)2170b57cec5SDimitry Andric static void printModuleId(raw_ostream &OS, const Container &C) {
2180b57cec5SDimitry Andric   return printModuleId(OS, C.begin(), C.end());
2190b57cec5SDimitry Andric }
2200b57cec5SDimitry Andric 
getFullModuleName(bool AllowStringLiterals) const2210b57cec5SDimitry Andric std::string Module::getFullModuleName(bool AllowStringLiterals) const {
2220b57cec5SDimitry Andric   SmallVector<StringRef, 2> Names;
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   // Build up the set of module names (from innermost to outermost).
2250b57cec5SDimitry Andric   for (const Module *M = this; M; M = M->Parent)
2260b57cec5SDimitry Andric     Names.push_back(M->Name);
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   std::string Result;
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric   llvm::raw_string_ostream Out(Result);
2310b57cec5SDimitry Andric   printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
2320b57cec5SDimitry Andric   Out.flush();
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric   return Result;
2350b57cec5SDimitry Andric }
2360b57cec5SDimitry Andric 
fullModuleNameIs(ArrayRef<StringRef> nameParts) const2370b57cec5SDimitry Andric bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
2380b57cec5SDimitry Andric   for (const Module *M = this; M; M = M->Parent) {
2390b57cec5SDimitry Andric     if (nameParts.empty() || M->Name != nameParts.back())
2400b57cec5SDimitry Andric       return false;
2410b57cec5SDimitry Andric     nameParts = nameParts.drop_back();
2420b57cec5SDimitry Andric   }
2430b57cec5SDimitry Andric   return nameParts.empty();
2440b57cec5SDimitry Andric }
2450b57cec5SDimitry Andric 
getUmbrellaDir() const2460b57cec5SDimitry Andric Module::DirectoryName Module::getUmbrellaDir() const {
2470b57cec5SDimitry Andric   if (Header U = getUmbrellaHeader())
248*5f7ddb14SDimitry Andric     return {"", "", U.Entry->getDir()};
2490b57cec5SDimitry Andric 
250*5f7ddb14SDimitry Andric   return {UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
251*5f7ddb14SDimitry Andric           Umbrella.dyn_cast<const DirectoryEntry *>()};
2525ffd83dbSDimitry Andric }
2535ffd83dbSDimitry Andric 
addTopHeader(const FileEntry * File)2545ffd83dbSDimitry Andric void Module::addTopHeader(const FileEntry *File) {
2555ffd83dbSDimitry Andric   assert(File);
2565ffd83dbSDimitry Andric   TopHeaders.insert(File);
2570b57cec5SDimitry Andric }
2580b57cec5SDimitry Andric 
getTopHeaders(FileManager & FileMgr)2590b57cec5SDimitry Andric ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
2600b57cec5SDimitry Andric   if (!TopHeaderNames.empty()) {
2610b57cec5SDimitry Andric     for (std::vector<std::string>::iterator
2620b57cec5SDimitry Andric            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
263a7dea167SDimitry Andric       if (auto FE = FileMgr.getFile(*I))
264a7dea167SDimitry Andric         TopHeaders.insert(*FE);
2650b57cec5SDimitry Andric     }
2660b57cec5SDimitry Andric     TopHeaderNames.clear();
2670b57cec5SDimitry Andric   }
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
2700b57cec5SDimitry Andric }
2710b57cec5SDimitry Andric 
directlyUses(const Module * Requested) const2720b57cec5SDimitry Andric bool Module::directlyUses(const Module *Requested) const {
2730b57cec5SDimitry Andric   auto *Top = getTopLevelModule();
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric   // A top-level module implicitly uses itself.
2760b57cec5SDimitry Andric   if (Requested->isSubModuleOf(Top))
2770b57cec5SDimitry Andric     return true;
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   for (auto *Use : Top->DirectUses)
2800b57cec5SDimitry Andric     if (Requested->isSubModuleOf(Use))
2810b57cec5SDimitry Andric       return true;
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   // Anyone is allowed to use our builtin stddef.h and its accompanying module.
2840b57cec5SDimitry Andric   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
2850b57cec5SDimitry Andric     return true;
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   return false;
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric 
addRequirement(StringRef Feature,bool RequiredState,const LangOptions & LangOpts,const TargetInfo & Target)2900b57cec5SDimitry Andric void Module::addRequirement(StringRef Feature, bool RequiredState,
2910b57cec5SDimitry Andric                             const LangOptions &LangOpts,
2920b57cec5SDimitry Andric                             const TargetInfo &Target) {
2935ffd83dbSDimitry Andric   Requirements.push_back(Requirement(std::string(Feature), RequiredState));
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric   // If this feature is currently available, we're done.
2960b57cec5SDimitry Andric   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
2970b57cec5SDimitry Andric     return;
2980b57cec5SDimitry Andric 
2995ffd83dbSDimitry Andric   markUnavailable(/*Unimportable*/true);
3000b57cec5SDimitry Andric }
3010b57cec5SDimitry Andric 
markUnavailable(bool Unimportable)3025ffd83dbSDimitry Andric void Module::markUnavailable(bool Unimportable) {
3035ffd83dbSDimitry Andric   auto needUpdate = [Unimportable](Module *M) {
3045ffd83dbSDimitry Andric     return M->IsAvailable || (!M->IsUnimportable && Unimportable);
3050b57cec5SDimitry Andric   };
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric   if (!needUpdate(this))
3080b57cec5SDimitry Andric     return;
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   SmallVector<Module *, 2> Stack;
3110b57cec5SDimitry Andric   Stack.push_back(this);
3120b57cec5SDimitry Andric   while (!Stack.empty()) {
3130b57cec5SDimitry Andric     Module *Current = Stack.back();
3140b57cec5SDimitry Andric     Stack.pop_back();
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric     if (!needUpdate(Current))
3170b57cec5SDimitry Andric       continue;
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric     Current->IsAvailable = false;
3205ffd83dbSDimitry Andric     Current->IsUnimportable |= Unimportable;
3210b57cec5SDimitry Andric     for (submodule_iterator Sub = Current->submodule_begin(),
3220b57cec5SDimitry Andric                          SubEnd = Current->submodule_end();
3230b57cec5SDimitry Andric          Sub != SubEnd; ++Sub) {
3240b57cec5SDimitry Andric       if (needUpdate(*Sub))
3250b57cec5SDimitry Andric         Stack.push_back(*Sub);
3260b57cec5SDimitry Andric     }
3270b57cec5SDimitry Andric   }
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
findSubmodule(StringRef Name) const3300b57cec5SDimitry Andric Module *Module::findSubmodule(StringRef Name) const {
3310b57cec5SDimitry Andric   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
3320b57cec5SDimitry Andric   if (Pos == SubModuleIndex.end())
3330b57cec5SDimitry Andric     return nullptr;
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric   return SubModules[Pos->getValue()];
3360b57cec5SDimitry Andric }
3370b57cec5SDimitry Andric 
findOrInferSubmodule(StringRef Name)3380b57cec5SDimitry Andric Module *Module::findOrInferSubmodule(StringRef Name) {
3390b57cec5SDimitry Andric   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
3400b57cec5SDimitry Andric   if (Pos != SubModuleIndex.end())
3410b57cec5SDimitry Andric     return SubModules[Pos->getValue()];
3420b57cec5SDimitry Andric   if (!InferSubmodules)
3430b57cec5SDimitry Andric     return nullptr;
3440b57cec5SDimitry Andric   Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
3450b57cec5SDimitry Andric   Result->InferExplicitSubmodules = InferExplicitSubmodules;
3460b57cec5SDimitry Andric   Result->InferSubmodules = InferSubmodules;
3470b57cec5SDimitry Andric   Result->InferExportWildcard = InferExportWildcard;
3480b57cec5SDimitry Andric   if (Result->InferExportWildcard)
3490b57cec5SDimitry Andric     Result->Exports.push_back(Module::ExportDecl(nullptr, true));
3500b57cec5SDimitry Andric   return Result;
3510b57cec5SDimitry Andric }
3520b57cec5SDimitry Andric 
getExportedModules(SmallVectorImpl<Module * > & Exported) const3530b57cec5SDimitry Andric void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
3540b57cec5SDimitry Andric   // All non-explicit submodules are exported.
3550b57cec5SDimitry Andric   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
3560b57cec5SDimitry Andric                                              E = SubModules.end();
3570b57cec5SDimitry Andric        I != E; ++I) {
3580b57cec5SDimitry Andric     Module *Mod = *I;
3590b57cec5SDimitry Andric     if (!Mod->IsExplicit)
3600b57cec5SDimitry Andric       Exported.push_back(Mod);
3610b57cec5SDimitry Andric   }
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric   // Find re-exported modules by filtering the list of imported modules.
3640b57cec5SDimitry Andric   bool AnyWildcard = false;
3650b57cec5SDimitry Andric   bool UnrestrictedWildcard = false;
3660b57cec5SDimitry Andric   SmallVector<Module *, 4> WildcardRestrictions;
3670b57cec5SDimitry Andric   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
3680b57cec5SDimitry Andric     Module *Mod = Exports[I].getPointer();
3690b57cec5SDimitry Andric     if (!Exports[I].getInt()) {
3700b57cec5SDimitry Andric       // Export a named module directly; no wildcards involved.
3710b57cec5SDimitry Andric       Exported.push_back(Mod);
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric       continue;
3740b57cec5SDimitry Andric     }
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric     // Wildcard export: export all of the imported modules that match
3770b57cec5SDimitry Andric     // the given pattern.
3780b57cec5SDimitry Andric     AnyWildcard = true;
3790b57cec5SDimitry Andric     if (UnrestrictedWildcard)
3800b57cec5SDimitry Andric       continue;
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric     if (Module *Restriction = Exports[I].getPointer())
3830b57cec5SDimitry Andric       WildcardRestrictions.push_back(Restriction);
3840b57cec5SDimitry Andric     else {
3850b57cec5SDimitry Andric       WildcardRestrictions.clear();
3860b57cec5SDimitry Andric       UnrestrictedWildcard = true;
3870b57cec5SDimitry Andric     }
3880b57cec5SDimitry Andric   }
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric   // If there were any wildcards, push any imported modules that were
3910b57cec5SDimitry Andric   // re-exported by the wildcard restriction.
3920b57cec5SDimitry Andric   if (!AnyWildcard)
3930b57cec5SDimitry Andric     return;
3940b57cec5SDimitry Andric 
3950b57cec5SDimitry Andric   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
3960b57cec5SDimitry Andric     Module *Mod = Imports[I];
3970b57cec5SDimitry Andric     bool Acceptable = UnrestrictedWildcard;
3980b57cec5SDimitry Andric     if (!Acceptable) {
3990b57cec5SDimitry Andric       // Check whether this module meets one of the restrictions.
4000b57cec5SDimitry Andric       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
4010b57cec5SDimitry Andric         Module *Restriction = WildcardRestrictions[R];
4020b57cec5SDimitry Andric         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
4030b57cec5SDimitry Andric           Acceptable = true;
4040b57cec5SDimitry Andric           break;
4050b57cec5SDimitry Andric         }
4060b57cec5SDimitry Andric       }
4070b57cec5SDimitry Andric     }
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric     if (!Acceptable)
4100b57cec5SDimitry Andric       continue;
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric     Exported.push_back(Mod);
4130b57cec5SDimitry Andric   }
4140b57cec5SDimitry Andric }
4150b57cec5SDimitry Andric 
buildVisibleModulesCache() const4160b57cec5SDimitry Andric void Module::buildVisibleModulesCache() const {
4170b57cec5SDimitry Andric   assert(VisibleModulesCache.empty() && "cache does not need building");
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric   // This module is visible to itself.
4200b57cec5SDimitry Andric   VisibleModulesCache.insert(this);
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric   // Every imported module is visible.
4230b57cec5SDimitry Andric   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
4240b57cec5SDimitry Andric   while (!Stack.empty()) {
4250b57cec5SDimitry Andric     Module *CurrModule = Stack.pop_back_val();
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric     // Every module transitively exported by an imported module is visible.
4280b57cec5SDimitry Andric     if (VisibleModulesCache.insert(CurrModule).second)
4290b57cec5SDimitry Andric       CurrModule->getExportedModules(Stack);
4300b57cec5SDimitry Andric   }
4310b57cec5SDimitry Andric }
4320b57cec5SDimitry Andric 
print(raw_ostream & OS,unsigned Indent,bool Dump) const433*5f7ddb14SDimitry Andric void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
4340b57cec5SDimitry Andric   OS.indent(Indent);
4350b57cec5SDimitry Andric   if (IsFramework)
4360b57cec5SDimitry Andric     OS << "framework ";
4370b57cec5SDimitry Andric   if (IsExplicit)
4380b57cec5SDimitry Andric     OS << "explicit ";
4390b57cec5SDimitry Andric   OS << "module ";
4400b57cec5SDimitry Andric   printModuleId(OS, &Name, &Name + 1);
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   if (IsSystem || IsExternC) {
4430b57cec5SDimitry Andric     OS.indent(Indent + 2);
4440b57cec5SDimitry Andric     if (IsSystem)
4450b57cec5SDimitry Andric       OS << " [system]";
4460b57cec5SDimitry Andric     if (IsExternC)
4470b57cec5SDimitry Andric       OS << " [extern_c]";
4480b57cec5SDimitry Andric   }
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric   OS << " {\n";
4510b57cec5SDimitry Andric 
4520b57cec5SDimitry Andric   if (!Requirements.empty()) {
4530b57cec5SDimitry Andric     OS.indent(Indent + 2);
4540b57cec5SDimitry Andric     OS << "requires ";
4550b57cec5SDimitry Andric     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
4560b57cec5SDimitry Andric       if (I)
4570b57cec5SDimitry Andric         OS << ", ";
4580b57cec5SDimitry Andric       if (!Requirements[I].second)
4590b57cec5SDimitry Andric         OS << "!";
4600b57cec5SDimitry Andric       OS << Requirements[I].first;
4610b57cec5SDimitry Andric     }
4620b57cec5SDimitry Andric     OS << "\n";
4630b57cec5SDimitry Andric   }
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   if (Header H = getUmbrellaHeader()) {
4660b57cec5SDimitry Andric     OS.indent(Indent + 2);
4670b57cec5SDimitry Andric     OS << "umbrella header \"";
4680b57cec5SDimitry Andric     OS.write_escaped(H.NameAsWritten);
4690b57cec5SDimitry Andric     OS << "\"\n";
4700b57cec5SDimitry Andric   } else if (DirectoryName D = getUmbrellaDir()) {
4710b57cec5SDimitry Andric     OS.indent(Indent + 2);
4720b57cec5SDimitry Andric     OS << "umbrella \"";
4730b57cec5SDimitry Andric     OS.write_escaped(D.NameAsWritten);
4740b57cec5SDimitry Andric     OS << "\"\n";
4750b57cec5SDimitry Andric   }
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
4780b57cec5SDimitry Andric     OS.indent(Indent + 2);
4790b57cec5SDimitry Andric     OS << "config_macros ";
4800b57cec5SDimitry Andric     if (ConfigMacrosExhaustive)
4810b57cec5SDimitry Andric       OS << "[exhaustive]";
4820b57cec5SDimitry Andric     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
4830b57cec5SDimitry Andric       if (I)
4840b57cec5SDimitry Andric         OS << ", ";
4850b57cec5SDimitry Andric       OS << ConfigMacros[I];
4860b57cec5SDimitry Andric     }
4870b57cec5SDimitry Andric     OS << "\n";
4880b57cec5SDimitry Andric   }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric   struct {
4910b57cec5SDimitry Andric     StringRef Prefix;
4920b57cec5SDimitry Andric     HeaderKind Kind;
4930b57cec5SDimitry Andric   } Kinds[] = {{"", HK_Normal},
4940b57cec5SDimitry Andric                {"textual ", HK_Textual},
4950b57cec5SDimitry Andric                {"private ", HK_Private},
4960b57cec5SDimitry Andric                {"private textual ", HK_PrivateTextual},
4970b57cec5SDimitry Andric                {"exclude ", HK_Excluded}};
4980b57cec5SDimitry Andric 
4990b57cec5SDimitry Andric   for (auto &K : Kinds) {
5000b57cec5SDimitry Andric     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
5010b57cec5SDimitry Andric     for (auto &H : Headers[K.Kind]) {
5020b57cec5SDimitry Andric       OS.indent(Indent + 2);
5030b57cec5SDimitry Andric       OS << K.Prefix << "header \"";
5040b57cec5SDimitry Andric       OS.write_escaped(H.NameAsWritten);
5050b57cec5SDimitry Andric       OS << "\" { size " << H.Entry->getSize()
5060b57cec5SDimitry Andric          << " mtime " << H.Entry->getModificationTime() << " }\n";
5070b57cec5SDimitry Andric     }
5080b57cec5SDimitry Andric   }
5090b57cec5SDimitry Andric   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
5100b57cec5SDimitry Andric     for (auto &U : *Unresolved) {
5110b57cec5SDimitry Andric       OS.indent(Indent + 2);
5120b57cec5SDimitry Andric       OS << Kinds[U.Kind].Prefix << "header \"";
5130b57cec5SDimitry Andric       OS.write_escaped(U.FileName);
5140b57cec5SDimitry Andric       OS << "\"";
5150b57cec5SDimitry Andric       if (U.Size || U.ModTime) {
5160b57cec5SDimitry Andric         OS << " {";
5170b57cec5SDimitry Andric         if (U.Size)
5180b57cec5SDimitry Andric           OS << " size " << *U.Size;
5190b57cec5SDimitry Andric         if (U.ModTime)
5200b57cec5SDimitry Andric           OS << " mtime " << *U.ModTime;
5210b57cec5SDimitry Andric         OS << " }";
5220b57cec5SDimitry Andric       }
5230b57cec5SDimitry Andric       OS << "\n";
5240b57cec5SDimitry Andric     }
5250b57cec5SDimitry Andric   }
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric   if (!ExportAsModule.empty()) {
5280b57cec5SDimitry Andric     OS.indent(Indent + 2);
5290b57cec5SDimitry Andric     OS << "export_as" << ExportAsModule << "\n";
5300b57cec5SDimitry Andric   }
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
5330b57cec5SDimitry Andric        MI != MIEnd; ++MI)
5340b57cec5SDimitry Andric     // Print inferred subframework modules so that we don't need to re-infer
5350b57cec5SDimitry Andric     // them (requires expensive directory iteration + stat calls) when we build
5360b57cec5SDimitry Andric     // the module. Regular inferred submodules are OK, as we need to look at all
5370b57cec5SDimitry Andric     // those header files anyway.
5380b57cec5SDimitry Andric     if (!(*MI)->IsInferred || (*MI)->IsFramework)
539*5f7ddb14SDimitry Andric       (*MI)->print(OS, Indent + 2, Dump);
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
5420b57cec5SDimitry Andric     OS.indent(Indent + 2);
5430b57cec5SDimitry Andric     OS << "export ";
5440b57cec5SDimitry Andric     if (Module *Restriction = Exports[I].getPointer()) {
5450b57cec5SDimitry Andric       OS << Restriction->getFullModuleName(true);
5460b57cec5SDimitry Andric       if (Exports[I].getInt())
5470b57cec5SDimitry Andric         OS << ".*";
5480b57cec5SDimitry Andric     } else {
5490b57cec5SDimitry Andric       OS << "*";
5500b57cec5SDimitry Andric     }
5510b57cec5SDimitry Andric     OS << "\n";
5520b57cec5SDimitry Andric   }
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
5550b57cec5SDimitry Andric     OS.indent(Indent + 2);
5560b57cec5SDimitry Andric     OS << "export ";
5570b57cec5SDimitry Andric     printModuleId(OS, UnresolvedExports[I].Id);
5580b57cec5SDimitry Andric     if (UnresolvedExports[I].Wildcard)
5590b57cec5SDimitry Andric       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
5600b57cec5SDimitry Andric     OS << "\n";
5610b57cec5SDimitry Andric   }
5620b57cec5SDimitry Andric 
563*5f7ddb14SDimitry Andric   if (Dump) {
564*5f7ddb14SDimitry Andric     for (Module *M : Imports) {
565*5f7ddb14SDimitry Andric       OS.indent(Indent + 2);
566*5f7ddb14SDimitry Andric       llvm::errs() << "import " << M->getFullModuleName() << "\n";
567*5f7ddb14SDimitry Andric     }
568*5f7ddb14SDimitry Andric   }
569*5f7ddb14SDimitry Andric 
5700b57cec5SDimitry Andric   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
5710b57cec5SDimitry Andric     OS.indent(Indent + 2);
5720b57cec5SDimitry Andric     OS << "use ";
5730b57cec5SDimitry Andric     OS << DirectUses[I]->getFullModuleName(true);
5740b57cec5SDimitry Andric     OS << "\n";
5750b57cec5SDimitry Andric   }
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
5780b57cec5SDimitry Andric     OS.indent(Indent + 2);
5790b57cec5SDimitry Andric     OS << "use ";
5800b57cec5SDimitry Andric     printModuleId(OS, UnresolvedDirectUses[I]);
5810b57cec5SDimitry Andric     OS << "\n";
5820b57cec5SDimitry Andric   }
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
5850b57cec5SDimitry Andric     OS.indent(Indent + 2);
5860b57cec5SDimitry Andric     OS << "link ";
5870b57cec5SDimitry Andric     if (LinkLibraries[I].IsFramework)
5880b57cec5SDimitry Andric       OS << "framework ";
5890b57cec5SDimitry Andric     OS << "\"";
5900b57cec5SDimitry Andric     OS.write_escaped(LinkLibraries[I].Library);
5910b57cec5SDimitry Andric     OS << "\"";
5920b57cec5SDimitry Andric   }
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
5950b57cec5SDimitry Andric     OS.indent(Indent + 2);
5960b57cec5SDimitry Andric     OS << "conflict ";
5970b57cec5SDimitry Andric     printModuleId(OS, UnresolvedConflicts[I].Id);
5980b57cec5SDimitry Andric     OS << ", \"";
5990b57cec5SDimitry Andric     OS.write_escaped(UnresolvedConflicts[I].Message);
6000b57cec5SDimitry Andric     OS << "\"\n";
6010b57cec5SDimitry Andric   }
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
6040b57cec5SDimitry Andric     OS.indent(Indent + 2);
6050b57cec5SDimitry Andric     OS << "conflict ";
6060b57cec5SDimitry Andric     OS << Conflicts[I].Other->getFullModuleName(true);
6070b57cec5SDimitry Andric     OS << ", \"";
6080b57cec5SDimitry Andric     OS.write_escaped(Conflicts[I].Message);
6090b57cec5SDimitry Andric     OS << "\"\n";
6100b57cec5SDimitry Andric   }
6110b57cec5SDimitry Andric 
6120b57cec5SDimitry Andric   if (InferSubmodules) {
6130b57cec5SDimitry Andric     OS.indent(Indent + 2);
6140b57cec5SDimitry Andric     if (InferExplicitSubmodules)
6150b57cec5SDimitry Andric       OS << "explicit ";
6160b57cec5SDimitry Andric     OS << "module * {\n";
6170b57cec5SDimitry Andric     if (InferExportWildcard) {
6180b57cec5SDimitry Andric       OS.indent(Indent + 4);
6190b57cec5SDimitry Andric       OS << "export *\n";
6200b57cec5SDimitry Andric     }
6210b57cec5SDimitry Andric     OS.indent(Indent + 2);
6220b57cec5SDimitry Andric     OS << "}\n";
6230b57cec5SDimitry Andric   }
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric   OS.indent(Indent);
6260b57cec5SDimitry Andric   OS << "}\n";
6270b57cec5SDimitry Andric }
6280b57cec5SDimitry Andric 
dump() const6290b57cec5SDimitry Andric LLVM_DUMP_METHOD void Module::dump() const {
630*5f7ddb14SDimitry Andric   print(llvm::errs(), 0, true);
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric 
setVisible(Module * M,SourceLocation Loc,VisibleCallback Vis,ConflictCallback Cb)6330b57cec5SDimitry Andric void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
6340b57cec5SDimitry Andric                                   VisibleCallback Vis, ConflictCallback Cb) {
6350b57cec5SDimitry Andric   assert(Loc.isValid() && "setVisible expects a valid import location");
6360b57cec5SDimitry Andric   if (isVisible(M))
6370b57cec5SDimitry Andric     return;
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric   ++Generation;
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric   struct Visiting {
6420b57cec5SDimitry Andric     Module *M;
6430b57cec5SDimitry Andric     Visiting *ExportedBy;
6440b57cec5SDimitry Andric   };
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
6470b57cec5SDimitry Andric     // Nothing to do for a module that's already visible.
6480b57cec5SDimitry Andric     unsigned ID = V.M->getVisibilityID();
6490b57cec5SDimitry Andric     if (ImportLocs.size() <= ID)
6500b57cec5SDimitry Andric       ImportLocs.resize(ID + 1);
6510b57cec5SDimitry Andric     else if (ImportLocs[ID].isValid())
6520b57cec5SDimitry Andric       return;
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric     ImportLocs[ID] = Loc;
6550b57cec5SDimitry Andric     Vis(M);
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric     // Make any exported modules visible.
6580b57cec5SDimitry Andric     SmallVector<Module *, 16> Exports;
6590b57cec5SDimitry Andric     V.M->getExportedModules(Exports);
6600b57cec5SDimitry Andric     for (Module *E : Exports) {
6615ffd83dbSDimitry Andric       // Don't import non-importable modules.
6625ffd83dbSDimitry Andric       if (!E->isUnimportable())
6630b57cec5SDimitry Andric         VisitModule({E, &V});
6640b57cec5SDimitry Andric     }
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric     for (auto &C : V.M->Conflicts) {
6670b57cec5SDimitry Andric       if (isVisible(C.Other)) {
6680b57cec5SDimitry Andric         llvm::SmallVector<Module*, 8> Path;
6690b57cec5SDimitry Andric         for (Visiting *I = &V; I; I = I->ExportedBy)
6700b57cec5SDimitry Andric           Path.push_back(I->M);
6710b57cec5SDimitry Andric         Cb(Path, C.Other, C.Message);
6720b57cec5SDimitry Andric       }
6730b57cec5SDimitry Andric     }
6740b57cec5SDimitry Andric   };
6750b57cec5SDimitry Andric   VisitModule({M, nullptr});
6760b57cec5SDimitry Andric }
6775ffd83dbSDimitry Andric 
ASTSourceDescriptor(Module & M)6785ffd83dbSDimitry Andric ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
6795ffd83dbSDimitry Andric     : Signature(M.Signature), ClangModule(&M) {
6805ffd83dbSDimitry Andric   if (M.Directory)
6815ffd83dbSDimitry Andric     Path = M.Directory->getName();
682af732203SDimitry Andric   if (auto File = M.getASTFile())
6835ffd83dbSDimitry Andric     ASTFile = File->getName();
6845ffd83dbSDimitry Andric }
6855ffd83dbSDimitry Andric 
getModuleName() const6865ffd83dbSDimitry Andric std::string ASTSourceDescriptor::getModuleName() const {
6875ffd83dbSDimitry Andric   if (ClangModule)
6885ffd83dbSDimitry Andric     return ClangModule->Name;
6895ffd83dbSDimitry Andric   else
6905ffd83dbSDimitry Andric     return std::string(PCHModuleName);
6915ffd83dbSDimitry Andric }
692