diff options
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 29 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 28 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 35 |
3 files changed, 59 insertions, 33 deletions
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index cbba16e6c1..514d36db91 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -190,6 +190,10 @@ public: /// \brief The file name of the module file. std::string FileName; + /// \brief Whether this module has been directly imported by the + /// user. + bool DirectlyImported; + /// \brief The memory buffer that stores the data associated with /// this AST file. llvm::OwningPtr<llvm::MemoryBuffer> Buffer; @@ -418,7 +422,11 @@ public: /// \brief List of modules which this module depends on llvm::SetVector<Module *> Imports; - + + /// \brief Determine whether this module was directly imported at + /// any point during translation. + bool isDirectlyImported() const { return DirectlyImported; } + /// \brief Dump debugging output for this module. void dump(); }; @@ -490,8 +498,17 @@ public: /// \brief Number of modules loaded unsigned size() const { return Chain.size(); } - /// \brief Creates a new module and adds it to the list of known modules - Module &addModule(StringRef FileName, ModuleKind Type); + /// \brief Attempts to create a new module and add it to the list of known + /// modules. + /// + /// \param FileName The file name of the module to be loaded. + /// + /// \param Type The kind of module being loaded. + /// + /// \param ImportedBy The module that is importing this module, or NULL if + /// this module is imported directly by the user. + Module &addModule(StringRef FileName, ModuleKind Type, + Module *ImportedBy); /// \brief Add an in-memory buffer the list of known buffers void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer); @@ -1007,7 +1024,8 @@ private: void MaybeAddSystemRootToFilename(std::string &Filename); - ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type); + ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type, + Module *ImportedBy); ASTReadResult ReadASTBlock(Module &F); bool CheckPredefinesBuffers(); bool ParseLineTable(Module &F, SmallVectorImpl<uint64_t> &Record); @@ -1104,8 +1122,7 @@ public: bool DisableValidation = false, bool DisableStatCache = false); ~ASTReader(); - /// \brief Load the precompiled header designated by the given file - /// name. + /// \brief Load the AST file designated by the given file name. ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type); /// \brief Checks that no file that is stored in PCH is out-of-sync with diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 1d7ea1346f..d81e9d8a36 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2045,7 +2045,7 @@ ASTReader::ReadASTBlock(Module &F) { Idx += Length; // Load the AST file. - switch(ReadASTCore(ImportedFile, ImportedKind)) { + switch(ReadASTCore(ImportedFile, ImportedKind, &F)) { case Failure: return Failure; // If we have to ignore the dependency, we'll have to ignore this too. case IgnorePCH: return IgnorePCH; @@ -2724,7 +2724,7 @@ ASTReader::ASTReadResult ASTReader::validateFileEntries() { ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, ModuleKind Type) { - switch(ReadASTCore(FileName, Type)) { + switch(ReadASTCore(FileName, Type, /*ImportedBy=*/0)) { case Failure: return Failure; case IgnorePCH: return IgnorePCH; case Success: break; @@ -2829,8 +2829,9 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, } ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName, - ModuleKind Type) { - Module &F = ModuleMgr.addModule(FileName, Type); + ModuleKind Type, + Module *ImportedBy) { + Module &F = ModuleMgr.addModule(FileName, Type, ImportedBy); if (FileName != "-") { CurrentDir = llvm::sys::path::parent_path(FileName); @@ -5610,7 +5611,8 @@ ASTReader::~ASTReader() { } Module::Module(ModuleKind Kind) - : Kind(Kind), SizeInBits(0), LocalNumSLocEntries(0), SLocEntryBaseID(0), + : Kind(Kind), DirectlyImported(false), SizeInBits(0), + LocalNumSLocEntries(0), SLocEntryBaseID(0), SLocEntryBaseOffset(0), SLocEntryOffsets(0), SLocFileOffsets(0), LocalNumIdentifiers(0), IdentifierOffsets(0), BaseIdentifierID(0), IdentifierTableData(0), @@ -5708,19 +5710,21 @@ llvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) { } /// \brief Creates a new module and adds it to the list of known modules -Module &ModuleManager::addModule(StringRef FileName, ModuleKind Type) { - Module *Prev = !size() ? 0 : &getLastModule(); +Module &ModuleManager::addModule(StringRef FileName, ModuleKind Type, + Module *ImportedBy) { Module *Current = new Module(Type); - Current->FileName = FileName.str(); - Chain.push_back(Current); + const FileEntry *Entry = FileMgr.getFile(FileName); + // FIXME: Check whether we already loaded this module, before Modules[Entry] = Current; - if (Prev) { - Current->ImportedBy.insert(Prev); - Prev->Imports.insert(Current); + if (ImportedBy) { + Current->ImportedBy.insert(ImportedBy); + ImportedBy->Imports.insert(Current); + } else { + Current->DirectlyImported = true; } return *Current; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 91c68df477..15a7cbc628 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -972,18 +972,23 @@ void ASTWriter::WriteMetadata(ASTContext &Context, StringRef isysroot, Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, Triple); if (Chain) { - // FIXME: Add all of the "directly imported" modules, not just - // "the one we're chaining to". serialization::ModuleManager &Mgr = Chain->getModuleManager(); llvm::SmallVector<char, 128> ModulePaths; Record.clear(); - Module &PrimaryModule = Mgr.getPrimaryModule(); - Record.push_back((unsigned)PrimaryModule.Kind); // FIXME: Stable encoding - // FIXME: Write import location, once it matters. - // FIXME: This writes the absolute path for AST files we depend on. - const std::string &MainFileName = PrimaryModule.FileName; - Record.push_back(MainFileName.size()); - Record.append(MainFileName.begin(), MainFileName.end()); + + for (ModuleManager::ModuleIterator M = Mgr.begin(), MEnd = Mgr.end(); + M != MEnd; ++M) { + // Skip modules that weren't directly imported. + if (!(*M)->isDirectlyImported()) + continue; + + Record.push_back((unsigned)(*M)->Kind); // FIXME: Stable encoding + // FIXME: Write import location, once it matters. + // 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()); + } Stream.EmitRecord(IMPORTS, Record); } @@ -3855,7 +3860,7 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec void ASTWriter::ReaderInitialized(ASTReader *Reader) { assert(Reader && "Cannot remove chain"); - assert(!Chain && "Cannot replace chain"); + assert((!Chain || Chain == Reader) && "Cannot replace chain"); assert(FirstDeclID == NextDeclID && FirstTypeID == NextTypeID && FirstIdentID == NextIdentID && @@ -3865,11 +3870,11 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) { Chain = Reader; - FirstDeclID += Chain->getTotalNumDecls(); - FirstTypeID += Chain->getTotalNumTypes(); - FirstIdentID += Chain->getTotalNumIdentifiers(); - FirstSelectorID += Chain->getTotalNumSelectors(); - FirstMacroID += Chain->getTotalNumMacroDefinitions(); + FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls(); + FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes(); + FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers(); + FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors(); + FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacroDefinitions(); NextDeclID = FirstDeclID; NextTypeID = FirstTypeID; NextIdentID = FirstIdentID; |