aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-08-19 02:29:29 +0000
committerDouglas Gregor <dgregor@apple.com>2011-08-19 02:29:29 +0000
commitfac4ece118d43e43e625c6d2b9a98905b1372d51 (patch)
treef0a8c94c98c60c9affc12a55286ffaecfa65556f /lib/Serialization
parent3b030a28cda2b953758507769c1d436bec5ec45e (diff)
Teach ModuleManager::addModule() to check whether a particular module
has already been loaded before allocating a new Module structure. If the module has already been loaded (uniquing based on file name), then just return the existing module rather than trying to load it again. This allows us to load a DAG of modules. Introduce a simple test case that forms a diamond-shaped module graph, and illustrates that a source file importing the bottom of the diamond can see declarations in all four of the modules that make up the diamond. Note that this version moves the file-opening logic into the module manager, rather than splitting it between the module manager and the AST reader. More importantly, it properly handles the weird-but-possibly-useful case of loading an AST file from "-". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138030 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization')
-rw-r--r--lib/Serialization/ASTReader.cpp104
1 files changed, 66 insertions, 38 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index d81e9d8a36..840b665cd7 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -2831,37 +2831,33 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName,
ModuleKind Type,
Module *ImportedBy) {
- Module &F = ModuleMgr.addModule(FileName, Type, ImportedBy);
+ Module *M;
+ bool NewModule;
+ std::string ErrorStr;
+ llvm::tie(M, NewModule) = ModuleMgr.addModule(FileName, Type, ImportedBy,
+ ErrorStr);
+
+ if (!M) {
+ // We couldn't load the module.
+ std::string Msg = "Unable to load module \"" + FileName.str() + "\": "
+ + ErrorStr;
+ Error(Msg);
+ return Failure;
+ }
+
+ if (!NewModule) {
+ // We've already loaded this module.
+ return Success;
+ }
+ // FIXME: This seems rather a hack. Should CurrentDir be part of the
+ // module?
if (FileName != "-") {
CurrentDir = llvm::sys::path::parent_path(FileName);
if (CurrentDir.empty()) CurrentDir = ".";
}
- if (llvm::MemoryBuffer *Buffer = ModuleMgr.lookupBuffer(FileName)) {
- F.Buffer.reset(Buffer);
- assert(F.Buffer && "Passed null buffer");
- } else {
- // Open the AST file.
- //
- // FIXME: This shouldn't be here, we should just take a raw_ostream.
- std::string ErrStr;
- llvm::error_code ec;
- if (FileName == "-") {
- ec = llvm::MemoryBuffer::getSTDIN(F.Buffer);
- if (ec)
- ErrStr = ec.message();
- } else
- F.Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrStr));
- if (!F.Buffer) {
- Error(ErrStr.c_str());
- return IgnorePCH;
- }
- }
-
- // Initialize the stream
- F.StreamFile.init((const unsigned char *)F.Buffer->getBufferStart(),
- (const unsigned char *)F.Buffer->getBufferEnd());
+ Module &F = *M;
llvm::BitstreamCursor &Stream = F.Stream;
Stream.init(F.StreamFile);
F.SizeInBits = F.Buffer->getBufferSize() * 8;
@@ -5709,25 +5705,57 @@ llvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) {
return InMemoryBuffers[Entry];
}
-/// \brief Creates a new module and adds it to the list of known modules
-Module &ModuleManager::addModule(StringRef FileName, ModuleKind Type,
- Module *ImportedBy) {
- Module *Current = new Module(Type);
- Current->FileName = FileName.str();
- Chain.push_back(Current);
-
+std::pair<Module *, bool>
+ModuleManager::addModule(StringRef FileName, ModuleKind Type,
+ Module *ImportedBy, std::string &ErrorStr) {
const FileEntry *Entry = FileMgr.getFile(FileName);
- // FIXME: Check whether we already loaded this module, before
- Modules[Entry] = Current;
+ if (!Entry && FileName != "-") {
+ ErrorStr = "file not found";
+ return std::make_pair(static_cast<Module*>(0), false);
+ }
+
+ // Check whether we already loaded this module, before
+ Module *&ModuleEntry = Modules[Entry];
+ bool NewModule = false;
+ if (!ModuleEntry) {
+ // Allocate a new module.
+ Module *New = new Module(Type);
+ New->FileName = FileName.str();
+ Chain.push_back(New);
+ NewModule = true;
+ ModuleEntry = New;
+
+ // Load the contents of the module
+ if (llvm::MemoryBuffer *Buffer = lookupBuffer(FileName)) {
+ // The buffer was already provided for us.
+ assert(Buffer && "Passed null buffer");
+ New->Buffer.reset(Buffer);
+ } else {
+ // Open the AST file.
+ llvm::error_code ec;
+ if (FileName == "-") {
+ ec = llvm::MemoryBuffer::getSTDIN(New->Buffer);
+ if (ec)
+ ErrorStr = ec.message();
+ } else
+ New->Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrorStr));
+
+ if (!New->Buffer)
+ return std::make_pair(static_cast<Module*>(0), false);
+ }
+
+ // Initialize the stream
+ New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(),
+ (const unsigned char *)New->Buffer->getBufferEnd()); }
if (ImportedBy) {
- Current->ImportedBy.insert(ImportedBy);
- ImportedBy->Imports.insert(Current);
+ ModuleEntry->ImportedBy.insert(ImportedBy);
+ ImportedBy->Imports.insert(ModuleEntry);
} else {
- Current->DirectlyImported = true;
+ ModuleEntry->DirectlyImported = true;
}
- return *Current;
+ return std::make_pair(ModuleEntry, NewModule);
}
void ModuleManager::addInMemoryBuffer(StringRef FileName,