diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2013-12-22 00:07:40 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2013-12-22 00:07:40 +0000 | 
| commit | bfef399519ca9b8a4b4c6b563253bad7e0eeffe0 (patch) | |
| tree | df8df0b0067b381eab470a3b8f28d14a552a6340 /lib/Basic/Module.cpp | |
| parent | 6a0372513edbc473b538d2f724efac50405d6fef (diff) | |
Notes
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 13518cde6642..d08cef1a1563 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 ";  | 
