2012-12-04 17:13:33 +08:00
|
|
|
//===--- Module.cpp - Describe a module -----------------------------------===//
|
2011-12-01 07:21:26 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file defines the Module class, which describes a module in the source
|
|
|
|
// code.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2013-10-29 06:18:19 +08:00
|
|
|
|
2011-12-01 07:21:26 +08:00
|
|
|
#include "clang/Basic/Module.h"
|
|
|
|
#include "clang/Basic/FileManager.h"
|
2011-12-31 12:05:44 +08:00
|
|
|
#include "clang/Basic/LangOptions.h"
|
2012-01-30 14:38:25 +08:00
|
|
|
#include "clang/Basic/TargetInfo.h"
|
2013-03-14 05:13:43 +08:00
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
2011-12-31 12:05:44 +08:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
|
|
#include "llvm/ADT/StringSwitch.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2013-10-29 06:18:19 +08:00
|
|
|
|
2011-12-01 07:21:26 +08:00
|
|
|
using namespace clang;
|
|
|
|
|
2012-01-05 07:32:19 +08:00
|
|
|
Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
|
|
|
|
bool IsFramework, bool IsExplicit)
|
2012-09-29 09:06:04 +08:00
|
|
|
: Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
|
|
|
|
Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false),
|
2012-01-28 03:52:33 +08:00
|
|
|
IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false),
|
|
|
|
InferSubmodules(false), InferExplicitSubmodules(false),
|
2013-03-20 11:59:18 +08:00
|
|
|
InferExportWildcard(false), ConfigMacrosExhaustive(false),
|
|
|
|
NameVisibility(Hidden)
|
2012-01-05 07:32:19 +08:00
|
|
|
{
|
|
|
|
if (Parent) {
|
|
|
|
if (!Parent->isAvailable())
|
|
|
|
IsAvailable = false;
|
2012-02-03 02:42:48 +08:00
|
|
|
if (Parent->IsSystem)
|
|
|
|
IsSystem = true;
|
2012-01-05 07:32:19 +08:00
|
|
|
|
|
|
|
Parent->SubModuleIndex[Name] = Parent->SubModules.size();
|
|
|
|
Parent->SubModules.push_back(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-01 07:21:26 +08:00
|
|
|
Module::~Module() {
|
2012-01-05 07:32:19 +08:00
|
|
|
for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
|
2011-12-01 07:21:26 +08:00
|
|
|
I != IEnd; ++I) {
|
2012-01-05 07:32:19 +08:00
|
|
|
delete *I;
|
2011-12-01 07:21:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-31 12:05:44 +08:00
|
|
|
/// \brief Determine whether a translation unit built using the current
|
|
|
|
/// language options has the given feature.
|
2012-01-30 14:01:29 +08:00
|
|
|
static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
|
|
|
|
const TargetInfo &Target) {
|
2011-12-31 12:05:44 +08:00
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
2012-01-30 14:38:25 +08:00
|
|
|
.Case("altivec", LangOpts.AltiVec)
|
2011-12-31 12:05:44 +08:00
|
|
|
.Case("blocks", LangOpts.Blocks)
|
|
|
|
.Case("cplusplus", LangOpts.CPlusPlus)
|
2013-01-02 19:42:31 +08:00
|
|
|
.Case("cplusplus11", LangOpts.CPlusPlus11)
|
2011-12-31 12:05:44 +08:00
|
|
|
.Case("objc", LangOpts.ObjC1)
|
|
|
|
.Case("objc_arc", LangOpts.ObjCAutoRefCount)
|
2012-01-30 14:38:25 +08:00
|
|
|
.Case("opencl", LangOpts.OpenCL)
|
|
|
|
.Case("tls", Target.isTLSSupported())
|
|
|
|
.Default(Target.hasFeature(Feature));
|
2011-12-31 12:05:44 +08:00
|
|
|
}
|
|
|
|
|
2013-10-29 06:18:19 +08:00
|
|
|
bool
|
2012-01-30 14:01:29 +08:00
|
|
|
Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
|
2013-10-29 06:18:19 +08:00
|
|
|
Requirement &Req) const {
|
2011-12-31 12:05:44 +08:00
|
|
|
if (IsAvailable)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
for (const Module *Current = this; Current; Current = Current->Parent) {
|
2013-10-29 06:18:19 +08:00
|
|
|
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];
|
2011-12-31 12:05:44 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("could not find a reason why module is unavailable");
|
|
|
|
}
|
|
|
|
|
2011-12-06 01:28:06 +08:00
|
|
|
bool Module::isSubModuleOf(Module *Other) const {
|
|
|
|
const Module *This = this;
|
|
|
|
do {
|
|
|
|
if (This == Other)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
This = This->Parent;
|
|
|
|
} while (This);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-12-06 06:27:44 +08:00
|
|
|
const Module *Module::getTopLevelModule() const {
|
|
|
|
const Module *Result = this;
|
|
|
|
while (Result->Parent)
|
|
|
|
Result = Result->Parent;
|
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2011-12-01 07:21:26 +08:00
|
|
|
std::string Module::getFullModuleName() const {
|
2013-01-13 03:30:44 +08:00
|
|
|
SmallVector<StringRef, 2> Names;
|
2011-12-01 07:21:26 +08:00
|
|
|
|
|
|
|
// Build up the set of module names (from innermost to outermost).
|
|
|
|
for (const Module *M = this; M; M = M->Parent)
|
|
|
|
Names.push_back(M->Name);
|
|
|
|
|
|
|
|
std::string Result;
|
2013-07-08 11:55:09 +08:00
|
|
|
for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(),
|
|
|
|
IEnd = Names.rend();
|
2011-12-01 07:21:26 +08:00
|
|
|
I != IEnd; ++I) {
|
|
|
|
if (!Result.empty())
|
|
|
|
Result += '.';
|
|
|
|
|
|
|
|
Result += *I;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2011-12-09 01:39:04 +08:00
|
|
|
const DirectoryEntry *Module::getUmbrellaDir() const {
|
|
|
|
if (const FileEntry *Header = getUmbrellaHeader())
|
|
|
|
return Header->getDir();
|
|
|
|
|
|
|
|
return Umbrella.dyn_cast<const DirectoryEntry *>();
|
|
|
|
}
|
|
|
|
|
2013-03-14 05:13:43 +08:00
|
|
|
ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
|
|
|
|
if (!TopHeaderNames.empty()) {
|
|
|
|
for (std::vector<std::string>::iterator
|
|
|
|
I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
|
|
|
|
if (const FileEntry *FE = FileMgr.getFile(*I))
|
|
|
|
TopHeaders.insert(FE);
|
|
|
|
}
|
|
|
|
TopHeaderNames.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
|
|
|
|
}
|
|
|
|
|
2013-10-29 06:18:19 +08:00
|
|
|
void Module::addRequirement(StringRef Feature, bool RequiredState,
|
|
|
|
const LangOptions &LangOpts,
|
2012-01-30 14:01:29 +08:00
|
|
|
const TargetInfo &Target) {
|
2013-10-29 06:18:19 +08:00
|
|
|
Requirements.push_back(Requirement(Feature, RequiredState));
|
2011-12-31 12:05:44 +08:00
|
|
|
|
|
|
|
// If this feature is currently available, we're done.
|
2013-10-29 06:18:19 +08:00
|
|
|
if (hasFeature(Feature, LangOpts, Target) == RequiredState)
|
2011-12-31 12:05:44 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (!IsAvailable)
|
|
|
|
return;
|
|
|
|
|
2013-01-13 03:30:44 +08:00
|
|
|
SmallVector<Module *, 2> Stack;
|
2011-12-31 12:05:44 +08:00
|
|
|
Stack.push_back(this);
|
|
|
|
while (!Stack.empty()) {
|
|
|
|
Module *Current = Stack.back();
|
|
|
|
Stack.pop_back();
|
|
|
|
|
|
|
|
if (!Current->IsAvailable)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Current->IsAvailable = false;
|
2012-01-05 07:32:19 +08:00
|
|
|
for (submodule_iterator Sub = Current->submodule_begin(),
|
|
|
|
SubEnd = Current->submodule_end();
|
2011-12-31 12:05:44 +08:00
|
|
|
Sub != SubEnd; ++Sub) {
|
2012-01-05 07:32:19 +08:00
|
|
|
if ((*Sub)->IsAvailable)
|
|
|
|
Stack.push_back(*Sub);
|
2011-12-31 12:05:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-05 07:32:19 +08:00
|
|
|
Module *Module::findSubmodule(StringRef Name) const {
|
|
|
|
llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
|
|
|
|
if (Pos == SubModuleIndex.end())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return SubModules[Pos->getValue()];
|
|
|
|
}
|
|
|
|
|
2013-01-13 03:30:44 +08:00
|
|
|
static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
|
2011-12-03 02:58:38 +08:00
|
|
|
for (unsigned I = 0, N = Id.size(); I != N; ++I) {
|
|
|
|
if (I)
|
|
|
|
OS << ".";
|
|
|
|
OS << Id[I].first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-20 03:34:40 +08:00
|
|
|
void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
|
2013-11-05 05:51:33 +08:00
|
|
|
// 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.
|
2013-02-20 03:34:40 +08:00
|
|
|
bool AnyWildcard = false;
|
|
|
|
bool UnrestrictedWildcard = false;
|
|
|
|
SmallVector<Module *, 4> WildcardRestrictions;
|
|
|
|
for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
|
|
|
|
Module *Mod = Exports[I].getPointer();
|
|
|
|
if (!Exports[I].getInt()) {
|
|
|
|
// Export a named module directly; no wildcards involved.
|
|
|
|
Exported.push_back(Mod);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wildcard export: export all of the imported modules that match
|
|
|
|
// the given pattern.
|
|
|
|
AnyWildcard = true;
|
|
|
|
if (UnrestrictedWildcard)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (Module *Restriction = Exports[I].getPointer())
|
|
|
|
WildcardRestrictions.push_back(Restriction);
|
|
|
|
else {
|
|
|
|
WildcardRestrictions.clear();
|
|
|
|
UnrestrictedWildcard = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If there were any wildcards, push any imported modules that were
|
|
|
|
// re-exported by the wildcard restriction.
|
|
|
|
if (!AnyWildcard)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
|
|
|
|
Module *Mod = Imports[I];
|
|
|
|
bool Acceptable = UnrestrictedWildcard;
|
|
|
|
if (!Acceptable) {
|
|
|
|
// Check whether this module meets one of the restrictions.
|
|
|
|
for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
|
|
|
|
Module *Restriction = WildcardRestrictions[R];
|
|
|
|
if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
|
|
|
|
Acceptable = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Acceptable)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Exported.push_back(Mod);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
When we perform dependent name lookup during template instantiation, it's not
sufficient to only consider names visible at the point of instantiation,
because that may not include names that were visible when the template was
defined. More generally, if the instantiation backtrace goes through a module
M, then every declaration visible within M should be available to the
instantiation. Any of those declarations might be part of the interface that M
intended to export to a template that it instantiates.
The fix here has two parts:
1) If we find a non-visible declaration during name lookup during template
instantiation, check whether the declaration was visible from the defining
module of all entities on the active template instantiation stack. The defining
module is not the owning module in all cases: we look at the module in which a
template was defined, not the module in which it was first instantiated.
2) Perform pending instantiations at the end of a module, not at the end of the
translation unit. This is general goodness, since it significantly cuts down
the amount of redundant work that is performed in every TU importing a module,
and also implicitly adds the module containing the point of instantiation to
the set of modules checked for declarations in a lookup within a template
instantiation.
There's a known issue here with template instantiations performed while
building a module, if additional imports are added later on. I'll fix that
in a subsequent commit.
llvm-svn: 187167
2013-07-26 07:08:39 +08:00
|
|
|
void Module::buildVisibleModulesCache() const {
|
|
|
|
assert(VisibleModulesCache.empty() && "cache does not need building");
|
|
|
|
|
|
|
|
// This module is visible to itself.
|
|
|
|
VisibleModulesCache.insert(this);
|
|
|
|
|
2013-11-01 06:24:10 +08:00
|
|
|
// Every imported module is visible.
|
2013-11-01 10:19:14 +08:00
|
|
|
SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
|
2013-11-01 06:24:10 +08:00
|
|
|
while (!Stack.empty()) {
|
|
|
|
Module *CurrModule = Stack.pop_back_val();
|
2013-11-01 10:19:14 +08:00
|
|
|
|
|
|
|
// Every module transitively exported by an imported module is visible.
|
|
|
|
if (VisibleModulesCache.insert(CurrModule).second)
|
|
|
|
CurrModule->getExportedModules(Stack);
|
When we perform dependent name lookup during template instantiation, it's not
sufficient to only consider names visible at the point of instantiation,
because that may not include names that were visible when the template was
defined. More generally, if the instantiation backtrace goes through a module
M, then every declaration visible within M should be available to the
instantiation. Any of those declarations might be part of the interface that M
intended to export to a template that it instantiates.
The fix here has two parts:
1) If we find a non-visible declaration during name lookup during template
instantiation, check whether the declaration was visible from the defining
module of all entities on the active template instantiation stack. The defining
module is not the owning module in all cases: we look at the module in which a
template was defined, not the module in which it was first instantiated.
2) Perform pending instantiations at the end of a module, not at the end of the
translation unit. This is general goodness, since it significantly cuts down
the amount of redundant work that is performed in every TU importing a module,
and also implicitly adds the module containing the point of instantiation to
the set of modules checked for declarations in a lookup within a template
instantiation.
There's a known issue here with template instantiations performed while
building a module, if additional imports are added later on. I'll fix that
in a subsequent commit.
llvm-svn: 187167
2013-07-26 07:08:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-13 03:30:44 +08:00
|
|
|
void Module::print(raw_ostream &OS, unsigned Indent) const {
|
2011-12-01 07:21:26 +08:00
|
|
|
OS.indent(Indent);
|
|
|
|
if (IsFramework)
|
|
|
|
OS << "framework ";
|
|
|
|
if (IsExplicit)
|
|
|
|
OS << "explicit ";
|
2012-01-28 03:52:33 +08:00
|
|
|
OS << "module " << Name;
|
2011-12-31 12:05:44 +08:00
|
|
|
|
2012-01-28 03:52:33 +08:00
|
|
|
if (IsSystem) {
|
|
|
|
OS.indent(Indent + 2);
|
|
|
|
OS << " [system]";
|
|
|
|
}
|
|
|
|
|
|
|
|
OS << " {\n";
|
|
|
|
|
2013-10-29 06:18:19 +08:00
|
|
|
if (!Requirements.empty()) {
|
2011-12-31 12:05:44 +08:00
|
|
|
OS.indent(Indent + 2);
|
|
|
|
OS << "requires ";
|
2013-10-29 06:18:19 +08:00
|
|
|
for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
|
2011-12-31 12:05:44 +08:00
|
|
|
if (I)
|
|
|
|
OS << ", ";
|
2013-10-29 06:18:19 +08:00
|
|
|
if (!Requirements[I].second)
|
|
|
|
OS << "!";
|
|
|
|
OS << Requirements[I].first;
|
2011-12-31 12:05:44 +08:00
|
|
|
}
|
|
|
|
OS << "\n";
|
|
|
|
}
|
2011-12-01 07:21:26 +08:00
|
|
|
|
2011-12-09 01:39:04 +08:00
|
|
|
if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
|
2011-12-01 07:21:26 +08:00
|
|
|
OS.indent(Indent + 2);
|
2011-12-09 02:00:48 +08:00
|
|
|
OS << "umbrella header \"";
|
2011-12-01 07:21:26 +08:00
|
|
|
OS.write_escaped(UmbrellaHeader->getName());
|
|
|
|
OS << "\"\n";
|
2011-12-09 02:00:48 +08:00
|
|
|
} else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) {
|
|
|
|
OS.indent(Indent + 2);
|
|
|
|
OS << "umbrella \"";
|
|
|
|
OS.write_escaped(UmbrellaDir->getName());
|
|
|
|
OS << "\"\n";
|
2011-12-01 07:21:26 +08:00
|
|
|
}
|
2013-03-20 08:22:05 +08:00
|
|
|
|
|
|
|
if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
|
|
|
|
OS.indent(Indent + 2);
|
|
|
|
OS << "config_macros ";
|
|
|
|
if (ConfigMacrosExhaustive)
|
2013-03-20 11:59:18 +08:00
|
|
|
OS << "[exhaustive]";
|
2013-03-20 08:22:05 +08:00
|
|
|
for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
|
|
|
|
if (I)
|
|
|
|
OS << ", ";
|
|
|
|
OS << ConfigMacros[I];
|
|
|
|
}
|
2013-03-20 11:59:18 +08:00
|
|
|
OS << "\n";
|
2013-03-20 08:22:05 +08:00
|
|
|
}
|
|
|
|
|
2013-06-21 05:14:14 +08:00
|
|
|
for (unsigned I = 0, N = NormalHeaders.size(); I != N; ++I) {
|
2011-12-01 07:21:26 +08:00
|
|
|
OS.indent(Indent + 2);
|
|
|
|
OS << "header \"";
|
2013-06-21 05:14:14 +08:00
|
|
|
OS.write_escaped(NormalHeaders[I]->getName());
|
2011-12-01 07:21:26 +08:00
|
|
|
OS << "\"\n";
|
|
|
|
}
|
2012-10-15 14:28:11 +08:00
|
|
|
|
|
|
|
for (unsigned I = 0, N = ExcludedHeaders.size(); I != N; ++I) {
|
|
|
|
OS.indent(Indent + 2);
|
|
|
|
OS << "exclude header \"";
|
|
|
|
OS.write_escaped(ExcludedHeaders[I]->getName());
|
|
|
|
OS << "\"\n";
|
|
|
|
}
|
2013-06-21 05:14:14 +08:00
|
|
|
|
|
|
|
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";
|
|
|
|
}
|
2011-12-01 07:21:26 +08:00
|
|
|
|
2012-01-05 07:32:19 +08:00
|
|
|
for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
|
2011-12-01 07:21:26 +08:00
|
|
|
MI != MIEnd; ++MI)
|
2012-01-05 07:32:19 +08:00
|
|
|
(*MI)->print(OS, Indent + 2);
|
2011-12-01 07:21:26 +08:00
|
|
|
|
2011-12-03 02:58:38 +08:00
|
|
|
for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
|
|
|
|
OS.indent(Indent + 2);
|
2011-12-06 01:34:59 +08:00
|
|
|
OS << "export ";
|
|
|
|
if (Module *Restriction = Exports[I].getPointer()) {
|
|
|
|
OS << Restriction->getFullModuleName();
|
|
|
|
if (Exports[I].getInt())
|
|
|
|
OS << ".*";
|
|
|
|
} else {
|
|
|
|
OS << "*";
|
|
|
|
}
|
2011-12-03 02:58:38 +08:00
|
|
|
OS << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
|
|
|
|
OS.indent(Indent + 2);
|
|
|
|
OS << "export ";
|
|
|
|
printModuleId(OS, UnresolvedExports[I].Id);
|
2011-12-06 01:34:59 +08:00
|
|
|
if (UnresolvedExports[I].Wildcard) {
|
|
|
|
if (UnresolvedExports[I].Id.empty())
|
|
|
|
OS << "*";
|
|
|
|
else
|
|
|
|
OS << ".*";
|
|
|
|
}
|
2011-12-03 02:58:38 +08:00
|
|
|
OS << "\n";
|
|
|
|
}
|
|
|
|
|
2013-09-24 17:14:14 +08:00
|
|
|
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";
|
|
|
|
}
|
|
|
|
|
2013-01-15 01:21:00 +08:00
|
|
|
for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
|
|
|
|
OS.indent(Indent + 2);
|
|
|
|
OS << "link ";
|
|
|
|
if (LinkLibraries[I].IsFramework)
|
|
|
|
OS << "framework ";
|
|
|
|
OS << "\"";
|
|
|
|
OS.write_escaped(LinkLibraries[I].Library);
|
|
|
|
OS << "\"";
|
|
|
|
}
|
|
|
|
|
2013-03-21 05:10:35 +08:00
|
|
|
for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
|
|
|
|
OS.indent(Indent + 2);
|
|
|
|
OS << "conflict ";
|
|
|
|
printModuleId(OS, UnresolvedConflicts[I].Id);
|
|
|
|
OS << ", \"";
|
|
|
|
OS.write_escaped(UnresolvedConflicts[I].Message);
|
|
|
|
OS << "\"\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
|
|
|
|
OS.indent(Indent + 2);
|
|
|
|
OS << "conflict ";
|
|
|
|
OS << Conflicts[I].Other->getFullModuleName();
|
|
|
|
OS << ", \"";
|
|
|
|
OS.write_escaped(Conflicts[I].Message);
|
|
|
|
OS << "\"\n";
|
|
|
|
}
|
|
|
|
|
2011-12-06 06:27:44 +08:00
|
|
|
if (InferSubmodules) {
|
|
|
|
OS.indent(Indent + 2);
|
|
|
|
if (InferExplicitSubmodules)
|
|
|
|
OS << "explicit ";
|
|
|
|
OS << "module * {\n";
|
|
|
|
if (InferExportWildcard) {
|
|
|
|
OS.indent(Indent + 4);
|
|
|
|
OS << "export *\n";
|
|
|
|
}
|
|
|
|
OS.indent(Indent + 2);
|
|
|
|
OS << "}\n";
|
|
|
|
}
|
|
|
|
|
2011-12-01 07:21:26 +08:00
|
|
|
OS.indent(Indent);
|
|
|
|
OS << "}\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void Module::dump() const {
|
|
|
|
print(llvm::errs());
|
|
|
|
}
|
|
|
|
|
|
|
|
|