diff options
Diffstat (limited to 'lib/Basic/Module.cpp')
-rw-r--r-- | lib/Basic/Module.cpp | 84 |
1 files changed, 69 insertions, 15 deletions
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp index 13518cd..d08cef1 100644 --- a/lib/Basic/Module.cpp +++ b/lib/Basic/Module.cpp @@ -11,6 +11,7 @@ // code. // //===----------------------------------------------------------------------===// + #include "clang/Basic/Module.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" @@ -20,6 +21,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" + using namespace clang; Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, @@ -65,16 +67,17 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, .Default(Target.hasFeature(Feature)); } -bool +bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, - StringRef &Feature) const { + Requirement &Req) const { if (IsAvailable) return true; for (const Module *Current = this; Current; Current = Current->Parent) { - for (unsigned I = 0, N = Current->Requires.size(); I != N; ++I) { - if (!hasFeature(Current->Requires[I], LangOpts, Target)) { - Feature = Current->Requires[I]; + for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { + if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != + Current->Requirements[I].second) { + Req = Current->Requirements[I]; return false; } } @@ -111,8 +114,8 @@ std::string Module::getFullModuleName() const { Names.push_back(M->Name); std::string Result; - for (SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), - IEnd = Names.rend(); + for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(), + IEnd = Names.rend(); I != IEnd; ++I) { if (!Result.empty()) Result += '.'; @@ -143,12 +146,13 @@ ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); } -void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts, +void Module::addRequirement(StringRef Feature, bool RequiredState, + const LangOptions &LangOpts, const TargetInfo &Target) { - Requires.push_back(Feature); + Requirements.push_back(Requirement(Feature, RequiredState)); // If this feature is currently available, we're done. - if (hasFeature(Feature, LangOpts, Target)) + if (hasFeature(Feature, LangOpts, Target) == RequiredState) return; if (!IsAvailable) @@ -190,6 +194,16 @@ static void printModuleId(raw_ostream &OS, const ModuleId &Id) { } void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { + // All non-explicit submodules are exported. + for (std::vector<Module *>::const_iterator I = SubModules.begin(), + E = SubModules.end(); + I != E; ++I) { + Module *Mod = *I; + if (!Mod->IsExplicit) + Exported.push_back(Mod); + } + + // Find re-exported modules by filtering the list of imported modules. bool AnyWildcard = false; bool UnrestrictedWildcard = false; SmallVector<Module *, 4> WildcardRestrictions; @@ -242,6 +256,23 @@ void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { } } +void Module::buildVisibleModulesCache() const { + assert(VisibleModulesCache.empty() && "cache does not need building"); + + // This module is visible to itself. + VisibleModulesCache.insert(this); + + // Every imported module is visible. + SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); + while (!Stack.empty()) { + Module *CurrModule = Stack.pop_back_val(); + + // Every module transitively exported by an imported module is visible. + if (VisibleModulesCache.insert(CurrModule).second) + CurrModule->getExportedModules(Stack); + } +} + void Module::print(raw_ostream &OS, unsigned Indent) const { OS.indent(Indent); if (IsFramework) @@ -257,13 +288,15 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { OS << " {\n"; - if (!Requires.empty()) { + if (!Requirements.empty()) { OS.indent(Indent + 2); OS << "requires "; - for (unsigned I = 0, N = Requires.size(); I != N; ++I) { + for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { if (I) OS << ", "; - OS << Requires[I]; + if (!Requirements[I].second) + OS << "!"; + OS << Requirements[I].first; } OS << "\n"; } @@ -293,10 +326,10 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { OS << "\n"; } - for (unsigned I = 0, N = Headers.size(); I != N; ++I) { + for (unsigned I = 0, N = NormalHeaders.size(); I != N; ++I) { OS.indent(Indent + 2); OS << "header \""; - OS.write_escaped(Headers[I]->getName()); + OS.write_escaped(NormalHeaders[I]->getName()); OS << "\"\n"; } @@ -306,6 +339,13 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { OS.write_escaped(ExcludedHeaders[I]->getName()); OS << "\"\n"; } + + for (unsigned I = 0, N = PrivateHeaders.size(); I != N; ++I) { + OS.indent(Indent + 2); + OS << "private header \""; + OS.write_escaped(PrivateHeaders[I]->getName()); + OS << "\"\n"; + } for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); MI != MIEnd; ++MI) @@ -337,6 +377,20 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { OS << "\n"; } + for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { + OS.indent(Indent + 2); + OS << "use "; + OS << DirectUses[I]->getFullModuleName(); + OS << "\n"; + } + + for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { + OS.indent(Indent + 2); + OS << "use "; + printModuleId(OS, UnresolvedDirectUses[I]); + OS << "\n"; + } + for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { OS.indent(Indent + 2); OS << "link "; |