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