jansvoboda11 updated this revision to Diff 472697.
jansvoboda11 added a comment.

Improve SourceLocation handling: invalid & inside predefines buffer.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137259/new/

https://reviews.llvm.org/D137259

Files:
  clang/include/clang/Frontend/CompilerInstance.h
  clang/lib/Frontend/CompilerInstance.cpp
  clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
  clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
  clang/test/ClangScanDeps/modules-basic.c

Index: clang/test/ClangScanDeps/modules-basic.c
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/modules-basic.c
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+//--- include/module.modulemap
+module m { header "m.h"}
+//--- include/m.h
+// empty
+
+//--- tu.c
+#include "m.h"
+
+//--- cdb.json.template
+[{
+  "file": "DIR/tu.c",
+  "directory": "DIR",
+  "command": "clang -fsyntax-only DIR/tu.c -fmodules -fmodules-cache-path=DIR/cache -fimplicit-module-maps -I DIR/include"
+}]
+
+// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
+
+// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full > %t/result.json
Index: clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
===================================================================
--- clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -424,6 +424,26 @@
     MD.ClangModuleMapFile = std::string(Path);
   }
 
+  if (MDC.ScanInstance.InMemoryModuleTransfer) {
+    for (const auto &E : MDC.ScanInstance.SortedFiles[M->getFullModuleName()]) {
+      if (E.FE->getName().endswith("__inferred_module.map")) {
+        MDC.addFileDep(MD, ModuleMap->getName());
+        continue;
+      }
+      MDC.addFileDep(MD, E.FE->getName());
+    }
+    if (M->NoUndeclaredIncludes) {
+      for (const auto &E : MDC.ScanInstance.SortedFiles[M->getFullModuleName()]) {
+        if (E.FE->getName().endswith("__inferred_module.map"))
+          continue;
+        // The top-level modulemap of this module will be the input file. We
+        // don't need to specify it as a module map.
+        if (E.FE == ModuleMap)
+          continue;
+        MD.ModuleMapFileDeps.push_back(E.FE->getName().str());
+      }
+    }
+  } else {
   serialization::ModuleFile *MF =
       MDC.ScanInstance.getASTReader()->getModuleManager().lookup(
           M->getASTFile());
@@ -452,12 +472,13 @@
           return;
         MD.ModuleMapFileDeps.emplace_back(FE->getName());
       });
+  }
 
   CompilerInvocation CI = MDC.makeInvocationForModuleBuildWithoutOutputs(
       MD, [&](CompilerInvocation &BuildInvocation) {
-        if (MDC.OptimizeArgs)
-          optimizeHeaderSearchOpts(BuildInvocation.getHeaderSearchOpts(),
-                                   *MDC.ScanInstance.getASTReader(), *MF);
+//        if (MDC.OptimizeArgs)
+//          optimizeHeaderSearchOpts(BuildInvocation.getHeaderSearchOpts(),
+//                                   *MDC.ScanInstance.getASTReader(), *MF);
       });
 
   MDC.associateWithContextHash(CI, MD);
Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
===================================================================
--- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -178,6 +178,8 @@
     CompilerInstance &ScanInstance = *ScanInstanceStorage;
     ScanInstance.setInvocation(std::move(Invocation));
 
+    ScanInstance.InMemoryModuleTransfer = true;
+
     // Create the compiler's actual diagnostics engine.
     sanitizeDiagOpts(ScanInstance.getDiagnosticOpts());
     ScanInstance.createDiagnostics(DiagConsumer, /*ShouldOwnClient=*/false);
Index: clang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- clang/lib/Frontend/CompilerInstance.cpp
+++ clang/lib/Frontend/CompilerInstance.cpp
@@ -1129,6 +1129,242 @@
   return LangOpts.CPlusPlus ? Language::CXX : Language::C;
 }
 
