xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/Basic/Module.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===- Module.cpp - Describe a module -------------------------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file defines the Module class, which describes a module in the source
107330f729Sjoerg // code.
117330f729Sjoerg //
127330f729Sjoerg //===----------------------------------------------------------------------===//
137330f729Sjoerg 
147330f729Sjoerg #include "clang/Basic/Module.h"
157330f729Sjoerg #include "clang/Basic/CharInfo.h"
167330f729Sjoerg #include "clang/Basic/FileManager.h"
177330f729Sjoerg #include "clang/Basic/LangOptions.h"
187330f729Sjoerg #include "clang/Basic/SourceLocation.h"
197330f729Sjoerg #include "clang/Basic/TargetInfo.h"
207330f729Sjoerg #include "llvm/ADT/ArrayRef.h"
217330f729Sjoerg #include "llvm/ADT/SmallVector.h"
227330f729Sjoerg #include "llvm/ADT/StringMap.h"
237330f729Sjoerg #include "llvm/ADT/StringRef.h"
247330f729Sjoerg #include "llvm/ADT/StringSwitch.h"
257330f729Sjoerg #include "llvm/Support/Compiler.h"
267330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
277330f729Sjoerg #include "llvm/Support/raw_ostream.h"
287330f729Sjoerg #include <algorithm>
297330f729Sjoerg #include <cassert>
307330f729Sjoerg #include <functional>
317330f729Sjoerg #include <string>
327330f729Sjoerg #include <utility>
337330f729Sjoerg #include <vector>
347330f729Sjoerg 
357330f729Sjoerg using namespace clang;
367330f729Sjoerg 
Module(StringRef Name,SourceLocation DefinitionLoc,Module * Parent,bool IsFramework,bool IsExplicit,unsigned VisibilityID)377330f729Sjoerg Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
387330f729Sjoerg                bool IsFramework, bool IsExplicit, unsigned VisibilityID)
397330f729Sjoerg     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
40*e038c9c4Sjoerg       VisibilityID(VisibilityID), IsUnimportable(false),
417330f729Sjoerg       HasIncompatibleModuleFile(false), IsAvailable(true),
427330f729Sjoerg       IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
437330f729Sjoerg       IsSystem(false), IsExternC(false), IsInferred(false),
447330f729Sjoerg       InferSubmodules(false), InferExplicitSubmodules(false),
457330f729Sjoerg       InferExportWildcard(false), ConfigMacrosExhaustive(false),
467330f729Sjoerg       NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
477330f729Sjoerg       NameVisibility(Hidden) {
487330f729Sjoerg   if (Parent) {
49*e038c9c4Sjoerg     IsAvailable = Parent->isAvailable();
50*e038c9c4Sjoerg     IsUnimportable = Parent->isUnimportable();
51*e038c9c4Sjoerg     IsSystem = Parent->IsSystem;
52*e038c9c4Sjoerg     IsExternC = Parent->IsExternC;
53*e038c9c4Sjoerg     NoUndeclaredIncludes = Parent->NoUndeclaredIncludes;
54*e038c9c4Sjoerg     ModuleMapIsPrivate = Parent->ModuleMapIsPrivate;
557330f729Sjoerg 
567330f729Sjoerg     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
577330f729Sjoerg     Parent->SubModules.push_back(this);
587330f729Sjoerg   }
597330f729Sjoerg }
607330f729Sjoerg 
~Module()617330f729Sjoerg Module::~Module() {
627330f729Sjoerg   for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
637330f729Sjoerg        I != IEnd; ++I) {
647330f729Sjoerg     delete *I;
657330f729Sjoerg   }
667330f729Sjoerg }
677330f729Sjoerg 
isPlatformEnvironment(const TargetInfo & Target,StringRef Feature)687330f729Sjoerg static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
697330f729Sjoerg   StringRef Platform = Target.getPlatformName();
707330f729Sjoerg   StringRef Env = Target.getTriple().getEnvironmentName();
717330f729Sjoerg 
727330f729Sjoerg   // Attempt to match platform and environment.
737330f729Sjoerg   if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
747330f729Sjoerg       Env == Feature)
757330f729Sjoerg     return true;
767330f729Sjoerg 
777330f729Sjoerg   auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
78*e038c9c4Sjoerg     auto Pos = LHS.find('-');
797330f729Sjoerg     if (Pos == StringRef::npos)
807330f729Sjoerg       return false;
817330f729Sjoerg     SmallString<128> NewLHS = LHS.slice(0, Pos);
827330f729Sjoerg     NewLHS += LHS.slice(Pos+1, LHS.size());
837330f729Sjoerg     return NewLHS == RHS;
847330f729Sjoerg   };
857330f729Sjoerg 
867330f729Sjoerg   SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
877330f729Sjoerg   // Darwin has different but equivalent variants for simulators, example:
887330f729Sjoerg   //   1. x86_64-apple-ios-simulator
897330f729Sjoerg   //   2. x86_64-apple-iossimulator
907330f729Sjoerg   // where both are valid examples of the same platform+environment but in the
917330f729Sjoerg   // variant (2) the simulator is hardcoded as part of the platform name. Both
927330f729Sjoerg   // forms above should match for "iossimulator" requirement.
937330f729Sjoerg   if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator"))
947330f729Sjoerg     return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
957330f729Sjoerg 
967330f729Sjoerg   return PlatformEnv == Feature;
977330f729Sjoerg }
987330f729Sjoerg 
997330f729Sjoerg /// Determine whether a translation unit built using the current
1007330f729Sjoerg /// language options has the given feature.
hasFeature(StringRef Feature,const LangOptions & LangOpts,const TargetInfo & Target)1017330f729Sjoerg static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
1027330f729Sjoerg                        const TargetInfo &Target) {
1037330f729Sjoerg   bool HasFeature = llvm::StringSwitch<bool>(Feature)
1047330f729Sjoerg                         .Case("altivec", LangOpts.AltiVec)
1057330f729Sjoerg                         .Case("blocks", LangOpts.Blocks)
1067330f729Sjoerg                         .Case("coroutines", LangOpts.Coroutines)
1077330f729Sjoerg                         .Case("cplusplus", LangOpts.CPlusPlus)
1087330f729Sjoerg                         .Case("cplusplus11", LangOpts.CPlusPlus11)
1097330f729Sjoerg                         .Case("cplusplus14", LangOpts.CPlusPlus14)
1107330f729Sjoerg                         .Case("cplusplus17", LangOpts.CPlusPlus17)
1117330f729Sjoerg                         .Case("c99", LangOpts.C99)
1127330f729Sjoerg                         .Case("c11", LangOpts.C11)
1137330f729Sjoerg                         .Case("c17", LangOpts.C17)
1147330f729Sjoerg                         .Case("freestanding", LangOpts.Freestanding)
1157330f729Sjoerg                         .Case("gnuinlineasm", LangOpts.GNUAsm)
1167330f729Sjoerg                         .Case("objc", LangOpts.ObjC)
1177330f729Sjoerg                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
1187330f729Sjoerg                         .Case("opencl", LangOpts.OpenCL)
1197330f729Sjoerg                         .Case("tls", Target.isTLSSupported())
1207330f729Sjoerg                         .Case("zvector", LangOpts.ZVector)
1217330f729Sjoerg                         .Default(Target.hasFeature(Feature) ||
1227330f729Sjoerg                                  isPlatformEnvironment(Target, Feature));
1237330f729Sjoerg   if (!HasFeature)
1247330f729Sjoerg     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
1257330f729Sjoerg                            LangOpts.ModuleFeatures.end(),
1267330f729Sjoerg                            Feature) != LangOpts.ModuleFeatures.end();
1277330f729Sjoerg   return HasFeature;
1287330f729Sjoerg }
1297330f729Sjoerg 
isUnimportable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,Module * & ShadowingModule) const130*e038c9c4Sjoerg bool Module::isUnimportable(const LangOptions &LangOpts,
131*e038c9c4Sjoerg                             const TargetInfo &Target, Requirement &Req,
132*e038c9c4Sjoerg                             Module *&ShadowingModule) const {
133*e038c9c4Sjoerg   if (!IsUnimportable)
134*e038c9c4Sjoerg     return false;
135*e038c9c4Sjoerg 
136*e038c9c4Sjoerg   for (const Module *Current = this; Current; Current = Current->Parent) {
137*e038c9c4Sjoerg     if (Current->ShadowingModule) {
138*e038c9c4Sjoerg       ShadowingModule = Current->ShadowingModule;
139*e038c9c4Sjoerg       return true;
140*e038c9c4Sjoerg     }
141*e038c9c4Sjoerg     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
142*e038c9c4Sjoerg       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
143*e038c9c4Sjoerg               Current->Requirements[I].second) {
144*e038c9c4Sjoerg         Req = Current->Requirements[I];
145*e038c9c4Sjoerg         return true;
146*e038c9c4Sjoerg       }
147*e038c9c4Sjoerg     }
148*e038c9c4Sjoerg   }
149*e038c9c4Sjoerg 
150*e038c9c4Sjoerg   llvm_unreachable("could not find a reason why module is unimportable");
151*e038c9c4Sjoerg }
152*e038c9c4Sjoerg 
isAvailable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,UnresolvedHeaderDirective & MissingHeader,Module * & ShadowingModule) const1537330f729Sjoerg bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
1547330f729Sjoerg                          Requirement &Req,
1557330f729Sjoerg                          UnresolvedHeaderDirective &MissingHeader,
1567330f729Sjoerg                          Module *&ShadowingModule) const {
1577330f729Sjoerg   if (IsAvailable)
1587330f729Sjoerg     return true;
1597330f729Sjoerg 
160*e038c9c4Sjoerg   if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
161*e038c9c4Sjoerg     return false;
162*e038c9c4Sjoerg 
163*e038c9c4Sjoerg   // FIXME: All missing headers are listed on the top-level module. Should we
164*e038c9c4Sjoerg   // just look there?
1657330f729Sjoerg   for (const Module *Current = this; Current; Current = Current->Parent) {
1667330f729Sjoerg     if (!Current->MissingHeaders.empty()) {
1677330f729Sjoerg       MissingHeader = Current->MissingHeaders.front();
1687330f729Sjoerg       return false;
1697330f729Sjoerg     }
1707330f729Sjoerg   }
1717330f729Sjoerg 
1727330f729Sjoerg   llvm_unreachable("could not find a reason why module is unavailable");
1737330f729Sjoerg }
1747330f729Sjoerg 
isSubModuleOf(const Module * Other) const1757330f729Sjoerg bool Module::isSubModuleOf(const Module *Other) const {
176*e038c9c4Sjoerg   for (auto *Parent = this; Parent; Parent = Parent->Parent) {
177*e038c9c4Sjoerg     if (Parent == Other)
1787330f729Sjoerg       return true;
179*e038c9c4Sjoerg   }
1807330f729Sjoerg   return false;
1817330f729Sjoerg }
1827330f729Sjoerg 
getTopLevelModule() const1837330f729Sjoerg const Module *Module::getTopLevelModule() const {
1847330f729Sjoerg   const Module *Result = this;
1857330f729Sjoerg   while (Result->Parent)
1867330f729Sjoerg     Result = Result->Parent;
1877330f729Sjoerg 
1887330f729Sjoerg   return Result;
1897330f729Sjoerg }
1907330f729Sjoerg 
getModuleNameFromComponent(const std::pair<std::string,SourceLocation> & IdComponent)1917330f729Sjoerg static StringRef getModuleNameFromComponent(
1927330f729Sjoerg     const std::pair<std::string, SourceLocation> &IdComponent) {
1937330f729Sjoerg   return IdComponent.first;
1947330f729Sjoerg }
1957330f729Sjoerg 
getModuleNameFromComponent(StringRef R)1967330f729Sjoerg static StringRef getModuleNameFromComponent(StringRef R) { return R; }
1977330f729Sjoerg 
1987330f729Sjoerg template<typename InputIter>
printModuleId(raw_ostream & OS,InputIter Begin,InputIter End,bool AllowStringLiterals=true)1997330f729Sjoerg static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
2007330f729Sjoerg                           bool AllowStringLiterals = true) {
2017330f729Sjoerg   for (InputIter It = Begin; It != End; ++It) {
2027330f729Sjoerg     if (It != Begin)
2037330f729Sjoerg       OS << ".";
2047330f729Sjoerg 
2057330f729Sjoerg     StringRef Name = getModuleNameFromComponent(*It);
2067330f729Sjoerg     if (!AllowStringLiterals || isValidIdentifier(Name))
2077330f729Sjoerg       OS << Name;
2087330f729Sjoerg     else {
2097330f729Sjoerg       OS << '"';
2107330f729Sjoerg       OS.write_escaped(Name);
2117330f729Sjoerg       OS << '"';
2127330f729Sjoerg     }
2137330f729Sjoerg   }
2147330f729Sjoerg }
2157330f729Sjoerg 
2167330f729Sjoerg template<typename Container>
printModuleId(raw_ostream & OS,const Container & C)2177330f729Sjoerg static void printModuleId(raw_ostream &OS, const Container &C) {
2187330f729Sjoerg   return printModuleId(OS, C.begin(), C.end());
2197330f729Sjoerg }
2207330f729Sjoerg 
getFullModuleName(bool AllowStringLiterals) const2217330f729Sjoerg std::string Module::getFullModuleName(bool AllowStringLiterals) const {
2227330f729Sjoerg   SmallVector<StringRef, 2> Names;
2237330f729Sjoerg 
2247330f729Sjoerg   // Build up the set of module names (from innermost to outermost).
2257330f729Sjoerg   for (const Module *M = this; M; M = M->Parent)
2267330f729Sjoerg     Names.push_back(M->Name);
2277330f729Sjoerg 
2287330f729Sjoerg   std::string Result;
2297330f729Sjoerg 
2307330f729Sjoerg   llvm::raw_string_ostream Out(Result);
2317330f729Sjoerg   printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
2327330f729Sjoerg   Out.flush();
2337330f729Sjoerg 
2347330f729Sjoerg   return Result;
2357330f729Sjoerg }
2367330f729Sjoerg 
fullModuleNameIs(ArrayRef<StringRef> nameParts) const2377330f729Sjoerg bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
2387330f729Sjoerg   for (const Module *M = this; M; M = M->Parent) {
2397330f729Sjoerg     if (nameParts.empty() || M->Name != nameParts.back())
2407330f729Sjoerg       return false;
2417330f729Sjoerg     nameParts = nameParts.drop_back();
2427330f729Sjoerg   }
2437330f729Sjoerg   return nameParts.empty();
2447330f729Sjoerg }
2457330f729Sjoerg 
getUmbrellaDir() const2467330f729Sjoerg Module::DirectoryName Module::getUmbrellaDir() const {
2477330f729Sjoerg   if (Header U = getUmbrellaHeader())
248*e038c9c4Sjoerg     return {"", "", U.Entry->getDir()};
2497330f729Sjoerg 
250*e038c9c4Sjoerg   return {UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
251*e038c9c4Sjoerg           Umbrella.dyn_cast<const DirectoryEntry *>()};
252*e038c9c4Sjoerg }
253*e038c9c4Sjoerg 
addTopHeader(const FileEntry * File)254*e038c9c4Sjoerg void Module::addTopHeader(const FileEntry *File) {
255*e038c9c4Sjoerg   assert(File);
256*e038c9c4Sjoerg   TopHeaders.insert(File);
2577330f729Sjoerg }
2587330f729Sjoerg 
getTopHeaders(FileManager & FileMgr)2597330f729Sjoerg ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
2607330f729Sjoerg   if (!TopHeaderNames.empty()) {
2617330f729Sjoerg     for (std::vector<std::string>::iterator
2627330f729Sjoerg            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
2637330f729Sjoerg       if (auto FE = FileMgr.getFile(*I))
2647330f729Sjoerg         TopHeaders.insert(*FE);
2657330f729Sjoerg     }
2667330f729Sjoerg     TopHeaderNames.clear();
2677330f729Sjoerg   }
2687330f729Sjoerg 
2697330f729Sjoerg   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
2707330f729Sjoerg }
2717330f729Sjoerg 
directlyUses(const Module * Requested) const2727330f729Sjoerg bool Module::directlyUses(const Module *Requested) const {
2737330f729Sjoerg   auto *Top = getTopLevelModule();
2747330f729Sjoerg 
2757330f729Sjoerg   // A top-level module implicitly uses itself.
2767330f729Sjoerg   if (Requested->isSubModuleOf(Top))
2777330f729Sjoerg     return true;
2787330f729Sjoerg 
2797330f729Sjoerg   for (auto *Use : Top->DirectUses)
2807330f729Sjoerg     if (Requested->isSubModuleOf(Use))
2817330f729Sjoerg       return true;
2827330f729Sjoerg 
2837330f729Sjoerg   // Anyone is allowed to use our builtin stddef.h and its accompanying module.
2847330f729Sjoerg   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
2857330f729Sjoerg     return true;
2867330f729Sjoerg 
2877330f729Sjoerg   return false;
2887330f729Sjoerg }
2897330f729Sjoerg 
addRequirement(StringRef Feature,bool RequiredState,const LangOptions & LangOpts,const TargetInfo & Target)2907330f729Sjoerg void Module::addRequirement(StringRef Feature, bool RequiredState,
2917330f729Sjoerg                             const LangOptions &LangOpts,
2927330f729Sjoerg                             const TargetInfo &Target) {
293*e038c9c4Sjoerg   Requirements.push_back(Requirement(std::string(Feature), RequiredState));
2947330f729Sjoerg 
2957330f729Sjoerg   // If this feature is currently available, we're done.
2967330f729Sjoerg   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
2977330f729Sjoerg     return;
2987330f729Sjoerg 
299*e038c9c4Sjoerg   markUnavailable(/*Unimportable*/true);
3007330f729Sjoerg }
3017330f729Sjoerg 
markUnavailable(bool Unimportable)302*e038c9c4Sjoerg void Module::markUnavailable(bool Unimportable) {
303*e038c9c4Sjoerg   auto needUpdate = [Unimportable](Module *M) {
304*e038c9c4Sjoerg     return M->IsAvailable || (!M->IsUnimportable && Unimportable);
3057330f729Sjoerg   };
3067330f729Sjoerg 
3077330f729Sjoerg   if (!needUpdate(this))
3087330f729Sjoerg     return;
3097330f729Sjoerg 
3107330f729Sjoerg   SmallVector<Module *, 2> Stack;
3117330f729Sjoerg   Stack.push_back(this);
3127330f729Sjoerg   while (!Stack.empty()) {
3137330f729Sjoerg     Module *Current = Stack.back();
3147330f729Sjoerg     Stack.pop_back();
3157330f729Sjoerg 
3167330f729Sjoerg     if (!needUpdate(Current))
3177330f729Sjoerg       continue;
3187330f729Sjoerg 
3197330f729Sjoerg     Current->IsAvailable = false;
320*e038c9c4Sjoerg     Current->IsUnimportable |= Unimportable;
3217330f729Sjoerg     for (submodule_iterator Sub = Current->submodule_begin(),
3227330f729Sjoerg                          SubEnd = Current->submodule_end();
3237330f729Sjoerg          Sub != SubEnd; ++Sub) {
3247330f729Sjoerg       if (needUpdate(*Sub))
3257330f729Sjoerg         Stack.push_back(*Sub);
3267330f729Sjoerg     }
3277330f729Sjoerg   }
3287330f729Sjoerg }
3297330f729Sjoerg 
findSubmodule(StringRef Name) const3307330f729Sjoerg Module *Module::findSubmodule(StringRef Name) const {
3317330f729Sjoerg   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
3327330f729Sjoerg   if (Pos == SubModuleIndex.end())
3337330f729Sjoerg     return nullptr;
3347330f729Sjoerg 
3357330f729Sjoerg   return SubModules[Pos->getValue()];
3367330f729Sjoerg }
3377330f729Sjoerg 
findOrInferSubmodule(StringRef Name)3387330f729Sjoerg Module *Module::findOrInferSubmodule(StringRef Name) {
3397330f729Sjoerg   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
3407330f729Sjoerg   if (Pos != SubModuleIndex.end())
3417330f729Sjoerg     return SubModules[Pos->getValue()];
3427330f729Sjoerg   if (!InferSubmodules)
3437330f729Sjoerg     return nullptr;
3447330f729Sjoerg   Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
3457330f729Sjoerg   Result->InferExplicitSubmodules = InferExplicitSubmodules;
3467330f729Sjoerg   Result->InferSubmodules = InferSubmodules;
3477330f729Sjoerg   Result->InferExportWildcard = InferExportWildcard;
3487330f729Sjoerg   if (Result->InferExportWildcard)
3497330f729Sjoerg     Result->Exports.push_back(Module::ExportDecl(nullptr, true));
3507330f729Sjoerg   return Result;
3517330f729Sjoerg }
3527330f729Sjoerg 
getExportedModules(SmallVectorImpl<Module * > & Exported) const3537330f729Sjoerg void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
3547330f729Sjoerg   // All non-explicit submodules are exported.
3557330f729Sjoerg   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
3567330f729Sjoerg                                              E = SubModules.end();
3577330f729Sjoerg        I != E; ++I) {
3587330f729Sjoerg     Module *Mod = *I;
3597330f729Sjoerg     if (!Mod->IsExplicit)
3607330f729Sjoerg       Exported.push_back(Mod);
3617330f729Sjoerg   }
3627330f729Sjoerg 
3637330f729Sjoerg   // Find re-exported modules by filtering the list of imported modules.
3647330f729Sjoerg   bool AnyWildcard = false;
3657330f729Sjoerg   bool UnrestrictedWildcard = false;
3667330f729Sjoerg   SmallVector<Module *, 4> WildcardRestrictions;
3677330f729Sjoerg   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
3687330f729Sjoerg     Module *Mod = Exports[I].getPointer();
3697330f729Sjoerg     if (!Exports[I].getInt()) {
3707330f729Sjoerg       // Export a named module directly; no wildcards involved.
3717330f729Sjoerg       Exported.push_back(Mod);
3727330f729Sjoerg 
3737330f729Sjoerg       continue;
3747330f729Sjoerg     }
3757330f729Sjoerg 
3767330f729Sjoerg     // Wildcard export: export all of the imported modules that match
3777330f729Sjoerg     // the given pattern.
3787330f729Sjoerg     AnyWildcard = true;
3797330f729Sjoerg     if (UnrestrictedWildcard)
3807330f729Sjoerg       continue;
3817330f729Sjoerg 
3827330f729Sjoerg     if (Module *Restriction = Exports[I].getPointer())
3837330f729Sjoerg       WildcardRestrictions.push_back(Restriction);
3847330f729Sjoerg     else {
3857330f729Sjoerg       WildcardRestrictions.clear();
3867330f729Sjoerg       UnrestrictedWildcard = true;
3877330f729Sjoerg     }
3887330f729Sjoerg   }
3897330f729Sjoerg 
3907330f729Sjoerg   // If there were any wildcards, push any imported modules that were
3917330f729Sjoerg   // re-exported by the wildcard restriction.
3927330f729Sjoerg   if (!AnyWildcard)
3937330f729Sjoerg     return;
3947330f729Sjoerg 
3957330f729Sjoerg   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
3967330f729Sjoerg     Module *Mod = Imports[I];
3977330f729Sjoerg     bool Acceptable = UnrestrictedWildcard;
3987330f729Sjoerg     if (!Acceptable) {
3997330f729Sjoerg       // Check whether this module meets one of the restrictions.
4007330f729Sjoerg       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
4017330f729Sjoerg         Module *Restriction = WildcardRestrictions[R];
4027330f729Sjoerg         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
4037330f729Sjoerg           Acceptable = true;
4047330f729Sjoerg           break;
4057330f729Sjoerg         }
4067330f729Sjoerg       }
4077330f729Sjoerg     }
4087330f729Sjoerg 
4097330f729Sjoerg     if (!Acceptable)
4107330f729Sjoerg       continue;
4117330f729Sjoerg 
4127330f729Sjoerg     Exported.push_back(Mod);
4137330f729Sjoerg   }
4147330f729Sjoerg }
4157330f729Sjoerg 
buildVisibleModulesCache() const4167330f729Sjoerg void Module::buildVisibleModulesCache() const {
4177330f729Sjoerg   assert(VisibleModulesCache.empty() && "cache does not need building");
4187330f729Sjoerg 
4197330f729Sjoerg   // This module is visible to itself.
4207330f729Sjoerg   VisibleModulesCache.insert(this);
4217330f729Sjoerg 
4227330f729Sjoerg   // Every imported module is visible.
4237330f729Sjoerg   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
4247330f729Sjoerg   while (!Stack.empty()) {
4257330f729Sjoerg     Module *CurrModule = Stack.pop_back_val();
4267330f729Sjoerg 
4277330f729Sjoerg     // Every module transitively exported by an imported module is visible.
4287330f729Sjoerg     if (VisibleModulesCache.insert(CurrModule).second)
4297330f729Sjoerg       CurrModule->getExportedModules(Stack);
4307330f729Sjoerg   }
4317330f729Sjoerg }
4327330f729Sjoerg 
print(raw_ostream & OS,unsigned Indent,bool Dump) const433*e038c9c4Sjoerg void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
4347330f729Sjoerg   OS.indent(Indent);
4357330f729Sjoerg   if (IsFramework)
4367330f729Sjoerg     OS << "framework ";
4377330f729Sjoerg   if (IsExplicit)
4387330f729Sjoerg     OS << "explicit ";
4397330f729Sjoerg   OS << "module ";
4407330f729Sjoerg   printModuleId(OS, &Name, &Name + 1);
4417330f729Sjoerg 
4427330f729Sjoerg   if (IsSystem || IsExternC) {
4437330f729Sjoerg     OS.indent(Indent + 2);
4447330f729Sjoerg     if (IsSystem)
4457330f729Sjoerg       OS << " [system]";
4467330f729Sjoerg     if (IsExternC)
4477330f729Sjoerg       OS << " [extern_c]";
4487330f729Sjoerg   }
4497330f729Sjoerg 
4507330f729Sjoerg   OS << " {\n";
4517330f729Sjoerg 
4527330f729Sjoerg   if (!Requirements.empty()) {
4537330f729Sjoerg     OS.indent(Indent + 2);
4547330f729Sjoerg     OS << "requires ";
4557330f729Sjoerg     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
4567330f729Sjoerg       if (I)
4577330f729Sjoerg         OS << ", ";
4587330f729Sjoerg       if (!Requirements[I].second)
4597330f729Sjoerg         OS << "!";
4607330f729Sjoerg       OS << Requirements[I].first;
4617330f729Sjoerg     }
4627330f729Sjoerg     OS << "\n";
4637330f729Sjoerg   }
4647330f729Sjoerg 
4657330f729Sjoerg   if (Header H = getUmbrellaHeader()) {
4667330f729Sjoerg     OS.indent(Indent + 2);
4677330f729Sjoerg     OS << "umbrella header \"";
4687330f729Sjoerg     OS.write_escaped(H.NameAsWritten);
4697330f729Sjoerg     OS << "\"\n";
4707330f729Sjoerg   } else if (DirectoryName D = getUmbrellaDir()) {
4717330f729Sjoerg     OS.indent(Indent + 2);
4727330f729Sjoerg     OS << "umbrella \"";
4737330f729Sjoerg     OS.write_escaped(D.NameAsWritten);
4747330f729Sjoerg     OS << "\"\n";
4757330f729Sjoerg   }
4767330f729Sjoerg 
4777330f729Sjoerg   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
4787330f729Sjoerg     OS.indent(Indent + 2);
4797330f729Sjoerg     OS << "config_macros ";
4807330f729Sjoerg     if (ConfigMacrosExhaustive)
4817330f729Sjoerg       OS << "[exhaustive]";
4827330f729Sjoerg     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
4837330f729Sjoerg       if (I)
4847330f729Sjoerg         OS << ", ";
4857330f729Sjoerg       OS << ConfigMacros[I];
4867330f729Sjoerg     }
4877330f729Sjoerg     OS << "\n";
4887330f729Sjoerg   }
4897330f729Sjoerg 
4907330f729Sjoerg   struct {
4917330f729Sjoerg     StringRef Prefix;
4927330f729Sjoerg     HeaderKind Kind;
4937330f729Sjoerg   } Kinds[] = {{"", HK_Normal},
4947330f729Sjoerg                {"textual ", HK_Textual},
4957330f729Sjoerg                {"private ", HK_Private},
4967330f729Sjoerg                {"private textual ", HK_PrivateTextual},
4977330f729Sjoerg                {"exclude ", HK_Excluded}};
4987330f729Sjoerg 
4997330f729Sjoerg   for (auto &K : Kinds) {
5007330f729Sjoerg     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
5017330f729Sjoerg     for (auto &H : Headers[K.Kind]) {
5027330f729Sjoerg       OS.indent(Indent + 2);
5037330f729Sjoerg       OS << K.Prefix << "header \"";
5047330f729Sjoerg       OS.write_escaped(H.NameAsWritten);
5057330f729Sjoerg       OS << "\" { size " << H.Entry->getSize()
5067330f729Sjoerg          << " mtime " << H.Entry->getModificationTime() << " }\n";
5077330f729Sjoerg     }
5087330f729Sjoerg   }
5097330f729Sjoerg   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
5107330f729Sjoerg     for (auto &U : *Unresolved) {
5117330f729Sjoerg       OS.indent(Indent + 2);
5127330f729Sjoerg       OS << Kinds[U.Kind].Prefix << "header \"";
5137330f729Sjoerg       OS.write_escaped(U.FileName);
5147330f729Sjoerg       OS << "\"";
5157330f729Sjoerg       if (U.Size || U.ModTime) {
5167330f729Sjoerg         OS << " {";
5177330f729Sjoerg         if (U.Size)
5187330f729Sjoerg           OS << " size " << *U.Size;
5197330f729Sjoerg         if (U.ModTime)
5207330f729Sjoerg           OS << " mtime " << *U.ModTime;
5217330f729Sjoerg         OS << " }";
5227330f729Sjoerg       }
5237330f729Sjoerg       OS << "\n";
5247330f729Sjoerg     }
5257330f729Sjoerg   }
5267330f729Sjoerg 
5277330f729Sjoerg   if (!ExportAsModule.empty()) {
5287330f729Sjoerg     OS.indent(Indent + 2);
5297330f729Sjoerg     OS << "export_as" << ExportAsModule << "\n";
5307330f729Sjoerg   }
5317330f729Sjoerg 
5327330f729Sjoerg   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
5337330f729Sjoerg        MI != MIEnd; ++MI)
5347330f729Sjoerg     // Print inferred subframework modules so that we don't need to re-infer
5357330f729Sjoerg     // them (requires expensive directory iteration + stat calls) when we build
5367330f729Sjoerg     // the module. Regular inferred submodules are OK, as we need to look at all
5377330f729Sjoerg     // those header files anyway.
5387330f729Sjoerg     if (!(*MI)->IsInferred || (*MI)->IsFramework)
539*e038c9c4Sjoerg       (*MI)->print(OS, Indent + 2, Dump);
5407330f729Sjoerg 
5417330f729Sjoerg   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
5427330f729Sjoerg     OS.indent(Indent + 2);
5437330f729Sjoerg     OS << "export ";
5447330f729Sjoerg     if (Module *Restriction = Exports[I].getPointer()) {
5457330f729Sjoerg       OS << Restriction->getFullModuleName(true);
5467330f729Sjoerg       if (Exports[I].getInt())
5477330f729Sjoerg         OS << ".*";
5487330f729Sjoerg     } else {
5497330f729Sjoerg       OS << "*";
5507330f729Sjoerg     }
5517330f729Sjoerg     OS << "\n";
5527330f729Sjoerg   }
5537330f729Sjoerg 
5547330f729Sjoerg   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
5557330f729Sjoerg     OS.indent(Indent + 2);
5567330f729Sjoerg     OS << "export ";
5577330f729Sjoerg     printModuleId(OS, UnresolvedExports[I].Id);
5587330f729Sjoerg     if (UnresolvedExports[I].Wildcard)
5597330f729Sjoerg       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
5607330f729Sjoerg     OS << "\n";
5617330f729Sjoerg   }
5627330f729Sjoerg 
563*e038c9c4Sjoerg   if (Dump) {
564*e038c9c4Sjoerg     for (Module *M : Imports) {
565*e038c9c4Sjoerg       OS.indent(Indent + 2);
566*e038c9c4Sjoerg       llvm::errs() << "import " << M->getFullModuleName() << "\n";
567*e038c9c4Sjoerg     }
568*e038c9c4Sjoerg   }
569*e038c9c4Sjoerg 
5707330f729Sjoerg   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
5717330f729Sjoerg     OS.indent(Indent + 2);
5727330f729Sjoerg     OS << "use ";
5737330f729Sjoerg     OS << DirectUses[I]->getFullModuleName(true);
5747330f729Sjoerg     OS << "\n";
5757330f729Sjoerg   }
5767330f729Sjoerg 
5777330f729Sjoerg   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
5787330f729Sjoerg     OS.indent(Indent + 2);
5797330f729Sjoerg     OS << "use ";
5807330f729Sjoerg     printModuleId(OS, UnresolvedDirectUses[I]);
5817330f729Sjoerg     OS << "\n";
5827330f729Sjoerg   }
5837330f729Sjoerg 
5847330f729Sjoerg   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
5857330f729Sjoerg     OS.indent(Indent + 2);
5867330f729Sjoerg     OS << "link ";
5877330f729Sjoerg     if (LinkLibraries[I].IsFramework)
5887330f729Sjoerg       OS << "framework ";
5897330f729Sjoerg     OS << "\"";
5907330f729Sjoerg     OS.write_escaped(LinkLibraries[I].Library);
5917330f729Sjoerg     OS << "\"";
5927330f729Sjoerg   }
5937330f729Sjoerg 
5947330f729Sjoerg   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
5957330f729Sjoerg     OS.indent(Indent + 2);
5967330f729Sjoerg     OS << "conflict ";
5977330f729Sjoerg     printModuleId(OS, UnresolvedConflicts[I].Id);
5987330f729Sjoerg     OS << ", \"";
5997330f729Sjoerg     OS.write_escaped(UnresolvedConflicts[I].Message);
6007330f729Sjoerg     OS << "\"\n";
6017330f729Sjoerg   }
6027330f729Sjoerg 
6037330f729Sjoerg   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
6047330f729Sjoerg     OS.indent(Indent + 2);
6057330f729Sjoerg     OS << "conflict ";
6067330f729Sjoerg     OS << Conflicts[I].Other->getFullModuleName(true);
6077330f729Sjoerg     OS << ", \"";
6087330f729Sjoerg     OS.write_escaped(Conflicts[I].Message);
6097330f729Sjoerg     OS << "\"\n";
6107330f729Sjoerg   }
6117330f729Sjoerg 
6127330f729Sjoerg   if (InferSubmodules) {
6137330f729Sjoerg     OS.indent(Indent + 2);
6147330f729Sjoerg     if (InferExplicitSubmodules)
6157330f729Sjoerg       OS << "explicit ";
6167330f729Sjoerg     OS << "module * {\n";
6177330f729Sjoerg     if (InferExportWildcard) {
6187330f729Sjoerg       OS.indent(Indent + 4);
6197330f729Sjoerg       OS << "export *\n";
6207330f729Sjoerg     }
6217330f729Sjoerg     OS.indent(Indent + 2);
6227330f729Sjoerg     OS << "}\n";
6237330f729Sjoerg   }
6247330f729Sjoerg 
6257330f729Sjoerg   OS.indent(Indent);
6267330f729Sjoerg   OS << "}\n";
6277330f729Sjoerg }
6287330f729Sjoerg 
dump() const6297330f729Sjoerg LLVM_DUMP_METHOD void Module::dump() const {
630*e038c9c4Sjoerg   print(llvm::errs(), 0, true);
6317330f729Sjoerg }
6327330f729Sjoerg 
setVisible(Module * M,SourceLocation Loc,VisibleCallback Vis,ConflictCallback Cb)6337330f729Sjoerg void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
6347330f729Sjoerg                                   VisibleCallback Vis, ConflictCallback Cb) {
6357330f729Sjoerg   assert(Loc.isValid() && "setVisible expects a valid import location");
6367330f729Sjoerg   if (isVisible(M))
6377330f729Sjoerg     return;
6387330f729Sjoerg 
6397330f729Sjoerg   ++Generation;
6407330f729Sjoerg 
6417330f729Sjoerg   struct Visiting {
6427330f729Sjoerg     Module *M;
6437330f729Sjoerg     Visiting *ExportedBy;
6447330f729Sjoerg   };
6457330f729Sjoerg 
6467330f729Sjoerg   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
6477330f729Sjoerg     // Nothing to do for a module that's already visible.
6487330f729Sjoerg     unsigned ID = V.M->getVisibilityID();
6497330f729Sjoerg     if (ImportLocs.size() <= ID)
6507330f729Sjoerg       ImportLocs.resize(ID + 1);
6517330f729Sjoerg     else if (ImportLocs[ID].isValid())
6527330f729Sjoerg       return;
6537330f729Sjoerg 
6547330f729Sjoerg     ImportLocs[ID] = Loc;
6557330f729Sjoerg     Vis(M);
6567330f729Sjoerg 
6577330f729Sjoerg     // Make any exported modules visible.
6587330f729Sjoerg     SmallVector<Module *, 16> Exports;
6597330f729Sjoerg     V.M->getExportedModules(Exports);
6607330f729Sjoerg     for (Module *E : Exports) {
661*e038c9c4Sjoerg       // Don't import non-importable modules.
662*e038c9c4Sjoerg       if (!E->isUnimportable())
6637330f729Sjoerg         VisitModule({E, &V});
6647330f729Sjoerg     }
6657330f729Sjoerg 
6667330f729Sjoerg     for (auto &C : V.M->Conflicts) {
6677330f729Sjoerg       if (isVisible(C.Other)) {
6687330f729Sjoerg         llvm::SmallVector<Module*, 8> Path;
6697330f729Sjoerg         for (Visiting *I = &V; I; I = I->ExportedBy)
6707330f729Sjoerg           Path.push_back(I->M);
6717330f729Sjoerg         Cb(Path, C.Other, C.Message);
6727330f729Sjoerg       }
6737330f729Sjoerg     }
6747330f729Sjoerg   };
6757330f729Sjoerg   VisitModule({M, nullptr});
6767330f729Sjoerg }
677*e038c9c4Sjoerg 
ASTSourceDescriptor(Module & M)678*e038c9c4Sjoerg ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
679*e038c9c4Sjoerg     : Signature(M.Signature), ClangModule(&M) {
680*e038c9c4Sjoerg   if (M.Directory)
681*e038c9c4Sjoerg     Path = M.Directory->getName();
682*e038c9c4Sjoerg   if (auto File = M.getASTFile())
683*e038c9c4Sjoerg     ASTFile = File->getName();
684*e038c9c4Sjoerg }
685*e038c9c4Sjoerg 
getModuleName() const686*e038c9c4Sjoerg std::string ASTSourceDescriptor::getModuleName() const {
687*e038c9c4Sjoerg   if (ClangModule)
688*e038c9c4Sjoerg     return ClangModule->Name;
689*e038c9c4Sjoerg   else
690*e038c9c4Sjoerg     return std::string(PCHModuleName);
691*e038c9c4Sjoerg }
692