summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp71
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp29
-rw-r--r--clang/lib/Serialization/GlobalModuleIndex.cpp10
-rw-r--r--clang/lib/Serialization/ModuleManager.cpp5
4 files changed, 95 insertions, 20 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 1d1957d6bfe..ea3b8b6cd1d 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -1161,7 +1161,7 @@ std::pair<SourceLocation, StringRef> ASTReader::getModuleImportLoc(int ID) {
// FIXME: Can we map this down to a particular submodule? That would be
// ideal.
- return std::make_pair(M->ImportLoc, llvm::sys::path::stem(M->FileName));
+ return std::make_pair(M->ImportLoc, StringRef(M->ModuleName));
}
/// \brief Find the location where the module F is imported.
@@ -1172,14 +1172,10 @@ SourceLocation ASTReader::getImportLocation(ModuleFile *F) {
// Otherwise we have a PCH. It's considered to be "imported" at the first
// location of its includer.
if (F->ImportedBy.empty() || !F->ImportedBy[0]) {
- // Main file is the importer. We assume that it is the first entry in the
- // entry table. We can't ask the manager, because at the time of PCH loading
- // the main file entry doesn't exist yet.
- // The very first entry is the invalid instantiation loc, which takes up
- // offsets 0 and 1.
- return SourceLocation::getFromRawEncoding(2U);
- }
- //return F->Loaders[0]->FirstLoc;
+ // Main file is the importer.
+ assert(!SourceMgr.getMainFileID().isInvalid() && "missing main file");
+ return SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
+ }
return F->ImportedBy[0]->FirstLoc;
}
@@ -2089,6 +2085,7 @@ void ASTReader::MaybeAddSystemRootToFilename(ModuleFile &M,
ASTReader::ASTReadResult
ASTReader::ReadControlBlock(ModuleFile &F,
SmallVectorImpl<ImportedModule> &Loaded,
+ const ModuleFile *ImportedBy,
unsigned ClientLoadCapabilities) {
BitstreamCursor &Stream = F.Stream;
@@ -2314,6 +2311,44 @@ ASTReader::ReadControlBlock(ModuleFile &F,
F.OriginalDir = Blob;
break;
+ case MODULE_NAME:
+ F.ModuleName = Blob;
+ break;
+
+ case MODULE_MAP_FILE:
+ F.ModuleMapPath = Blob;
+
+ // Try to resolve ModuleName in the current header search context and
+ // verify that it is found in the same module map file as we saved. If the
+ // top-level AST file is a main file, skip this check because there is no
+ // usable header search context.
+ assert(!F.ModuleName.empty() &&
+ "MODULE_NAME should come before MOUDLE_MAP_FILE");
+ if (F.Kind == MK_Module &&
+ (*ModuleMgr.begin())->Kind != MK_MainFile) {
+ Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
+ if (!M) {
+ assert(ImportedBy && "top-level import should be verified");
+ if ((ClientLoadCapabilities & ARR_Missing) == 0)
+ Diag(diag::err_imported_module_not_found)
+ << F.ModuleName << ImportedBy->FileName;
+ return Missing;
+ }
+
+ const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath);
+ if (StoredModMap == nullptr || StoredModMap != M->ModuleMap) {
+ assert(M->ModuleMap && "found module is missing module map file");
+ assert(M->Name == F.ModuleName && "found module with different name");
+ assert(ImportedBy && "top-level import should be verified");
+ if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
+ Diag(diag::err_imported_module_modmap_changed)
+ << F.ModuleName << ImportedBy->FileName
+ << M->ModuleMap->getName() << F.ModuleMapPath;
+ return OutOfDate;
+ }
+ }
+ break;
+
case INPUT_FILE_OFFSETS:
F.InputFileOffsets = (const uint32_t *)Blob.data();
F.InputFilesLoaded.resize(Record[0]);
@@ -3537,7 +3572,7 @@ ASTReader::ReadASTCore(StringRef FileName,
break;
case CONTROL_BLOCK_ID:
HaveReadControlBlock = true;
- switch (ReadControlBlock(F, Loaded, ClientLoadCapabilities)) {
+ switch (ReadControlBlock(F, Loaded, ImportedBy, ClientLoadCapabilities)) {
case Success:
break;
@@ -4059,13 +4094,19 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
bool InferExportWildcard = Record[Idx++];
bool ConfigMacrosExhaustive = Record[Idx++];
- Module *ParentModule = 0;
- if (Parent)
+ Module *ParentModule = nullptr;
+ const FileEntry *ModuleMap = nullptr;
+ if (Parent) {
ParentModule = getSubmodule(Parent);
-
+ ModuleMap = ParentModule->ModuleMap;
+ }
+
+ if (!F.ModuleMapPath.empty())
+ ModuleMap = FileMgr.getFile(F.ModuleMapPath);
+
// Retrieve this (sub)module from the module map, creating it if
// necessary.
- CurrentModule = ModMap.findOrCreateModule(Name, ParentModule,
+ CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, ModuleMap,
IsFramework,
IsExplicit).first;
SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;
@@ -4090,7 +4131,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
CurrentModule->setASTFile(F.File);
}
-
+
CurrentModule->IsFromModuleFile = true;
CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
CurrentModule->IsExternC = IsExternC;
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 99f0b5c5662..96a254ae9a5 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -798,6 +798,8 @@ void ASTWriter::WriteBlockInfoBlock() {
// Control Block.
BLOCK(CONTROL_BLOCK);
RECORD(METADATA);
+ RECORD(MODULE_NAME);
+ RECORD(MODULE_MAP_FILE);
RECORD(IMPORTS);
RECORD(LANGUAGE_OPTIONS);
RECORD(TARGET_OPTIONS);
@@ -1050,6 +1052,32 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record,
getClangFullRepositoryVersion());
+ // Module name
+ if (WritingModule) {
+ BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
+ unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
+ RecordData Record;
+ Record.push_back(MODULE_NAME);
+ Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name);
+ }
+
+ // Module map file
+ if (WritingModule) {
+ BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(MODULE_MAP_FILE));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Filename
+ unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
+
+ assert(WritingModule->ModuleMap && "missing module map");
+ SmallString<128> ModuleMap(WritingModule->ModuleMap->getName());
+ llvm::sys::fs::make_absolute(ModuleMap);
+ RecordData Record;
+ Record.push_back(MODULE_MAP_FILE);
+ Stream.EmitRecordWithBlob(AbbrevCode, Record, ModuleMap.str());
+ }
+
// Imports
if (Chain) {
serialization::ModuleManager &Mgr = Chain->getModuleManager();
@@ -1065,7 +1093,6 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
AddSourceLocation((*M)->ImportLoc, Record);
Record.push_back((*M)->File->getSize());
Record.push_back((*M)->File->getModificationTime());
- // FIXME: This writes the absolute path for AST files we depend on.
const std::string &FileName = (*M)->FileName;
Record.push_back(FileName.size());
Record.append(FileName.begin(), FileName.end());
diff --git a/clang/lib/Serialization/GlobalModuleIndex.cpp b/clang/lib/Serialization/GlobalModuleIndex.cpp
index 804a14363a8..9ebb0ad5e59 100644
--- a/clang/lib/Serialization/GlobalModuleIndex.cpp
+++ b/clang/lib/Serialization/GlobalModuleIndex.cpp
@@ -14,6 +14,7 @@
#include "ASTReaderInternals.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/OnDiskHashTable.h"
+#include "clang/Lex/HeaderSearch.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/GlobalModuleIndex.h"
#include "clang/Serialization/Module.h"
@@ -203,7 +204,12 @@ GlobalModuleIndex::GlobalModuleIndex(llvm::MemoryBuffer *Buffer,
assert(Idx == Record.size() && "More module info?");
// Record this module as an unresolved module.
- UnresolvedModules[llvm::sys::path::stem(Modules[ID].FileName)] = ID;
+ // FIXME: this doesn't work correctly for module names containing path
+ // separators.
+ StringRef ModuleName = llvm::sys::path::stem(Modules[ID].FileName);
+ // Remove the -<hash of ModuleMapPath>
+ ModuleName = ModuleName.rsplit('-').first;
+ UnresolvedModules[ModuleName] = ID;
break;
}
@@ -308,7 +314,7 @@ bool GlobalModuleIndex::lookupIdentifier(StringRef Name, HitSet &Hits) {
bool GlobalModuleIndex::loadedModuleFile(ModuleFile *File) {
// Look for the module in the global module index based on the module name.
- StringRef Name = llvm::sys::path::stem(File->FileName);
+ StringRef Name = File->ModuleName;
llvm::StringMap<unsigned>::iterator Known = UnresolvedModules.find(Name);
if (Known == UnresolvedModules.end()) {
return true;
diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp
index 3513eba8602..c36d902deb7 100644
--- a/clang/lib/Serialization/ModuleManager.cpp
+++ b/clang/lib/Serialization/ModuleManager.cpp
@@ -11,6 +11,7 @@
// modules for the ASTReader.
//
//===----------------------------------------------------------------------===//
+#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Serialization/GlobalModuleIndex.h"
#include "clang/Serialization/ModuleManager.h"
@@ -155,7 +156,7 @@ void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last,
FileMgr.invalidateCache((*victim)->File);
if (modMap) {
- StringRef ModuleName = llvm::sys::path::stem((*victim)->FileName);
+ StringRef ModuleName = (*victim)->ModuleName;
if (Module *mod = modMap->findModule(ModuleName)) {
mod->setASTFile(0);
}
@@ -429,7 +430,7 @@ namespace llvm {
}
std::string getNodeLabel(ModuleFile *M, const ModuleManager&) {
- return llvm::sys::path::stem(M->FileName);
+ return M->ModuleName;
}
};
}
OpenPOWER on IntegriCloud