1918e0ca7SEugene Zelenko //===- Module.cpp - Describe a module -------------------------------------===//
2de3ef502SDouglas Gregor //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6de3ef502SDouglas Gregor //
7de3ef502SDouglas Gregor //===----------------------------------------------------------------------===//
8de3ef502SDouglas Gregor //
9de3ef502SDouglas Gregor // This file defines the Module class, which describes a module in the source
10de3ef502SDouglas Gregor // code.
11de3ef502SDouglas Gregor //
12de3ef502SDouglas Gregor //===----------------------------------------------------------------------===//
13a3feee2aSRichard Smith 
14de3ef502SDouglas Gregor #include "clang/Basic/Module.h"
159565c75bSRichard Smith #include "clang/Basic/CharInfo.h"
16de3ef502SDouglas Gregor #include "clang/Basic/FileManager.h"
171fb5c3a6SDouglas Gregor #include "clang/Basic/LangOptions.h"
18918e0ca7SEugene Zelenko #include "clang/Basic/SourceLocation.h"
190070c0bfSDouglas Gregor #include "clang/Basic/TargetInfo.h"
203c5305c1SArgyrios Kyrtzidis #include "llvm/ADT/ArrayRef.h"
211fb5c3a6SDouglas Gregor #include "llvm/ADT/SmallVector.h"
22918e0ca7SEugene Zelenko #include "llvm/ADT/StringMap.h"
23918e0ca7SEugene Zelenko #include "llvm/ADT/StringRef.h"
241fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h"
25918e0ca7SEugene Zelenko #include "llvm/Support/Compiler.h"
263a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h"
273a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h"
28918e0ca7SEugene Zelenko #include <algorithm>
29918e0ca7SEugene Zelenko #include <cassert>
30918e0ca7SEugene Zelenko #include <functional>
31918e0ca7SEugene Zelenko #include <string>
32918e0ca7SEugene Zelenko #include <utility>
33918e0ca7SEugene Zelenko #include <vector>
34a3feee2aSRichard Smith 
35de3ef502SDouglas Gregor using namespace clang;
36de3ef502SDouglas Gregor 
37eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
38a7e2cc68SRichard Smith                bool IsFramework, bool IsExplicit, unsigned VisibilityID)
39918e0ca7SEugene Zelenko     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
40fc76b4adSRichard Smith       VisibilityID(VisibilityID), IsUnimportable(false),
41918e0ca7SEugene Zelenko       HasIncompatibleModuleFile(false), IsAvailable(true),
42918e0ca7SEugene Zelenko       IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
43918e0ca7SEugene Zelenko       IsSystem(false), IsExternC(false), IsInferred(false),
44918e0ca7SEugene Zelenko       InferSubmodules(false), InferExplicitSubmodules(false),
458a308ec2SRichard Smith       InferExportWildcard(false), ConfigMacrosExhaustive(false),
4690b0a1fcSJordan Rose       NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
476e73cfa8SDuncan P. N. Exon Smith       NameVisibility(Hidden) {
48eb90e830SDouglas Gregor   if (Parent) {
49fc76b4adSRichard Smith     IsAvailable = Parent->isAvailable();
50fc76b4adSRichard Smith     IsUnimportable = Parent->isUnimportable();
51fc76b4adSRichard Smith     IsSystem = Parent->IsSystem;
52fc76b4adSRichard Smith     IsExternC = Parent->IsExternC;
53fc76b4adSRichard Smith     NoUndeclaredIncludes = Parent->NoUndeclaredIncludes;
54fc76b4adSRichard Smith     ModuleMapIsPrivate = Parent->ModuleMapIsPrivate;
55eb90e830SDouglas Gregor 
56eb90e830SDouglas Gregor     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
57eb90e830SDouglas Gregor     Parent->SubModules.push_back(this);
58eb90e830SDouglas Gregor   }
59eb90e830SDouglas Gregor }
60eb90e830SDouglas Gregor 
61de3ef502SDouglas Gregor Module::~Module() {
62eb90e830SDouglas Gregor   for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
63de3ef502SDouglas Gregor        I != IEnd; ++I) {
64eb90e830SDouglas Gregor     delete *I;
65de3ef502SDouglas Gregor   }
66de3ef502SDouglas Gregor }
67de3ef502SDouglas Gregor 
68e7240f02SBruno Cardoso Lopes static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
69e7240f02SBruno Cardoso Lopes   StringRef Platform = Target.getPlatformName();
70e7240f02SBruno Cardoso Lopes   StringRef Env = Target.getTriple().getEnvironmentName();
71e7240f02SBruno Cardoso Lopes 
72e7240f02SBruno Cardoso Lopes   // Attempt to match platform and environment.
73e7240f02SBruno Cardoso Lopes   if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
74e7240f02SBruno Cardoso Lopes       Env == Feature)
75e7240f02SBruno Cardoso Lopes     return true;
76e7240f02SBruno Cardoso Lopes 
77e7240f02SBruno Cardoso Lopes   auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
78c70f3686SFangrui Song     auto Pos = LHS.find('-');
79e7240f02SBruno Cardoso Lopes     if (Pos == StringRef::npos)
80e7240f02SBruno Cardoso Lopes       return false;
81e7240f02SBruno Cardoso Lopes     SmallString<128> NewLHS = LHS.slice(0, Pos);
82e7240f02SBruno Cardoso Lopes     NewLHS += LHS.slice(Pos+1, LHS.size());
83e7240f02SBruno Cardoso Lopes     return NewLHS == RHS;
84e7240f02SBruno Cardoso Lopes   };
85e7240f02SBruno Cardoso Lopes 
86e7240f02SBruno Cardoso Lopes   SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
87e7240f02SBruno Cardoso Lopes   // Darwin has different but equivalent variants for simulators, example:
88e7240f02SBruno Cardoso Lopes   //   1. x86_64-apple-ios-simulator
89e7240f02SBruno Cardoso Lopes   //   2. x86_64-apple-iossimulator
90e7240f02SBruno Cardoso Lopes   // where both are valid examples of the same platform+environment but in the
91e7240f02SBruno Cardoso Lopes   // variant (2) the simulator is hardcoded as part of the platform name. Both
92e7240f02SBruno Cardoso Lopes   // forms above should match for "iossimulator" requirement.
93e7240f02SBruno Cardoso Lopes   if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator"))
94e7240f02SBruno Cardoso Lopes     return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
95e7240f02SBruno Cardoso Lopes 
96e7240f02SBruno Cardoso Lopes   return PlatformEnv == Feature;
97e7240f02SBruno Cardoso Lopes }
98e7240f02SBruno Cardoso Lopes 
999fc8faf9SAdrian Prantl /// Determine whether a translation unit built using the current
1001fb5c3a6SDouglas Gregor /// language options has the given feature.
10189929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
10289929282SDouglas Gregor                        const TargetInfo &Target) {
103532d2104SBen Langmuir   bool HasFeature = llvm::StringSwitch<bool>(Feature)
1040070c0bfSDouglas Gregor                         .Case("altivec", LangOpts.AltiVec)
1051fb5c3a6SDouglas Gregor                         .Case("blocks", LangOpts.Blocks)
10610ab78e8SRichard Smith                         .Case("coroutines", LangOpts.Coroutines)
1071fb5c3a6SDouglas Gregor                         .Case("cplusplus", LangOpts.CPlusPlus)
1082bf7fdb7SRichard Smith                         .Case("cplusplus11", LangOpts.CPlusPlus11)
1096d9cf8aaSBruno Cardoso Lopes                         .Case("cplusplus14", LangOpts.CPlusPlus14)
1106d9cf8aaSBruno Cardoso Lopes                         .Case("cplusplus17", LangOpts.CPlusPlus17)
1116d9cf8aaSBruno Cardoso Lopes                         .Case("c99", LangOpts.C99)
1126d9cf8aaSBruno Cardoso Lopes                         .Case("c11", LangOpts.C11)
1136d9cf8aaSBruno Cardoso Lopes                         .Case("c17", LangOpts.C17)
114fb6358d2SElad Cohen                         .Case("freestanding", LangOpts.Freestanding)
1156736e199SBruno Cardoso Lopes                         .Case("gnuinlineasm", LangOpts.GNUAsm)
116fa98390bSErik Pilkington                         .Case("objc", LangOpts.ObjC)
1171fb5c3a6SDouglas Gregor                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
1180070c0bfSDouglas Gregor                         .Case("opencl", LangOpts.OpenCL)
1190070c0bfSDouglas Gregor                         .Case("tls", Target.isTLSSupported())
1203c5038a5SUlrich Weigand                         .Case("zvector", LangOpts.ZVector)
121e7240f02SBruno Cardoso Lopes                         .Default(Target.hasFeature(Feature) ||
122e7240f02SBruno Cardoso Lopes                                  isPlatformEnvironment(Target, Feature));
123532d2104SBen Langmuir   if (!HasFeature)
124532d2104SBen Langmuir     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
125532d2104SBen Langmuir                            LangOpts.ModuleFeatures.end(),
126532d2104SBen Langmuir                            Feature) != LangOpts.ModuleFeatures.end();
127532d2104SBen Langmuir   return HasFeature;
1281fb5c3a6SDouglas Gregor }
1291fb5c3a6SDouglas Gregor 
130fc76b4adSRichard Smith bool Module::isUnimportable(const LangOptions &LangOpts,
131fc76b4adSRichard Smith                             const TargetInfo &Target, Requirement &Req,
132fc76b4adSRichard Smith                             Module *&ShadowingModule) const {
133fc76b4adSRichard Smith   if (!IsUnimportable)
134fc76b4adSRichard Smith     return false;
135fc76b4adSRichard Smith 
136fc76b4adSRichard Smith   for (const Module *Current = this; Current; Current = Current->Parent) {
137fc76b4adSRichard Smith     if (Current->ShadowingModule) {
138fc76b4adSRichard Smith       ShadowingModule = Current->ShadowingModule;
139fc76b4adSRichard Smith       return true;
140fc76b4adSRichard Smith     }
141fc76b4adSRichard Smith     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
142fc76b4adSRichard Smith       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
143fc76b4adSRichard Smith               Current->Requirements[I].second) {
144fc76b4adSRichard Smith         Req = Current->Requirements[I];
145fc76b4adSRichard Smith         return true;
146fc76b4adSRichard Smith       }
147fc76b4adSRichard Smith     }
148fc76b4adSRichard Smith   }
149fc76b4adSRichard Smith 
150fc76b4adSRichard Smith   llvm_unreachable("could not find a reason why module is unimportable");
151fc76b4adSRichard Smith }
152fc76b4adSRichard Smith 
1533c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
1543c1a41adSRichard Smith                          Requirement &Req,
1558587dfd9SBruno Cardoso Lopes                          UnresolvedHeaderDirective &MissingHeader,
1568587dfd9SBruno Cardoso Lopes                          Module *&ShadowingModule) const {
1571fb5c3a6SDouglas Gregor   if (IsAvailable)
1581fb5c3a6SDouglas Gregor     return true;
1591fb5c3a6SDouglas Gregor 
160fc76b4adSRichard Smith   if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
161fc76b4adSRichard Smith     return false;
162fc76b4adSRichard Smith 
163fc76b4adSRichard Smith   // FIXME: All missing headers are listed on the top-level module. Should we
164fc76b4adSRichard Smith   // just look there?
1651fb5c3a6SDouglas Gregor   for (const Module *Current = this; Current; Current = Current->Parent) {
16675a7e435SBen Langmuir     if (!Current->MissingHeaders.empty()) {
16775a7e435SBen Langmuir       MissingHeader = Current->MissingHeaders.front();
16875a7e435SBen Langmuir       return false;
16975a7e435SBen Langmuir     }
1701fb5c3a6SDouglas Gregor   }
1711fb5c3a6SDouglas Gregor 
1721fb5c3a6SDouglas Gregor   llvm_unreachable("could not find a reason why module is unavailable");
1731fb5c3a6SDouglas Gregor }
1741fb5c3a6SDouglas Gregor 
17562bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const {
176b907ad53SAdrian Prantl   for (auto *Parent = this; Parent; Parent = Parent->Parent) {
177b907ad53SAdrian Prantl     if (Parent == Other)
178f5eedd05SDouglas Gregor       return true;
179b907ad53SAdrian Prantl   }
180f5eedd05SDouglas Gregor   return false;
181f5eedd05SDouglas Gregor }
182f5eedd05SDouglas Gregor 
18373441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
18473441091SDouglas Gregor   const Module *Result = this;
18573441091SDouglas Gregor   while (Result->Parent)
18673441091SDouglas Gregor     Result = Result->Parent;
18773441091SDouglas Gregor 
18873441091SDouglas Gregor   return Result;
18973441091SDouglas Gregor }
19073441091SDouglas Gregor 
1919565c75bSRichard Smith static StringRef getModuleNameFromComponent(
1929565c75bSRichard Smith     const std::pair<std::string, SourceLocation> &IdComponent) {
1939565c75bSRichard Smith   return IdComponent.first;
1949565c75bSRichard Smith }
195918e0ca7SEugene Zelenko 
1969565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; }
1979565c75bSRichard Smith 
1989565c75bSRichard Smith template<typename InputIter>
1999565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
2009565c75bSRichard Smith                           bool AllowStringLiterals = true) {
2019565c75bSRichard Smith   for (InputIter It = Begin; It != End; ++It) {
2029565c75bSRichard Smith     if (It != Begin)
2039565c75bSRichard Smith       OS << ".";
2049565c75bSRichard Smith 
2059565c75bSRichard Smith     StringRef Name = getModuleNameFromComponent(*It);
206*601102d2SCorentin Jabot     if (!AllowStringLiterals || isValidAsciiIdentifier(Name))
2079565c75bSRichard Smith       OS << Name;
2089565c75bSRichard Smith     else {
2099565c75bSRichard Smith       OS << '"';
2109565c75bSRichard Smith       OS.write_escaped(Name);
2119565c75bSRichard Smith       OS << '"';
2129565c75bSRichard Smith     }
2139565c75bSRichard Smith   }
2149565c75bSRichard Smith }
2159565c75bSRichard Smith 
2169565c75bSRichard Smith template<typename Container>
2179565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) {
2189565c75bSRichard Smith   return printModuleId(OS, C.begin(), C.end());
2199565c75bSRichard Smith }
2209565c75bSRichard Smith 
2219565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const {
222f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Names;
223de3ef502SDouglas Gregor 
224de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
225de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
226de3ef502SDouglas Gregor     Names.push_back(M->Name);
227de3ef502SDouglas Gregor 
228de3ef502SDouglas Gregor   std::string Result;
229de3ef502SDouglas Gregor 
2309565c75bSRichard Smith   llvm::raw_string_ostream Out(Result);
2319565c75bSRichard Smith   printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
2329565c75bSRichard Smith   Out.flush();
233de3ef502SDouglas Gregor 
234de3ef502SDouglas Gregor   return Result;
235de3ef502SDouglas Gregor }
236de3ef502SDouglas Gregor 
2377ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
2387ff29148SBen Langmuir   for (const Module *M = this; M; M = M->Parent) {
2397ff29148SBen Langmuir     if (nameParts.empty() || M->Name != nameParts.back())
2407ff29148SBen Langmuir       return false;
2417ff29148SBen Langmuir     nameParts = nameParts.drop_back();
2427ff29148SBen Langmuir   }
2437ff29148SBen Langmuir   return nameParts.empty();
2447ff29148SBen Langmuir }
2457ff29148SBen Langmuir 
2462b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const {
2472b63d15fSRichard Smith   if (Header U = getUmbrellaHeader())
248d3676d4bSMichael Spencer     return {"", "", U.Entry->getDir()};
24973141fa9SDouglas Gregor 
250d3676d4bSMichael Spencer   return {UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
251d3676d4bSMichael Spencer           Umbrella.dyn_cast<const DirectoryEntry *>()};
252bc883665SReid Kleckner }
253bc883665SReid Kleckner 
254bc883665SReid Kleckner void Module::addTopHeader(const FileEntry *File) {
255bc883665SReid Kleckner   assert(File);
256bc883665SReid Kleckner   TopHeaders.insert(File);
25773141fa9SDouglas Gregor }
25873141fa9SDouglas Gregor 
2593c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
2603c5305c1SArgyrios Kyrtzidis   if (!TopHeaderNames.empty()) {
2613c5305c1SArgyrios Kyrtzidis     for (std::vector<std::string>::iterator
2623c5305c1SArgyrios Kyrtzidis            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
2638d323d15SHarlan Haskins       if (auto FE = FileMgr.getFile(*I))
2648d323d15SHarlan Haskins         TopHeaders.insert(*FE);
2653c5305c1SArgyrios Kyrtzidis     }
2663c5305c1SArgyrios Kyrtzidis     TopHeaderNames.clear();
2673c5305c1SArgyrios Kyrtzidis   }
2683c5305c1SArgyrios Kyrtzidis 
2693c5305c1SArgyrios Kyrtzidis   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
2703c5305c1SArgyrios Kyrtzidis }
2713c5305c1SArgyrios Kyrtzidis 
2728f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const {
2738f4d3ff1SRichard Smith   auto *Top = getTopLevelModule();
2748f4d3ff1SRichard Smith 
2758f4d3ff1SRichard Smith   // A top-level module implicitly uses itself.
2768f4d3ff1SRichard Smith   if (Requested->isSubModuleOf(Top))
2778f4d3ff1SRichard Smith     return true;
2788f4d3ff1SRichard Smith 
2798f4d3ff1SRichard Smith   for (auto *Use : Top->DirectUses)
2808f4d3ff1SRichard Smith     if (Requested->isSubModuleOf(Use))
2818f4d3ff1SRichard Smith       return true;
282ed84df00SBruno Cardoso Lopes 
283ed84df00SBruno Cardoso Lopes   // Anyone is allowed to use our builtin stddef.h and its accompanying module.
284ed84df00SBruno Cardoso Lopes   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
285ed84df00SBruno Cardoso Lopes     return true;
286ed84df00SBruno Cardoso Lopes 
2878f4d3ff1SRichard Smith   return false;
2888f4d3ff1SRichard Smith }
2898f4d3ff1SRichard Smith 
290a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
291a3feee2aSRichard Smith                             const LangOptions &LangOpts,
29289929282SDouglas Gregor                             const TargetInfo &Target) {
293bb39b529SBenjamin Kramer   Requirements.push_back(Requirement(std::string(Feature), RequiredState));
2941fb5c3a6SDouglas Gregor 
2951fb5c3a6SDouglas Gregor   // If this feature is currently available, we're done.
296a3feee2aSRichard Smith   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
2971fb5c3a6SDouglas Gregor     return;
2981fb5c3a6SDouglas Gregor 
299fc76b4adSRichard Smith   markUnavailable(/*Unimportable*/true);
300ec8c9752SBen Langmuir }
301ec8c9752SBen Langmuir 
302fc76b4adSRichard Smith void Module::markUnavailable(bool Unimportable) {
303fc76b4adSRichard Smith   auto needUpdate = [Unimportable](Module *M) {
304fc76b4adSRichard Smith     return M->IsAvailable || (!M->IsUnimportable && Unimportable);
30575a7e435SBen Langmuir   };
30675a7e435SBen Langmuir 
30775a7e435SBen Langmuir   if (!needUpdate(this))
3081fb5c3a6SDouglas Gregor     return;
3091fb5c3a6SDouglas Gregor 
310f857950dSDmitri Gribenko   SmallVector<Module *, 2> Stack;
3111fb5c3a6SDouglas Gregor   Stack.push_back(this);
3121fb5c3a6SDouglas Gregor   while (!Stack.empty()) {
3131fb5c3a6SDouglas Gregor     Module *Current = Stack.back();
3141fb5c3a6SDouglas Gregor     Stack.pop_back();
3151fb5c3a6SDouglas Gregor 
31675a7e435SBen Langmuir     if (!needUpdate(Current))
3171fb5c3a6SDouglas Gregor       continue;
3181fb5c3a6SDouglas Gregor 
3191fb5c3a6SDouglas Gregor     Current->IsAvailable = false;
320fc76b4adSRichard Smith     Current->IsUnimportable |= Unimportable;
321eb90e830SDouglas Gregor     for (submodule_iterator Sub = Current->submodule_begin(),
322eb90e830SDouglas Gregor                          SubEnd = Current->submodule_end();
3231fb5c3a6SDouglas Gregor          Sub != SubEnd; ++Sub) {
32475a7e435SBen Langmuir       if (needUpdate(*Sub))
325eb90e830SDouglas Gregor         Stack.push_back(*Sub);
3261fb5c3a6SDouglas Gregor     }
3271fb5c3a6SDouglas Gregor   }
3281fb5c3a6SDouglas Gregor }
3291fb5c3a6SDouglas Gregor 
330eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
331eb90e830SDouglas Gregor   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
332eb90e830SDouglas Gregor   if (Pos == SubModuleIndex.end())
333f1186c5aSCraig Topper     return nullptr;
334eb90e830SDouglas Gregor 
335eb90e830SDouglas Gregor   return SubModules[Pos->getValue()];
336eb90e830SDouglas Gregor }
337eb90e830SDouglas Gregor 
33889e58ddbSDavid Blaikie Module *Module::findOrInferSubmodule(StringRef Name) {
33989e58ddbSDavid Blaikie   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
34089e58ddbSDavid Blaikie   if (Pos != SubModuleIndex.end())
34189e58ddbSDavid Blaikie     return SubModules[Pos->getValue()];
34289e58ddbSDavid Blaikie   if (!InferSubmodules)
34389e58ddbSDavid Blaikie     return nullptr;
34489e58ddbSDavid Blaikie   Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
34589e58ddbSDavid Blaikie   Result->InferExplicitSubmodules = InferExplicitSubmodules;
34689e58ddbSDavid Blaikie   Result->InferSubmodules = InferSubmodules;
34789e58ddbSDavid Blaikie   Result->InferExportWildcard = InferExportWildcard;
34889e58ddbSDavid Blaikie   if (Result->InferExportWildcard)
34989e58ddbSDavid Blaikie     Result->Exports.push_back(Module::ExportDecl(nullptr, true));
35089e58ddbSDavid Blaikie   return Result;
35189e58ddbSDavid Blaikie }
35289e58ddbSDavid Blaikie 
3538739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
354e9bcf5b7SDmitri Gribenko   // All non-explicit submodules are exported.
355e9bcf5b7SDmitri Gribenko   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
356e9bcf5b7SDmitri Gribenko                                              E = SubModules.end();
357e9bcf5b7SDmitri Gribenko        I != E; ++I) {
358e9bcf5b7SDmitri Gribenko     Module *Mod = *I;
359e9bcf5b7SDmitri Gribenko     if (!Mod->IsExplicit)
360e9bcf5b7SDmitri Gribenko       Exported.push_back(Mod);
361e9bcf5b7SDmitri Gribenko   }
362e9bcf5b7SDmitri Gribenko 
363e9bcf5b7SDmitri Gribenko   // Find re-exported modules by filtering the list of imported modules.
3648739f7b7SArgyrios Kyrtzidis   bool AnyWildcard = false;
3658739f7b7SArgyrios Kyrtzidis   bool UnrestrictedWildcard = false;
3668739f7b7SArgyrios Kyrtzidis   SmallVector<Module *, 4> WildcardRestrictions;
3678739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
3688739f7b7SArgyrios Kyrtzidis     Module *Mod = Exports[I].getPointer();
3698739f7b7SArgyrios Kyrtzidis     if (!Exports[I].getInt()) {
3708739f7b7SArgyrios Kyrtzidis       // Export a named module directly; no wildcards involved.
3718739f7b7SArgyrios Kyrtzidis       Exported.push_back(Mod);
3728739f7b7SArgyrios Kyrtzidis 
3738739f7b7SArgyrios Kyrtzidis       continue;
3748739f7b7SArgyrios Kyrtzidis     }
3758739f7b7SArgyrios Kyrtzidis 
3768739f7b7SArgyrios Kyrtzidis     // Wildcard export: export all of the imported modules that match
3778739f7b7SArgyrios Kyrtzidis     // the given pattern.
3788739f7b7SArgyrios Kyrtzidis     AnyWildcard = true;
3798739f7b7SArgyrios Kyrtzidis     if (UnrestrictedWildcard)
3808739f7b7SArgyrios Kyrtzidis       continue;
3818739f7b7SArgyrios Kyrtzidis 
3828739f7b7SArgyrios Kyrtzidis     if (Module *Restriction = Exports[I].getPointer())
3838739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.push_back(Restriction);
3848739f7b7SArgyrios Kyrtzidis     else {
3858739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.clear();
3868739f7b7SArgyrios Kyrtzidis       UnrestrictedWildcard = true;
3878739f7b7SArgyrios Kyrtzidis     }
3888739f7b7SArgyrios Kyrtzidis   }
3898739f7b7SArgyrios Kyrtzidis 
3908739f7b7SArgyrios Kyrtzidis   // If there were any wildcards, push any imported modules that were
3918739f7b7SArgyrios Kyrtzidis   // re-exported by the wildcard restriction.
3928739f7b7SArgyrios Kyrtzidis   if (!AnyWildcard)
3938739f7b7SArgyrios Kyrtzidis     return;
3948739f7b7SArgyrios Kyrtzidis 
3958739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
3968739f7b7SArgyrios Kyrtzidis     Module *Mod = Imports[I];
3978739f7b7SArgyrios Kyrtzidis     bool Acceptable = UnrestrictedWildcard;
3988739f7b7SArgyrios Kyrtzidis     if (!Acceptable) {
3998739f7b7SArgyrios Kyrtzidis       // Check whether this module meets one of the restrictions.
4008739f7b7SArgyrios Kyrtzidis       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
4018739f7b7SArgyrios Kyrtzidis         Module *Restriction = WildcardRestrictions[R];
4028739f7b7SArgyrios Kyrtzidis         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
4038739f7b7SArgyrios Kyrtzidis           Acceptable = true;
4048739f7b7SArgyrios Kyrtzidis           break;
4058739f7b7SArgyrios Kyrtzidis         }
4068739f7b7SArgyrios Kyrtzidis       }
4078739f7b7SArgyrios Kyrtzidis     }
4088739f7b7SArgyrios Kyrtzidis 
4098739f7b7SArgyrios Kyrtzidis     if (!Acceptable)
4108739f7b7SArgyrios Kyrtzidis       continue;
4118739f7b7SArgyrios Kyrtzidis 
4128739f7b7SArgyrios Kyrtzidis     Exported.push_back(Mod);
4138739f7b7SArgyrios Kyrtzidis   }
4148739f7b7SArgyrios Kyrtzidis }
4158739f7b7SArgyrios Kyrtzidis 
4160e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
4170e5d7b8cSRichard Smith   assert(VisibleModulesCache.empty() && "cache does not need building");
4180e5d7b8cSRichard Smith 
4190e5d7b8cSRichard Smith   // This module is visible to itself.
4200e5d7b8cSRichard Smith   VisibleModulesCache.insert(this);
4210e5d7b8cSRichard Smith 
4220e5d7b8cSRichard Smith   // Every imported module is visible.
423dde17e74SRichard Smith   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
424dc360d57SDmitri Gribenko   while (!Stack.empty()) {
425dc360d57SDmitri Gribenko     Module *CurrModule = Stack.pop_back_val();
426dc360d57SDmitri Gribenko 
427dde17e74SRichard Smith     // Every module transitively exported by an imported module is visible.
428dde17e74SRichard Smith     if (VisibleModulesCache.insert(CurrModule).second)
429dde17e74SRichard Smith       CurrModule->getExportedModules(Stack);
4300e5d7b8cSRichard Smith   }
4310e5d7b8cSRichard Smith }
4320e5d7b8cSRichard Smith 
4333775d811SRichard Smith void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
434de3ef502SDouglas Gregor   OS.indent(Indent);
435de3ef502SDouglas Gregor   if (IsFramework)
436de3ef502SDouglas Gregor     OS << "framework ";
437de3ef502SDouglas Gregor   if (IsExplicit)
438de3ef502SDouglas Gregor     OS << "explicit ";
4399565c75bSRichard Smith   OS << "module ";
4409565c75bSRichard Smith   printModuleId(OS, &Name, &Name + 1);
441a686e1b0SDouglas Gregor 
4427615f00eSBen Langmuir   if (IsSystem || IsExternC) {
443a686e1b0SDouglas Gregor     OS.indent(Indent + 2);
4447615f00eSBen Langmuir     if (IsSystem)
445a686e1b0SDouglas Gregor       OS << " [system]";
4467615f00eSBen Langmuir     if (IsExternC)
4477615f00eSBen Langmuir       OS << " [extern_c]";
448a686e1b0SDouglas Gregor   }
449a686e1b0SDouglas Gregor 
450a686e1b0SDouglas Gregor   OS << " {\n";
451de3ef502SDouglas Gregor 
452a3feee2aSRichard Smith   if (!Requirements.empty()) {
4531fb5c3a6SDouglas Gregor     OS.indent(Indent + 2);
4541fb5c3a6SDouglas Gregor     OS << "requires ";
455a3feee2aSRichard Smith     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
4561fb5c3a6SDouglas Gregor       if (I)
4571fb5c3a6SDouglas Gregor         OS << ", ";
458a3feee2aSRichard Smith       if (!Requirements[I].second)
459a3feee2aSRichard Smith         OS << "!";
460a3feee2aSRichard Smith       OS << Requirements[I].first;
4611fb5c3a6SDouglas Gregor     }
4621fb5c3a6SDouglas Gregor     OS << "\n";
4631fb5c3a6SDouglas Gregor   }
4641fb5c3a6SDouglas Gregor 
4652b63d15fSRichard Smith   if (Header H = getUmbrellaHeader()) {
466de3ef502SDouglas Gregor     OS.indent(Indent + 2);
467322f633cSDouglas Gregor     OS << "umbrella header \"";
4682b63d15fSRichard Smith     OS.write_escaped(H.NameAsWritten);
469de3ef502SDouglas Gregor     OS << "\"\n";
4702b63d15fSRichard Smith   } else if (DirectoryName D = getUmbrellaDir()) {
471322f633cSDouglas Gregor     OS.indent(Indent + 2);
472322f633cSDouglas Gregor     OS << "umbrella \"";
4732b63d15fSRichard Smith     OS.write_escaped(D.NameAsWritten);
474322f633cSDouglas Gregor     OS << "\"\n";
475de3ef502SDouglas Gregor   }
476de3ef502SDouglas Gregor 
47735b13eceSDouglas Gregor   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
47835b13eceSDouglas Gregor     OS.indent(Indent + 2);
47935b13eceSDouglas Gregor     OS << "config_macros ";
48035b13eceSDouglas Gregor     if (ConfigMacrosExhaustive)
4818d932427SDouglas Gregor       OS << "[exhaustive]";
48235b13eceSDouglas Gregor     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
48335b13eceSDouglas Gregor       if (I)
48435b13eceSDouglas Gregor         OS << ", ";
48535b13eceSDouglas Gregor       OS << ConfigMacros[I];
48635b13eceSDouglas Gregor     }
4878d932427SDouglas Gregor     OS << "\n";
48835b13eceSDouglas Gregor   }
48935b13eceSDouglas Gregor 
4903c1a41adSRichard Smith   struct {
491306d8920SRichard Smith     StringRef Prefix;
4923c1a41adSRichard Smith     HeaderKind Kind;
4933c1a41adSRichard Smith   } Kinds[] = {{"", HK_Normal},
4943c1a41adSRichard Smith                {"textual ", HK_Textual},
4953c1a41adSRichard Smith                {"private ", HK_Private},
4963c1a41adSRichard Smith                {"private textual ", HK_PrivateTextual},
4973c1a41adSRichard Smith                {"exclude ", HK_Excluded}};
498306d8920SRichard Smith 
499306d8920SRichard Smith   for (auto &K : Kinds) {
500040e1266SRichard Smith     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
5013c1a41adSRichard Smith     for (auto &H : Headers[K.Kind]) {
502de3ef502SDouglas Gregor       OS.indent(Indent + 2);
503306d8920SRichard Smith       OS << K.Prefix << "header \"";
5043c1a41adSRichard Smith       OS.write_escaped(H.NameAsWritten);
505040e1266SRichard Smith       OS << "\" { size " << H.Entry->getSize()
506040e1266SRichard Smith          << " mtime " << H.Entry->getModificationTime() << " }\n";
507040e1266SRichard Smith     }
508040e1266SRichard Smith   }
509040e1266SRichard Smith   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
510040e1266SRichard Smith     for (auto &U : *Unresolved) {
511040e1266SRichard Smith       OS.indent(Indent + 2);
512040e1266SRichard Smith       OS << Kinds[U.Kind].Prefix << "header \"";
513040e1266SRichard Smith       OS.write_escaped(U.FileName);
514040e1266SRichard Smith       OS << "\"";
515040e1266SRichard Smith       if (U.Size || U.ModTime) {
516040e1266SRichard Smith         OS << " {";
517040e1266SRichard Smith         if (U.Size)
518040e1266SRichard Smith           OS << " size " << *U.Size;
519040e1266SRichard Smith         if (U.ModTime)
520040e1266SRichard Smith           OS << " mtime " << *U.ModTime;
521040e1266SRichard Smith         OS << " }";
522040e1266SRichard Smith       }
523040e1266SRichard Smith       OS << "\n";
524de3ef502SDouglas Gregor     }
525b53e5483SLawrence Crowl   }
526b53e5483SLawrence Crowl 
527f0b11de2SDouglas Gregor   if (!ExportAsModule.empty()) {
528f0b11de2SDouglas Gregor     OS.indent(Indent + 2);
529f0b11de2SDouglas Gregor     OS << "export_as" << ExportAsModule << "\n";
530f0b11de2SDouglas Gregor   }
531f0b11de2SDouglas Gregor 
532eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
533de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
5349d6448b1SBen Langmuir     // Print inferred subframework modules so that we don't need to re-infer
5359d6448b1SBen Langmuir     // them (requires expensive directory iteration + stat calls) when we build
5369d6448b1SBen Langmuir     // the module. Regular inferred submodules are OK, as we need to look at all
5379d6448b1SBen Langmuir     // those header files anyway.
5389d6448b1SBen Langmuir     if (!(*MI)->IsInferred || (*MI)->IsFramework)
5393775d811SRichard Smith       (*MI)->print(OS, Indent + 2, Dump);
540de3ef502SDouglas Gregor 
54124bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
54224bb923aSDouglas Gregor     OS.indent(Indent + 2);
5438c7c8352SDouglas Gregor     OS << "export ";
5448c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
5459565c75bSRichard Smith       OS << Restriction->getFullModuleName(true);
54624bb923aSDouglas Gregor       if (Exports[I].getInt())
54724bb923aSDouglas Gregor         OS << ".*";
5488c7c8352SDouglas Gregor     } else {
5498c7c8352SDouglas Gregor       OS << "*";
5508c7c8352SDouglas Gregor     }
55124bb923aSDouglas Gregor     OS << "\n";
55224bb923aSDouglas Gregor   }
55324bb923aSDouglas Gregor 
55424bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
55524bb923aSDouglas Gregor     OS.indent(Indent + 2);
55624bb923aSDouglas Gregor     OS << "export ";
55724bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
5587f96b391SDavide Italiano     if (UnresolvedExports[I].Wildcard)
5597f96b391SDavide Italiano       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
56024bb923aSDouglas Gregor     OS << "\n";
56124bb923aSDouglas Gregor   }
56224bb923aSDouglas Gregor 
5633775d811SRichard Smith   if (Dump) {
5643775d811SRichard Smith     for (Module *M : Imports) {
5653775d811SRichard Smith       OS.indent(Indent + 2);
5663775d811SRichard Smith       llvm::errs() << "import " << M->getFullModuleName() << "\n";
5673775d811SRichard Smith     }
5683775d811SRichard Smith   }
5693775d811SRichard Smith 
570ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
571ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
572ba7f2f71SDaniel Jasper     OS << "use ";
5739565c75bSRichard Smith     OS << DirectUses[I]->getFullModuleName(true);
574ba7f2f71SDaniel Jasper     OS << "\n";
575ba7f2f71SDaniel Jasper   }
576ba7f2f71SDaniel Jasper 
577ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
578ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
579ba7f2f71SDaniel Jasper     OS << "use ";
580ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
581ba7f2f71SDaniel Jasper     OS << "\n";
582ba7f2f71SDaniel Jasper   }
583ba7f2f71SDaniel Jasper 
5846ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
5856ddfca91SDouglas Gregor     OS.indent(Indent + 2);
5866ddfca91SDouglas Gregor     OS << "link ";
5876ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
5886ddfca91SDouglas Gregor       OS << "framework ";
5896ddfca91SDouglas Gregor     OS << "\"";
5906ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
5916ddfca91SDouglas Gregor     OS << "\"";
5926ddfca91SDouglas Gregor   }
5936ddfca91SDouglas Gregor 
594fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
595fb912657SDouglas Gregor     OS.indent(Indent + 2);
596fb912657SDouglas Gregor     OS << "conflict ";
597fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
598fb912657SDouglas Gregor     OS << ", \"";
599fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
600fb912657SDouglas Gregor     OS << "\"\n";
601fb912657SDouglas Gregor   }
602fb912657SDouglas Gregor 
603fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
604fb912657SDouglas Gregor     OS.indent(Indent + 2);
605fb912657SDouglas Gregor     OS << "conflict ";
6069565c75bSRichard Smith     OS << Conflicts[I].Other->getFullModuleName(true);
607fb912657SDouglas Gregor     OS << ", \"";
608fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
609fb912657SDouglas Gregor     OS << "\"\n";
610fb912657SDouglas Gregor   }
611fb912657SDouglas Gregor 
61273441091SDouglas Gregor   if (InferSubmodules) {
61373441091SDouglas Gregor     OS.indent(Indent + 2);
61473441091SDouglas Gregor     if (InferExplicitSubmodules)
61573441091SDouglas Gregor       OS << "explicit ";
61673441091SDouglas Gregor     OS << "module * {\n";
61773441091SDouglas Gregor     if (InferExportWildcard) {
61873441091SDouglas Gregor       OS.indent(Indent + 4);
61973441091SDouglas Gregor       OS << "export *\n";
62073441091SDouglas Gregor     }
62173441091SDouglas Gregor     OS.indent(Indent + 2);
62273441091SDouglas Gregor     OS << "}\n";
62373441091SDouglas Gregor   }
62473441091SDouglas Gregor 
625de3ef502SDouglas Gregor   OS.indent(Indent);
626de3ef502SDouglas Gregor   OS << "}\n";
627de3ef502SDouglas Gregor }
628de3ef502SDouglas Gregor 
629cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const {
6303775d811SRichard Smith   print(llvm::errs(), 0, true);
631de3ef502SDouglas Gregor }
632de3ef502SDouglas Gregor 
633a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
634a7e2cc68SRichard Smith                                   VisibleCallback Vis, ConflictCallback Cb) {
6356d25fdc4SBen Langmuir   assert(Loc.isValid() && "setVisible expects a valid import location");
636a7e2cc68SRichard Smith   if (isVisible(M))
637a7e2cc68SRichard Smith     return;
638de3ef502SDouglas Gregor 
639a7e2cc68SRichard Smith   ++Generation;
640a7e2cc68SRichard Smith 
641a7e2cc68SRichard Smith   struct Visiting {
642a7e2cc68SRichard Smith     Module *M;
643a7e2cc68SRichard Smith     Visiting *ExportedBy;
644a7e2cc68SRichard Smith   };
645a7e2cc68SRichard Smith 
646a7e2cc68SRichard Smith   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
647a7e2cc68SRichard Smith     // Nothing to do for a module that's already visible.
648a7e2cc68SRichard Smith     unsigned ID = V.M->getVisibilityID();
649a7e2cc68SRichard Smith     if (ImportLocs.size() <= ID)
650a7e2cc68SRichard Smith       ImportLocs.resize(ID + 1);
651a7e2cc68SRichard Smith     else if (ImportLocs[ID].isValid())
652a7e2cc68SRichard Smith       return;
653a7e2cc68SRichard Smith 
654a7e2cc68SRichard Smith     ImportLocs[ID] = Loc;
655a7e2cc68SRichard Smith     Vis(M);
656a7e2cc68SRichard Smith 
657a7e2cc68SRichard Smith     // Make any exported modules visible.
658a7e2cc68SRichard Smith     SmallVector<Module *, 16> Exports;
659a7e2cc68SRichard Smith     V.M->getExportedModules(Exports);
660841dbda3SRichard Smith     for (Module *E : Exports) {
6616bc75023SRichard Smith       // Don't import non-importable modules.
6626bc75023SRichard Smith       if (!E->isUnimportable())
663a7e2cc68SRichard Smith         VisitModule({E, &V});
664841dbda3SRichard Smith     }
665a7e2cc68SRichard Smith 
666a7e2cc68SRichard Smith     for (auto &C : V.M->Conflicts) {
667a7e2cc68SRichard Smith       if (isVisible(C.Other)) {
668a7e2cc68SRichard Smith         llvm::SmallVector<Module*, 8> Path;
669a7e2cc68SRichard Smith         for (Visiting *I = &V; I; I = I->ExportedBy)
670a7e2cc68SRichard Smith           Path.push_back(I->M);
671a7e2cc68SRichard Smith         Cb(Path, C.Other, C.Message);
672a7e2cc68SRichard Smith       }
673a7e2cc68SRichard Smith     }
674a7e2cc68SRichard Smith   };
675a7e2cc68SRichard Smith   VisitModule({M, nullptr});
676a7e2cc68SRichard Smith }
677c915cb95SReid Kleckner 
678f4754ea0SAdrian Prantl ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
679c915cb95SReid Kleckner     : Signature(M.Signature), ClangModule(&M) {
680c915cb95SReid Kleckner   if (M.Directory)
681c915cb95SReid Kleckner     Path = M.Directory->getName();
6829f151df1SDuncan P. N. Exon Smith   if (auto File = M.getASTFile())
683c915cb95SReid Kleckner     ASTFile = File->getName();
684c915cb95SReid Kleckner }
685c915cb95SReid Kleckner 
686c915cb95SReid Kleckner std::string ASTSourceDescriptor::getModuleName() const {
687c915cb95SReid Kleckner   if (ClangModule)
688c915cb95SReid Kleckner     return ClangModule->Name;
689c915cb95SReid Kleckner   else
690c915cb95SReid Kleckner     return std::string(PCHModuleName);
691c915cb95SReid Kleckner }
692