diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 20:44:45 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 20:44:45 +0000 | 
| commit | 33956c43007dfb106f401e3c14abc011a4b1d4ca (patch) | |
| tree | 50a603f7e1932cd42f58e26687ce907933014db0 /contrib/llvm/tools/clang/lib/Basic/Module.cpp | |
| parent | ff0cc061ecf297f1556e906d229826fd709f37d6 (diff) | |
| parent | 5e20cdd81c44a443562a09007668ffdf76c455af (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic/Module.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Module.cpp | 111 | 
1 files changed, 86 insertions, 25 deletions
| diff --git a/contrib/llvm/tools/clang/lib/Basic/Module.cpp b/contrib/llvm/tools/clang/lib/Basic/Module.cpp index 03f9bd3f329c..7308665bd2d8 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Module.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Module.cpp @@ -25,14 +25,14 @@  using namespace clang;  Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, -               bool IsFramework, bool IsExplicit) +               bool IsFramework, bool IsExplicit, unsigned VisibilityID)      : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(), -      Umbrella(), ASTFile(nullptr), IsMissingRequirement(false), -      IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), -      IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), -      IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), -      InferExportWildcard(false), ConfigMacrosExhaustive(false), -      NameVisibility(Hidden) { +      Umbrella(), ASTFile(nullptr), VisibilityID(VisibilityID), +      IsMissingRequirement(false), IsAvailable(true), IsFromModuleFile(false), +      IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), +      IsExternC(false), IsInferred(false), InferSubmodules(false), +      InferExplicitSubmodules(false), InferExportWildcard(false), +      ConfigMacrosExhaustive(false), NameVisibility(Hidden) {    if (Parent) {      if (!Parent->isAvailable())        IsAvailable = false; @@ -58,16 +58,21 @@ Module::~Module() {  /// language options has the given feature.  static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,                         const TargetInfo &Target) { -  return llvm::StringSwitch<bool>(Feature) -           .Case("altivec", LangOpts.AltiVec) -           .Case("blocks", LangOpts.Blocks) -           .Case("cplusplus", LangOpts.CPlusPlus) -           .Case("cplusplus11", LangOpts.CPlusPlus11) -           .Case("objc", LangOpts.ObjC1) -           .Case("objc_arc", LangOpts.ObjCAutoRefCount) -           .Case("opencl", LangOpts.OpenCL) -           .Case("tls", Target.isTLSSupported()) -           .Default(Target.hasFeature(Feature)); +  bool HasFeature = llvm::StringSwitch<bool>(Feature) +                        .Case("altivec", LangOpts.AltiVec) +                        .Case("blocks", LangOpts.Blocks) +                        .Case("cplusplus", LangOpts.CPlusPlus) +                        .Case("cplusplus11", LangOpts.CPlusPlus11) +                        .Case("objc", LangOpts.ObjC1) +                        .Case("objc_arc", LangOpts.ObjCAutoRefCount) +                        .Case("opencl", LangOpts.OpenCL) +                        .Case("tls", Target.isTLSSupported()) +                        .Default(Target.hasFeature(Feature)); +  if (!HasFeature) +    HasFeature = std::find(LangOpts.ModuleFeatures.begin(), +                           LangOpts.ModuleFeatures.end(), +                           Feature) != LangOpts.ModuleFeatures.end(); +  return HasFeature;  }  bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, @@ -133,11 +138,11 @@ std::string Module::getFullModuleName() const {    return Result;  } -const DirectoryEntry *Module::getUmbrellaDir() const { -  if (const FileEntry *Header = getUmbrellaHeader()) -    return Header->getDir(); +Module::DirectoryName Module::getUmbrellaDir() const { +  if (Header U = getUmbrellaHeader()) +    return {"", U.Entry->getDir()}; -  return Umbrella.dyn_cast<const DirectoryEntry *>(); +  return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};  }  ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { @@ -153,6 +158,19 @@ ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {    return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());  } +bool Module::directlyUses(const Module *Requested) const { +  auto *Top = getTopLevelModule(); + +  // A top-level module implicitly uses itself. +  if (Requested->isSubModuleOf(Top)) +    return true; + +  for (auto *Use : Top->DirectUses) +    if (Requested->isSubModuleOf(Use)) +      return true; +  return false; +} +  void Module::addRequirement(StringRef Feature, bool RequiredState,                              const LangOptions &LangOpts,                              const TargetInfo &Target) { @@ -316,15 +334,15 @@ void Module::print(raw_ostream &OS, unsigned Indent) const {      OS << "\n";    } -  if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { +  if (Header H = getUmbrellaHeader()) {      OS.indent(Indent + 2);      OS << "umbrella header \""; -    OS.write_escaped(UmbrellaHeader->getName()); +    OS.write_escaped(H.NameAsWritten);      OS << "\"\n"; -  } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { +  } else if (DirectoryName D = getUmbrellaDir()) {      OS.indent(Indent + 2);      OS << "umbrella \""; -    OS.write_escaped(UmbrellaDir->getName()); +    OS.write_escaped(D.NameAsWritten);      OS << "\"\n";        } @@ -457,4 +475,47 @@ void Module::dump() const {    print(llvm::errs());  } +void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, +                                  VisibleCallback Vis, ConflictCallback Cb) { +  if (isVisible(M)) +    return; +  ++Generation; + +  struct Visiting { +    Module *M; +    Visiting *ExportedBy; +  }; + +  std::function<void(Visiting)> VisitModule = [&](Visiting V) { +    // Modules that aren't available cannot be made visible. +    if (!V.M->isAvailable()) +      return; + +    // Nothing to do for a module that's already visible. +    unsigned ID = V.M->getVisibilityID(); +    if (ImportLocs.size() <= ID) +      ImportLocs.resize(ID + 1); +    else if (ImportLocs[ID].isValid()) +      return; + +    ImportLocs[ID] = Loc; +    Vis(M); + +    // Make any exported modules visible. +    SmallVector<Module *, 16> Exports; +    V.M->getExportedModules(Exports); +    for (Module *E : Exports) +      VisitModule({E, &V}); + +    for (auto &C : V.M->Conflicts) { +      if (isVisible(C.Other)) { +        llvm::SmallVector<Module*, 8> Path; +        for (Visiting *I = &V; I; I = I->ExportedBy) +          Path.push_back(I->M); +        Cb(Path, C.Other, C.Message); +      } +    } +  }; +  VisitModule({M, nullptr}); +} | 
