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