+class Translator {
+  CompilerInstance &A;
+  const CompilerInstance &B;
+
+  llvm::StringSet<> TranslatedModules;
+
+public:
+  Translator(CompilerInstance &A, const CompilerInstance &B) : A(A), B(B) {}
+
+  template <class T> Optional<T> translate(const Optional<T> &BO) {
+    if (!BO)
+      return None;
+    return translate(*BO);
+  }
+
+  template <class T> const T *translate(const T *BP) {
+    if (!BP)
+      return nullptr;
+    return &translate(*BP);
+  }
+
+  template <class T> T *translate(T *BP) {
+    if (!BP)
+      return nullptr;
+    return &translate(*BP);
+  }
+
+  template <class T, class U>
+  llvm::PointerUnion<T, U> translate(llvm::PointerUnion<T, U> BPU) {
+    if (!BPU)
+      return nullptr;
+    if (BPU.template is<T>())
+      return translate(BPU.template get<T>());
+    return translate(BPU.template get<U>());
+  }
+
+  template <class T, unsigned N>
+  SmallVector<T, N> translate(const SmallVector<T, N> &BV) {
+    SmallVector<T, N> AV;
+    AV.reserve(BV.size());
+    for (const T &Entry : BV)
+      AV.push_back(translate(Entry));
+    return AV;
+  }
+
+  template <class T, unsigned N>
+  llvm::SmallSetVector<T, N> translate(const llvm::SmallSetVector<T, N>& BSSV) {
+    llvm::SmallSetVector<T, N> ASSV;
+    for (const auto &Entry : BSSV)
+      ASSV.insert(translate(Entry));
+    return ASSV;
+  }
+
+  const FileEntry &translate(const FileEntry &BFE) {
+    return **A.getFileManager().getFile(BFE.getName());
+  }
+
+  FileEntryRef translate(FileEntryRef BFE) {
+    return *A.getFileManager().getOptionalFileRef(BFE.getName());
+  }
+
+  const DirectoryEntry &translate(const DirectoryEntry &BDE) {
+    return **A.getFileManager().getDirectory(BDE.getName());
+  }
+
+  SourceLocation translate(SourceLocation BLoc) {
+    if (BLoc.isInvalid())
+      return {};
+
+    auto &ASM = A.getSourceManager();
+    auto &BSM = B.getSourceManager();
+
+    auto &APP = A.getPreprocessor();
+    auto &BPP = B.getPreprocessor();
+
+    auto BOffset = BSM.getFileOffset(BLoc);
+    auto AOffset = BSM.getFileOffset(BLoc);
+
+    auto BFileID = BSM.getFileID(BLoc);
+    auto AFileID = [&]() {
+      if (BFileID == BPP.getPredefinesFileID())
+        return APP.getPredefinesFileID();
+
+      auto BFileCharacteristic = BSM.getFileCharacteristic(BLoc);
+      auto AFileCharacteristic = BFileCharacteristic;
+
+      auto *BFileEntry = BSM.getFileEntryForID(BFileID);
+      auto *AFileEntry = translate(BFileEntry);
+      return ASM.getOrCreateFileID(AFileEntry, AFileCharacteristic);
+    }();
+
+    return ASM.getComposedLoc(AFileID, AOffset);
+  }
+
+  Module::Header translate(const Module::Header &BHeader) {
+    return Module::Header{BHeader.NameAsWritten,
+                          BHeader.PathRelativeToRootModuleDirectory,
+                          translate(BHeader.Entry)};
+  }
+
+  std::vector<Module *> translate(Module::submodule_iterator Begin,
+                                  Module::submodule_iterator End) {
+    std::vector<Module *> ASubModules;
+    for (auto It = Begin; It != End; ++It)
+      ASubModules.push_back(translate(*It));
+    return ASubModules;
+  }
+
+  Module::UnresolvedHeaderDirective
+  translate(const Module::UnresolvedHeaderDirective &BD) {
+    return {BD.Kind, //
+            translate(BD.FileNameLoc),
+            BD.FileName,
+            BD.IsUmbrella,
+            BD.HasBuiltinHeader,
+            BD.Size,
+            BD.ModTime};
+  }
+
+  Module::ExportDecl translate(const Module::ExportDecl &BED) {
+    return {translate(BED.getPointer()), BED.getInt()};
+  }
+
+  ModuleId translate(const ModuleId &BId) {
+    ModuleId Res;
+    for (const auto &Element : BId)
+      Res.push_back({Element.first, translate(Element.second)});
+    return Res;
+  }
+
+  Module::UnresolvedExportDecl
+  translate(const Module::UnresolvedExportDecl &BUED) {
+    return {translate(BUED.ExportLoc), translate(BUED.Id), BUED.Wildcard};
+  }
+
+  Module::LinkLibrary translate(const Module::LinkLibrary &X) {
+    return X;
+  }
+
+  Module::UnresolvedConflict translate(const Module::UnresolvedConflict &X) {
+    return {translate(X.Id), X.Message};
+  }
+
+  Module::Conflict translate(const Module::Conflict &X) {
+    return {translate(X.Other), X.Message};
+  }
+
+  const Module &translate(const Module &BMod) {
+    return translate(const_cast<Module &>(BMod));
+  }
+
+  Module &translate(Module &BMod) {
+    auto &AModMap = A.getPreprocessor().getHeaderSearchInfo().getModuleMap();
+    auto &BHS = B.getPreprocessor().getHeaderSearchInfo();
+
+    auto [AMod, New] = AModMap.findOrCreateModule(
+        BMod.Name, translate(BMod.Parent),
+        BMod.IsFramework, BMod.IsExplicit);
+
+    if (!TranslatedModules.insert(BMod.Name).second)
+      return *AMod;
+
+    // Even if instance A already knows about module, it might not know
+    // information that's figured during compile of the module (e.g. imports).
+    if (!New) {
+      //      llvm::errs() << "translating existing module " << BMod.Name << "\n";
+    }
+
+    AMod->Kind = BMod.Kind;
+    AMod->Directory = translate(BMod.Directory);
+    AMod->PresumedModuleMapFile = BMod.PresumedModuleMapFile;
+    AMod->DefinitionLoc = translate(AMod->DefinitionLoc);
+    AMod->Umbrella = translate(BMod.Umbrella);
+    AMod->UmbrellaAsWritten = BMod.UmbrellaAsWritten;
+    AMod->UmbrellaRelativeToRootModuleDirectory = BMod.UmbrellaRelativeToRootModuleDirectory;
+    AMod->ExportAsModule = BMod.ExportAsModule;
+
+    for (Module *BSubMod : BMod.submodules())
+      translate(BSubMod);
+
+    for (const FileEntry *BTopHeader : BMod.getTopHeaders(B.getFileManager()))
+      AMod->addTopHeader(translate(BTopHeader));
+
+    // TODO: Propagate VisibilityID to other data structures.
+
+    for (auto Kind : {Module::HK_Normal, Module::HK_Textual, Module::HK_Private,
+                      Module::HK_PrivateTextual, Module::HK_Excluded}) {
+      for (const auto &BH : BMod.Headers[Kind]) {
+        const auto &AH = translate(BH);
+        AModMap.addHeader(AMod, AH, ModuleMap::headerKindToRole(Kind),
+                          BHS.getFileInfo(BH.Entry).isModuleHeader);
+      }
+    }
+
+    AMod->UnresolvedHeaders = translate(BMod.UnresolvedHeaders);
+    AMod->MissingHeaders = translate(BMod.MissingHeaders);
+    AMod->Requirements = BMod.Requirements;
+    AMod->ShadowingModule = translate(BMod.ShadowingModule);
+    AMod->IsUnimportable = BMod.IsUnimportable;
+    AMod->HasIncompatibleModuleFile = BMod.HasIncompatibleModuleFile;
+    AMod->IsAvailable = BMod.IsAvailable;
+    AMod->IsFromModuleFile = BMod.IsFromModuleFile;
+    AMod->IsFramework = BMod.IsFramework;
+    AMod->IsExplicit = BMod.IsExplicit;
+    AMod->IsSystem = BMod.IsSystem;
+    AMod->IsExternC = BMod.IsExternC;
+    AMod->IsInferred = BMod.IsInferred;
+    AMod->InferSubmodules = BMod.InferSubmodules;
+    AMod->InferExplicitSubmodules = BMod.InferExplicitSubmodules;
+    AMod->InferExportWildcard = BMod.InferExportWildcard;
+    AMod->ConfigMacrosExhaustive = BMod.ConfigMacrosExhaustive;
+    AMod->NoUndeclaredIncludes = BMod.NoUndeclaredIncludes;
+    AMod->ModuleMapIsPrivate = BMod.ModuleMapIsPrivate;
+    AMod->NameVisibility = BMod.NameVisibility;
+    AMod->InferredSubmoduleLoc = translate(BMod.InferredSubmoduleLoc);
+    AMod->Imports = translate(BMod.Imports);
+    AMod->Exports = translate(BMod.Exports);
+    AMod->UnresolvedExports = translate(BMod.UnresolvedExports);
+    AMod->DirectUses = translate(BMod.DirectUses);
+    AMod->UnresolvedDirectUses = translate(BMod.UnresolvedDirectUses);
+    AMod->UndeclaredUses = translate(BMod.UndeclaredUses);
+    AMod->LinkLibraries = translate(BMod.LinkLibraries);
+    AMod->UseExportAsModuleLinkName = BMod.UseExportAsModuleLinkName;
+    AMod->ConfigMacros = BMod.ConfigMacros;
+    AMod->UnresolvedConflicts = BMod.UnresolvedConflicts;
+    AMod->Conflicts = BMod.Conflicts;
+
+    return *AMod;
+  }
+
+  Module *translateModule(StringRef BName) {
+    return translate(
+        B.getPreprocessor().getHeaderSearchInfo().lookupModule(BName));
+  }
+};
+
 /// Compile a module file for the given module, using the options
 /// provided by the importing compiler instance. Returns true if the module
 /// was built without errors.
