diff options
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 71 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 29 | ||||
-rw-r--r-- | clang/lib/Serialization/GlobalModuleIndex.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Serialization/ModuleManager.cpp | 5 |
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; } }; } |