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
Module(StringRef Name,SourceLocation DefinitionLoc,Module * Parent,bool IsFramework,bool IsExplicit,unsigned VisibilityID)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
~Module()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
isPlatformEnvironment(const TargetInfo & Target,StringRef Feature)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.
hasFeature(StringRef Feature,const LangOptions & LangOpts,const TargetInfo & Target)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)
1240e9373a6SKazu Hirata HasFeature = llvm::is_contained(LangOpts.ModuleFeatures, Feature);
125532d2104SBen Langmuir return HasFeature;
1261fb5c3a6SDouglas Gregor }
1271fb5c3a6SDouglas Gregor
isUnimportable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,Module * & ShadowingModule) const128fc76b4adSRichard Smith bool Module::isUnimportable(const LangOptions &LangOpts,
129fc76b4adSRichard Smith const TargetInfo &Target, Requirement &Req,
130fc76b4adSRichard Smith Module *&ShadowingModule) const {
131fc76b4adSRichard Smith if (!IsUnimportable)
132fc76b4adSRichard Smith return false;
133fc76b4adSRichard Smith
134fc76b4adSRichard Smith for (const Module *Current = this; Current; Current = Current->Parent) {
135fc76b4adSRichard Smith if (Current->ShadowingModule) {
136fc76b4adSRichard Smith ShadowingModule = Current->ShadowingModule;
137fc76b4adSRichard Smith return true;
138fc76b4adSRichard Smith }
139fc76b4adSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
140fc76b4adSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
141fc76b4adSRichard Smith Current->Requirements[I].second) {
142fc76b4adSRichard Smith Req = Current->Requirements[I];
143fc76b4adSRichard Smith return true;
144fc76b4adSRichard Smith }
145fc76b4adSRichard Smith }
146fc76b4adSRichard Smith }
147fc76b4adSRichard Smith
148fc76b4adSRichard Smith llvm_unreachable("could not find a reason why module is unimportable");
149fc76b4adSRichard Smith }
150fc76b4adSRichard Smith
isAvailable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,UnresolvedHeaderDirective & MissingHeader,Module * & ShadowingModule) const1513c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
1523c1a41adSRichard Smith Requirement &Req,
1538587dfd9SBruno Cardoso Lopes UnresolvedHeaderDirective &MissingHeader,
1548587dfd9SBruno Cardoso Lopes Module *&ShadowingModule) const {
1551fb5c3a6SDouglas Gregor if (IsAvailable)
1561fb5c3a6SDouglas Gregor return true;
1571fb5c3a6SDouglas Gregor
158fc76b4adSRichard Smith if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
159fc76b4adSRichard Smith return false;
160fc76b4adSRichard Smith
161fc76b4adSRichard Smith // FIXME: All missing headers are listed on the top-level module. Should we
162fc76b4adSRichard Smith // just look there?
1631fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) {
16475a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) {
16575a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front();
16675a7e435SBen Langmuir return false;
16775a7e435SBen Langmuir }
1681fb5c3a6SDouglas Gregor }
1691fb5c3a6SDouglas Gregor
1701fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable");
1711fb5c3a6SDouglas Gregor }
1721fb5c3a6SDouglas Gregor
isSubModuleOf(const Module * Other) const17362bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const {
174b907ad53SAdrian Prantl for (auto *Parent = this; Parent; Parent = Parent->Parent) {
175b907ad53SAdrian Prantl if (Parent == Other)
176f5eedd05SDouglas Gregor return true;
177b907ad53SAdrian Prantl }
178f5eedd05SDouglas Gregor return false;
179f5eedd05SDouglas Gregor }
180f5eedd05SDouglas Gregor
getTopLevelModule() const18173441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
18273441091SDouglas Gregor const Module *Result = this;
18373441091SDouglas Gregor while (Result->Parent)
18473441091SDouglas Gregor Result = Result->Parent;
18573441091SDouglas Gregor
18673441091SDouglas Gregor return Result;
18773441091SDouglas Gregor }
18873441091SDouglas Gregor
getModuleNameFromComponent(const std::pair<std::string,SourceLocation> & IdComponent)1899565c75bSRichard Smith static StringRef getModuleNameFromComponent(
1909565c75bSRichard Smith const std::pair<std::string, SourceLocation> &IdComponent) {
1919565c75bSRichard Smith return IdComponent.first;
1929565c75bSRichard Smith }
193918e0ca7SEugene Zelenko
getModuleNameFromComponent(StringRef R)1949565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; }
1959565c75bSRichard Smith
1969565c75bSRichard Smith template<typename InputIter>
printModuleId(raw_ostream & OS,InputIter Begin,InputIter End,bool AllowStringLiterals=true)1979565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
1989565c75bSRichard Smith bool AllowStringLiterals = true) {
1999565c75bSRichard Smith for (InputIter It = Begin; It != End; ++It) {
2009565c75bSRichard Smith if (It != Begin)
2019565c75bSRichard Smith OS << ".";
2029565c75bSRichard Smith
2039565c75bSRichard Smith StringRef Name = getModuleNameFromComponent(*It);
204601102d2SCorentin Jabot if (!AllowStringLiterals || isValidAsciiIdentifier(Name))
2059565c75bSRichard Smith OS << Name;
2069565c75bSRichard Smith else {
2079565c75bSRichard Smith OS << '"';
2089565c75bSRichard Smith OS.write_escaped(Name);
2099565c75bSRichard Smith OS << '"';
2109565c75bSRichard Smith }
2119565c75bSRichard Smith }
2129565c75bSRichard Smith }
2139565c75bSRichard Smith
2149565c75bSRichard Smith template<typename Container>
printModuleId(raw_ostream & OS,const Container & C)2159565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) {
2169565c75bSRichard Smith return printModuleId(OS, C.begin(), C.end());
2179565c75bSRichard Smith }
2189565c75bSRichard Smith
getFullModuleName(bool AllowStringLiterals) const2199565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const {
220f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names;
221de3ef502SDouglas Gregor
222de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost).
223de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent)
224de3ef502SDouglas Gregor Names.push_back(M->Name);
225de3ef502SDouglas Gregor
226de3ef502SDouglas Gregor std::string Result;
227de3ef502SDouglas Gregor
2289565c75bSRichard Smith llvm::raw_string_ostream Out(Result);
2299565c75bSRichard Smith printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
2309565c75bSRichard Smith Out.flush();
231de3ef502SDouglas Gregor
232de3ef502SDouglas Gregor return Result;
233de3ef502SDouglas Gregor }
234de3ef502SDouglas Gregor
fullModuleNameIs(ArrayRef<StringRef> nameParts) const2357ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
2367ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) {
2377ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back())
2387ff29148SBen Langmuir return false;
2397ff29148SBen Langmuir nameParts = nameParts.drop_back();
2407ff29148SBen Langmuir }
2417ff29148SBen Langmuir return nameParts.empty();
2427ff29148SBen Langmuir }
2437ff29148SBen Langmuir
getUmbrellaDir() const2442b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const {
2452b63d15fSRichard Smith if (Header U = getUmbrellaHeader())
246d3676d4bSMichael Spencer return {"", "", U.Entry->getDir()};
24773141fa9SDouglas Gregor
248d3676d4bSMichael Spencer return {UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
249d3676d4bSMichael Spencer Umbrella.dyn_cast<const DirectoryEntry *>()};
250bc883665SReid Kleckner }
251bc883665SReid Kleckner
addTopHeader(const FileEntry * File)252bc883665SReid Kleckner void Module::addTopHeader(const FileEntry *File) {
253bc883665SReid Kleckner assert(File);
254bc883665SReid Kleckner TopHeaders.insert(File);
25573141fa9SDouglas Gregor }
25673141fa9SDouglas Gregor
getTopHeaders(FileManager & FileMgr)2573c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
2583c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) {
2593c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator
2603c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
2618d323d15SHarlan Haskins if (auto FE = FileMgr.getFile(*I))
2628d323d15SHarlan Haskins TopHeaders.insert(*FE);
2633c5305c1SArgyrios Kyrtzidis }
2643c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear();
2653c5305c1SArgyrios Kyrtzidis }
2663c5305c1SArgyrios Kyrtzidis
2673c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
2683c5305c1SArgyrios Kyrtzidis }
2693c5305c1SArgyrios Kyrtzidis
directlyUses(const Module * Requested)270*b45888e9SJan Svoboda bool Module::directlyUses(const Module *Requested) {
2718f4d3ff1SRichard Smith auto *Top = getTopLevelModule();
2728f4d3ff1SRichard Smith
2738f4d3ff1SRichard Smith // A top-level module implicitly uses itself.
2748f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top))
2758f4d3ff1SRichard Smith return true;
2768f4d3ff1SRichard Smith
2778f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses)
2788f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use))
2798f4d3ff1SRichard Smith return true;
280ed84df00SBruno Cardoso Lopes
281ed84df00SBruno Cardoso Lopes // Anyone is allowed to use our builtin stddef.h and its accompanying module.
282ed84df00SBruno Cardoso Lopes if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
283ed84df00SBruno Cardoso Lopes return true;
284ed84df00SBruno Cardoso Lopes
285*b45888e9SJan Svoboda if (NoUndeclaredIncludes)
286*b45888e9SJan Svoboda UndeclaredUses.insert(Requested);
287*b45888e9SJan Svoboda
2888f4d3ff1SRichard Smith return false;
2898f4d3ff1SRichard Smith }
2908f4d3ff1SRichard Smith
addRequirement(StringRef Feature,bool RequiredState,const LangOptions & LangOpts,const TargetInfo & Target)291a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
292a3feee2aSRichard Smith const LangOptions &LangOpts,
29389929282SDouglas Gregor const TargetInfo &Target) {
294bb39b529SBenjamin Kramer Requirements.push_back(Requirement(std::string(Feature), RequiredState));
2951fb5c3a6SDouglas Gregor
2961fb5c3a6SDouglas Gregor // If this feature is currently available, we're done.
297a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState)
2981fb5c3a6SDouglas Gregor return;
2991fb5c3a6SDouglas Gregor
300fc76b4adSRichard Smith markUnavailable(/*Unimportable*/true);
301ec8c9752SBen Langmuir }
302ec8c9752SBen Langmuir
markUnavailable(bool Unimportable)303fc76b4adSRichard Smith void Module::markUnavailable(bool Unimportable) {
304fc76b4adSRichard Smith auto needUpdate = [Unimportable](Module *M) {
305fc76b4adSRichard Smith return M->IsAvailable || (!M->IsUnimportable && Unimportable);
30675a7e435SBen Langmuir };
30775a7e435SBen Langmuir
30875a7e435SBen Langmuir if (!needUpdate(this))
3091fb5c3a6SDouglas Gregor return;
3101fb5c3a6SDouglas Gregor
311f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack;
3121fb5c3a6SDouglas Gregor Stack.push_back(this);
3131fb5c3a6SDouglas Gregor while (!Stack.empty()) {
3141fb5c3a6SDouglas Gregor Module *Current = Stack.back();
3151fb5c3a6SDouglas Gregor Stack.pop_back();
3161fb5c3a6SDouglas Gregor
31775a7e435SBen Langmuir if (!needUpdate(Current))
3181fb5c3a6SDouglas Gregor continue;
3191fb5c3a6SDouglas Gregor
3201fb5c3a6SDouglas Gregor Current->IsAvailable = false;
321fc76b4adSRichard Smith Current->IsUnimportable |= Unimportable;
322eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(),
323eb90e830SDouglas Gregor SubEnd = Current->submodule_end();
3241fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) {
32575a7e435SBen Langmuir if (needUpdate(*Sub))
326eb90e830SDouglas Gregor Stack.push_back(*Sub);
3271fb5c3a6SDouglas Gregor }
3281fb5c3a6SDouglas Gregor }
3291fb5c3a6SDouglas Gregor }
3301fb5c3a6SDouglas Gregor
findSubmodule(StringRef Name) const331eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
332eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
333eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end())
334f1186c5aSCraig Topper return nullptr;
335eb90e830SDouglas Gregor
336eb90e830SDouglas Gregor return SubModules[Pos->getValue()];
337eb90e830SDouglas Gregor }
338eb90e830SDouglas Gregor
findOrInferSubmodule(StringRef Name)33989e58ddbSDavid Blaikie Module *Module::findOrInferSubmodule(StringRef Name) {
34089e58ddbSDavid Blaikie llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
34189e58ddbSDavid Blaikie if (Pos != SubModuleIndex.end())
34289e58ddbSDavid Blaikie return SubModules[Pos->getValue()];
34389e58ddbSDavid Blaikie if (!InferSubmodules)
34489e58ddbSDavid Blaikie return nullptr;
34589e58ddbSDavid Blaikie Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
34689e58ddbSDavid Blaikie Result->InferExplicitSubmodules = InferExplicitSubmodules;
34789e58ddbSDavid Blaikie Result->InferSubmodules = InferSubmodules;
34889e58ddbSDavid Blaikie Result->InferExportWildcard = InferExportWildcard;
34989e58ddbSDavid Blaikie if (Result->InferExportWildcard)
35089e58ddbSDavid Blaikie Result->Exports.push_back(Module::ExportDecl(nullptr, true));
35189e58ddbSDavid Blaikie return Result;
35289e58ddbSDavid Blaikie }
35389e58ddbSDavid Blaikie
getExportedModules(SmallVectorImpl<Module * > & Exported) const3548739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
355e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported.
356e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(),
357e9bcf5b7SDmitri Gribenko E = SubModules.end();
358e9bcf5b7SDmitri Gribenko I != E; ++I) {
359e9bcf5b7SDmitri Gribenko Module *Mod = *I;
360e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit)
361e9bcf5b7SDmitri Gribenko Exported.push_back(Mod);
362e9bcf5b7SDmitri Gribenko }
363e9bcf5b7SDmitri Gribenko
364e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules.
3658739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false;
3668739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false;
3678739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions;
3688739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
3698739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer();
3708739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) {
3718739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved.
3728739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod);
3738739f7b7SArgyrios Kyrtzidis
3748739f7b7SArgyrios Kyrtzidis continue;
3758739f7b7SArgyrios Kyrtzidis }
3768739f7b7SArgyrios Kyrtzidis
3778739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match
3788739f7b7SArgyrios Kyrtzidis // the given pattern.
3798739f7b7SArgyrios Kyrtzidis AnyWildcard = true;
3808739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard)
3818739f7b7SArgyrios Kyrtzidis continue;
3828739f7b7SArgyrios Kyrtzidis
3838739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer())
3848739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction);
3858739f7b7SArgyrios Kyrtzidis else {
3868739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear();
3878739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true;
3888739f7b7SArgyrios Kyrtzidis }
3898739f7b7SArgyrios Kyrtzidis }
3908739f7b7SArgyrios Kyrtzidis
3918739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were
3928739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction.
3938739f7b7SArgyrios Kyrtzidis if (!AnyWildcard)
3948739f7b7SArgyrios Kyrtzidis return;
3958739f7b7SArgyrios Kyrtzidis
3968739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
3978739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I];
3988739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard;
3998739f7b7SArgyrios Kyrtzidis if (!Acceptable) {
4008739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions.
4018739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
4028739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R];
4038739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
4048739f7b7SArgyrios Kyrtzidis Acceptable = true;
4058739f7b7SArgyrios Kyrtzidis break;
4068739f7b7SArgyrios Kyrtzidis }
4078739f7b7SArgyrios Kyrtzidis }
4088739f7b7SArgyrios Kyrtzidis }
4098739f7b7SArgyrios Kyrtzidis
4108739f7b7SArgyrios Kyrtzidis if (!Acceptable)
4118739f7b7SArgyrios Kyrtzidis continue;
4128739f7b7SArgyrios Kyrtzidis
4138739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod);
4148739f7b7SArgyrios Kyrtzidis }
4158739f7b7SArgyrios Kyrtzidis }
4168739f7b7SArgyrios Kyrtzidis
buildVisibleModulesCache() const4170e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
4180e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building");
4190e5d7b8cSRichard Smith
4200e5d7b8cSRichard Smith // This module is visible to itself.
4210e5d7b8cSRichard Smith VisibleModulesCache.insert(this);
4220e5d7b8cSRichard Smith
4230e5d7b8cSRichard Smith // Every imported module is visible.
424dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
425dc360d57SDmitri Gribenko while (!Stack.empty()) {
426dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val();
427dc360d57SDmitri Gribenko
428dde17e74SRichard Smith // Every module transitively exported by an imported module is visible.
429dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second)
430dde17e74SRichard Smith CurrModule->getExportedModules(Stack);
4310e5d7b8cSRichard Smith }
4320e5d7b8cSRichard Smith }
4330e5d7b8cSRichard Smith
print(raw_ostream & OS,unsigned Indent,bool Dump) const4343775d811SRichard Smith void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
435de3ef502SDouglas Gregor OS.indent(Indent);
436de3ef502SDouglas Gregor if (IsFramework)
437de3ef502SDouglas Gregor OS << "framework ";
438de3ef502SDouglas Gregor if (IsExplicit)
439de3ef502SDouglas Gregor OS << "explicit ";
4409565c75bSRichard Smith OS << "module ";
4419565c75bSRichard Smith printModuleId(OS, &Name, &Name + 1);
442a686e1b0SDouglas Gregor
4437615f00eSBen Langmuir if (IsSystem || IsExternC) {
444a686e1b0SDouglas Gregor OS.indent(Indent + 2);
4457615f00eSBen Langmuir if (IsSystem)
446a686e1b0SDouglas Gregor OS << " [system]";
4477615f00eSBen Langmuir if (IsExternC)
4487615f00eSBen Langmuir OS << " [extern_c]";
449a686e1b0SDouglas Gregor }
450a686e1b0SDouglas Gregor
451a686e1b0SDouglas Gregor OS << " {\n";
452de3ef502SDouglas Gregor
453a3feee2aSRichard Smith if (!Requirements.empty()) {
4541fb5c3a6SDouglas Gregor OS.indent(Indent + 2);
4551fb5c3a6SDouglas Gregor OS << "requires ";
456a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
4571fb5c3a6SDouglas Gregor if (I)
4581fb5c3a6SDouglas Gregor OS << ", ";
459a3feee2aSRichard Smith if (!Requirements[I].second)
460a3feee2aSRichard Smith OS << "!";
461a3feee2aSRichard Smith OS << Requirements[I].first;
4621fb5c3a6SDouglas Gregor }
4631fb5c3a6SDouglas Gregor OS << "\n";
4641fb5c3a6SDouglas Gregor }
4651fb5c3a6SDouglas Gregor
4662b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) {
467de3ef502SDouglas Gregor OS.indent(Indent + 2);
468322f633cSDouglas Gregor OS << "umbrella header \"";
4692b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten);
470de3ef502SDouglas Gregor OS << "\"\n";
4712b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) {
472322f633cSDouglas Gregor OS.indent(Indent + 2);
473322f633cSDouglas Gregor OS << "umbrella \"";
4742b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten);
475322f633cSDouglas Gregor OS << "\"\n";
476de3ef502SDouglas Gregor }
477de3ef502SDouglas Gregor
47835b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
47935b13eceSDouglas Gregor OS.indent(Indent + 2);
48035b13eceSDouglas Gregor OS << "config_macros ";
48135b13eceSDouglas Gregor if (ConfigMacrosExhaustive)
4828d932427SDouglas Gregor OS << "[exhaustive]";
48335b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
48435b13eceSDouglas Gregor if (I)
48535b13eceSDouglas Gregor OS << ", ";
48635b13eceSDouglas Gregor OS << ConfigMacros[I];
48735b13eceSDouglas Gregor }
4888d932427SDouglas Gregor OS << "\n";
48935b13eceSDouglas Gregor }
49035b13eceSDouglas Gregor
4913c1a41adSRichard Smith struct {
492306d8920SRichard Smith StringRef Prefix;
4933c1a41adSRichard Smith HeaderKind Kind;
4943c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal},
4953c1a41adSRichard Smith {"textual ", HK_Textual},
4963c1a41adSRichard Smith {"private ", HK_Private},
4973c1a41adSRichard Smith {"private textual ", HK_PrivateTextual},
4983c1a41adSRichard Smith {"exclude ", HK_Excluded}};
499306d8920SRichard Smith
500306d8920SRichard Smith for (auto &K : Kinds) {
501040e1266SRichard Smith assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
5023c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) {
503de3ef502SDouglas Gregor OS.indent(Indent + 2);
504306d8920SRichard Smith OS << K.Prefix << "header \"";
5053c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten);
506040e1266SRichard Smith OS << "\" { size " << H.Entry->getSize()
507040e1266SRichard Smith << " mtime " << H.Entry->getModificationTime() << " }\n";
508040e1266SRichard Smith }
509040e1266SRichard Smith }
510040e1266SRichard Smith for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
511040e1266SRichard Smith for (auto &U : *Unresolved) {
512040e1266SRichard Smith OS.indent(Indent + 2);
513040e1266SRichard Smith OS << Kinds[U.Kind].Prefix << "header \"";
514040e1266SRichard Smith OS.write_escaped(U.FileName);
515040e1266SRichard Smith OS << "\"";
516040e1266SRichard Smith if (U.Size || U.ModTime) {
517040e1266SRichard Smith OS << " {";
518040e1266SRichard Smith if (U.Size)
519040e1266SRichard Smith OS << " size " << *U.Size;
520040e1266SRichard Smith if (U.ModTime)
521040e1266SRichard Smith OS << " mtime " << *U.ModTime;
522040e1266SRichard Smith OS << " }";
523040e1266SRichard Smith }
524040e1266SRichard Smith OS << "\n";
525de3ef502SDouglas Gregor }
526b53e5483SLawrence Crowl }
527b53e5483SLawrence Crowl
528f0b11de2SDouglas Gregor if (!ExportAsModule.empty()) {
529f0b11de2SDouglas Gregor OS.indent(Indent + 2);
530f0b11de2SDouglas Gregor OS << "export_as" << ExportAsModule << "\n";
531f0b11de2SDouglas Gregor }
532f0b11de2SDouglas Gregor
533eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
534de3ef502SDouglas Gregor MI != MIEnd; ++MI)
5359d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer
5369d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build
5379d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all
5389d6448b1SBen Langmuir // those header files anyway.
5399d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework)
5403775d811SRichard Smith (*MI)->print(OS, Indent + 2, Dump);
541de3ef502SDouglas Gregor
54224bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
54324bb923aSDouglas Gregor OS.indent(Indent + 2);
5448c7c8352SDouglas Gregor OS << "export ";
5458c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) {
5469565c75bSRichard Smith OS << Restriction->getFullModuleName(true);
54724bb923aSDouglas Gregor if (Exports[I].getInt())
54824bb923aSDouglas Gregor OS << ".*";
5498c7c8352SDouglas Gregor } else {
5508c7c8352SDouglas Gregor OS << "*";
5518c7c8352SDouglas Gregor }
55224bb923aSDouglas Gregor OS << "\n";
55324bb923aSDouglas Gregor }
55424bb923aSDouglas Gregor
55524bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
55624bb923aSDouglas Gregor OS.indent(Indent + 2);
55724bb923aSDouglas Gregor OS << "export ";
55824bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id);
5597f96b391SDavide Italiano if (UnresolvedExports[I].Wildcard)
5607f96b391SDavide Italiano OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
56124bb923aSDouglas Gregor OS << "\n";
56224bb923aSDouglas Gregor }
56324bb923aSDouglas Gregor
5643775d811SRichard Smith if (Dump) {
5653775d811SRichard Smith for (Module *M : Imports) {
5663775d811SRichard Smith OS.indent(Indent + 2);
5673775d811SRichard Smith llvm::errs() << "import " << M->getFullModuleName() << "\n";
5683775d811SRichard Smith }
5693775d811SRichard Smith }
5703775d811SRichard Smith
571ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
572ba7f2f71SDaniel Jasper OS.indent(Indent + 2);
573ba7f2f71SDaniel Jasper OS << "use ";
5749565c75bSRichard Smith OS << DirectUses[I]->getFullModuleName(true);
575ba7f2f71SDaniel Jasper OS << "\n";
576ba7f2f71SDaniel Jasper }
577ba7f2f71SDaniel Jasper
578ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
579ba7f2f71SDaniel Jasper OS.indent(Indent + 2);
580ba7f2f71SDaniel Jasper OS << "use ";
581ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]);
582ba7f2f71SDaniel Jasper OS << "\n";
583ba7f2f71SDaniel Jasper }
584ba7f2f71SDaniel Jasper
5856ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
5866ddfca91SDouglas Gregor OS.indent(Indent + 2);
5876ddfca91SDouglas Gregor OS << "link ";
5886ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework)
5896ddfca91SDouglas Gregor OS << "framework ";
5906ddfca91SDouglas Gregor OS << "\"";
5916ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library);
5926ddfca91SDouglas Gregor OS << "\"";
5936ddfca91SDouglas Gregor }
5946ddfca91SDouglas Gregor
595fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
596fb912657SDouglas Gregor OS.indent(Indent + 2);
597fb912657SDouglas Gregor OS << "conflict ";
598fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id);
599fb912657SDouglas Gregor OS << ", \"";
600fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message);
601fb912657SDouglas Gregor OS << "\"\n";
602fb912657SDouglas Gregor }
603fb912657SDouglas Gregor
604fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
605fb912657SDouglas Gregor OS.indent(Indent + 2);
606fb912657SDouglas Gregor OS << "conflict ";
6079565c75bSRichard Smith OS << Conflicts[I].Other->getFullModuleName(true);
608fb912657SDouglas Gregor OS << ", \"";
609fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message);
610fb912657SDouglas Gregor OS << "\"\n";
611fb912657SDouglas Gregor }
612fb912657SDouglas Gregor
61373441091SDouglas Gregor if (InferSubmodules) {
61473441091SDouglas Gregor OS.indent(Indent + 2);
61573441091SDouglas Gregor if (InferExplicitSubmodules)
61673441091SDouglas Gregor OS << "explicit ";
61773441091SDouglas Gregor OS << "module * {\n";
61873441091SDouglas Gregor if (InferExportWildcard) {
61973441091SDouglas Gregor OS.indent(Indent + 4);
62073441091SDouglas Gregor OS << "export *\n";
62173441091SDouglas Gregor }
62273441091SDouglas Gregor OS.indent(Indent + 2);
62373441091SDouglas Gregor OS << "}\n";
62473441091SDouglas Gregor }
62573441091SDouglas Gregor
626de3ef502SDouglas Gregor OS.indent(Indent);
627de3ef502SDouglas Gregor OS << "}\n";
628de3ef502SDouglas Gregor }
629de3ef502SDouglas Gregor
dump() const630cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const {
6313775d811SRichard Smith print(llvm::errs(), 0, true);
632de3ef502SDouglas Gregor }
633de3ef502SDouglas Gregor
setVisible(Module * M,SourceLocation Loc,VisibleCallback Vis,ConflictCallback Cb)634a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
635a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) {
6366d25fdc4SBen Langmuir assert(Loc.isValid() && "setVisible expects a valid import location");
637a7e2cc68SRichard Smith if (isVisible(M))
638a7e2cc68SRichard Smith return;
639de3ef502SDouglas Gregor
640a7e2cc68SRichard Smith ++Generation;
641a7e2cc68SRichard Smith
642a7e2cc68SRichard Smith struct Visiting {
643a7e2cc68SRichard Smith Module *M;
644a7e2cc68SRichard Smith Visiting *ExportedBy;
645a7e2cc68SRichard Smith };
646a7e2cc68SRichard Smith
647a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) {
648a7e2cc68SRichard Smith // Nothing to do for a module that's already visible.
649a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID();
650a7e2cc68SRichard Smith if (ImportLocs.size() <= ID)
651a7e2cc68SRichard Smith ImportLocs.resize(ID + 1);
652a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid())
653a7e2cc68SRichard Smith return;
654a7e2cc68SRichard Smith
655a7e2cc68SRichard Smith ImportLocs[ID] = Loc;
656a7e2cc68SRichard Smith Vis(M);
657a7e2cc68SRichard Smith
658a7e2cc68SRichard Smith // Make any exported modules visible.
659a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports;
660a7e2cc68SRichard Smith V.M->getExportedModules(Exports);
661841dbda3SRichard Smith for (Module *E : Exports) {
6626bc75023SRichard Smith // Don't import non-importable modules.
6636bc75023SRichard Smith if (!E->isUnimportable())
664a7e2cc68SRichard Smith VisitModule({E, &V});
665841dbda3SRichard Smith }
666a7e2cc68SRichard Smith
667a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) {
668a7e2cc68SRichard Smith if (isVisible(C.Other)) {
669a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path;
670a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy)
671a7e2cc68SRichard Smith Path.push_back(I->M);
672a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message);
673a7e2cc68SRichard Smith }
674a7e2cc68SRichard Smith }
675a7e2cc68SRichard Smith };
676a7e2cc68SRichard Smith VisitModule({M, nullptr});
677a7e2cc68SRichard Smith }
678c915cb95SReid Kleckner
ASTSourceDescriptor(Module & M)679f4754ea0SAdrian Prantl ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
680c915cb95SReid Kleckner : Signature(M.Signature), ClangModule(&M) {
681c915cb95SReid Kleckner if (M.Directory)
682c915cb95SReid Kleckner Path = M.Directory->getName();
6839f151df1SDuncan P. N. Exon Smith if (auto File = M.getASTFile())
684c915cb95SReid Kleckner ASTFile = File->getName();
685c915cb95SReid Kleckner }
686c915cb95SReid Kleckner
getModuleName() const687c915cb95SReid Kleckner std::string ASTSourceDescriptor::getModuleName() const {
688c915cb95SReid Kleckner if (ClangModule)
689c915cb95SReid Kleckner return ClangModule->Name;
690c915cb95SReid Kleckner else
691c915cb95SReid Kleckner return std::string(PCHModuleName);
692c915cb95SReid Kleckner }
693