@@ -1246,6 +1482,8 @@
                                             diag::remark_module_build)
     << ModuleName << ModuleFileName;
 
+  Instance.InMemoryModuleTransfer = ImportingInstance.InMemoryModuleTransfer;
+
   PreBuildStep(Instance);
 
   // Execute the action to actually build the module in-place. Use a separate
@@ -1254,6 +1492,51 @@
       [&]() {
         GenerateModuleFromModuleMapAction Action;
         Instance.ExecuteAction(Action);
+
+        if (!ImportingInstance.InMemoryModuleTransfer)
+          return;
+
+        Translator T(ImportingInstance, Instance);
+        T.translateModule(ModuleName);
+        //        llvm::errs() << "translated " << ModuleName << "\n";
+
+        std::set<const FileEntry *> AffectingModuleMaps;
+        std::set<const FileEntry *> SkippedModuleMaps;
+
+        auto &SortedFiles = ImportingInstance.SortedFiles[ModuleName];
+        for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size(); I != N; ++I) {
+          // Get this source location entry.
+          const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(I);
+
+          // We only care about file entries that were not overridden.
+          if (!SLoc->isFile())
+            continue;
+          const SrcMgr::FileInfo &File = SLoc->getFile();
+          const SrcMgr::ContentCache *Cache = &File.getContentCache();
+          if (!Cache->OrigEntry)
+            continue;
+
+          if (isModuleMap(File.getFileCharacteristic()) &&
+              !isSystem(File.getFileCharacteristic()) &&
+              !AffectingModuleMaps.empty() &&
+              AffectingModuleMaps.find(Cache->OrigEntry) ==
+                  AffectingModuleMaps.end()) {
+            SkippedModuleMaps.insert(Cache->OrigEntry);
+            // Do not emit modulemaps that do not affect current module.
+            continue;
+          }
+
+          CompilerInstance::EntryStruct Entry{
+              T.translate(Cache->OrigEntry),
+              isSystem(File.getFileCharacteristic()),
+              isModuleMap(File.getFileCharacteristic()) &&
+                  File.getIncludeLoc().isInvalid()};
+
+          if (Entry.IsSystemFile)
+            SortedFiles.push_back(Entry);
+          else
+            SortedFiles.push_front(Entry);
+        }
       },
       DesiredStackSize);
 
