]> granicus.if.org Git - clang/commitdiff
Keep track of which modules have been loaded directly (e.g., via
authorDouglas Gregor <dgregor@apple.com>
Thu, 18 Aug 2011 04:12:04 +0000 (04:12 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 18 Aug 2011 04:12:04 +0000 (04:12 +0000)
-import-module) vs. loaded because some other module depends on
them. As part of doing this, pass down the module that caused a module
to be loaded directly, rather than assuming that we're loading a
chain. Finally, write out all of the directly-loaded modules when
serializing an AST file (using the new IMPORTS record), so that an AST
file can depend on more than one other AST file, all of which will be
loaded when that AST file is loaded. This allows us to form and load a
tree of modules, but we can't yet load a DAG of modules.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137923 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Serialization/ASTReader.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp

index cbba16e6c1f2350f2cc909c6d64cc9445aa93e29..514d36db919c45462d1b660d7fd3c42361afd669 100644 (file)
@@ -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
index 1d7ea1346fca1680a35baad12f7942458341f1a1..d81e9d8a36a47a4198a8be78bc546f26bb97c981 100644 (file)
@@ -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;
index 91c68df4778754084e70201a9fb59b5784c9aa37..15a7cbc6284d81f18cccc8e8bef1ebfb3a95e728 100644 (file)
@@ -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;