summaryrefslogtreecommitdiffstats
path: root/lib/Basic/Module.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Basic/Module.cpp')
-rw-r--r--lib/Basic/Module.cpp84
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 ";
OpenPOWER on IntegriCloud