@@ -1364,17 +1647,25 @@
                                       SourceLocation ModuleNameLoc,
                                       Module *Module, StringRef ModuleFileName,
                                       bool *OutOfDate) {
+  if (ImportingInstance.InMemoryModuleTransfer)
+    return true;
+
   DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics();
 
   unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing;
   if (OutOfDate)
     ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate;
 
+  llvm::errs() << "readASTAfterCompileModule " << Module << " " << Module->getFullModuleName() << " " << Module->Imports.size() << "\n";
+
   // Try to read the module file, now that we've compiled it.
   ASTReader::ASTReadResult ReadResult =
       ImportingInstance.getASTReader()->ReadAST(
           ModuleFileName, serialization::MK_ImplicitModule, ImportLoc,
           ModuleLoadCapabilities);
+
+  llvm::errs() << "readASTAfterCompileModule " << Module << " " << Module->getFullModuleName() << " " << Module->Imports.size() << "\n";
+
   if (ReadResult == ASTReader::Success)
     return true;
 
@@ -1799,6 +2090,8 @@
   Module *M =
       HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective);
 
+  assert(M && "no module in findOrCompileModuleAndReadAST");
+
   // Select the source and filename for loading the named module.
   std::string ModuleFilename;
   ModuleSource Source =
@@ -1938,7 +2231,7 @@
 
   // Try to compile and then read the AST.
   if (!compileModuleAndReadAST(*this, ImportLoc, ModuleNameLoc, M,
-                               ModuleFilename)) {
+                               ModuleFilename)) { //
     assert(getDiagnostics().hasErrorOccurred() &&
            "undiagnosed error in compileModuleAndReadAST");
     if (getPreprocessorOpts().FailedModules)
Index: clang/include/clang/Frontend/CompilerInstance.h
===================================================================
--- clang/include/clang/Frontend/CompilerInstance.h
+++ clang/include/clang/Frontend/CompilerInstance.h
@@ -179,6 +179,14 @@
   CompilerInstance(const CompilerInstance &) = delete;
   void operator=(const CompilerInstance &) = delete;
 public:
+  struct EntryStruct {
+    Optional<FileEntryRef> FE;
+    bool IsSystemFile;
+    bool IsTopLevelModuleMap;
+  };
+  llvm::StringMap<std::deque<EntryStruct>> SortedFiles;
+  bool InMemoryModuleTransfer;
+
   explicit CompilerInstance(
       std::shared_ptr<PCHContainerOperations> PCHContainerOps =
           std::make_shared<PCHContainerOperations>(),
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to