benlangmuir updated this revision to Diff 450313. benlangmuir added a comment. Herald added a subscriber: ormris.
Attempt to fix test failure seen on Windows. It revealed two bugs - Avoid reusing the FileManager at the top-level in clang-scan-deps to make the test behave as expected - Make the FileManager return the cached redirecting entry, to match how it behaves when it's a new file, and test this case explicitly. I think it was mostly luck of exactly which file lookups happen that we didn't hit this on other platforms. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D131076/new/ https://reviews.llvm.org/D131076 Files: clang/include/clang/Driver/Options.td clang/include/clang/Frontend/FrontendOptions.h clang/lib/Basic/FileManager.cpp clang/lib/Frontend/CompilerInstance.cpp clang/test/ClangScanDeps/modulemap-via-vfs.m clang/test/Modules/submodule-in-private-mmap-vfs.m clang/test/VFS/module-import.m clang/unittests/Basic/FileManagerTest.cpp
Index: clang/unittests/Basic/FileManagerTest.cpp =================================================================== --- clang/unittests/Basic/FileManagerTest.cpp +++ clang/unittests/Basic/FileManagerTest.cpp @@ -340,6 +340,7 @@ auto F1Again = manager.getFileRef("dir/f1.cpp"); auto F1Also = manager.getFileRef("dir/f1-also.cpp"); auto F1Redirect = manager.getFileRef("dir/f1-redirect.cpp"); + auto F1RedirectAgain = manager.getFileRef("dir/f1-redirect.cpp"); auto F2 = manager.getFileRef("dir/f2.cpp"); // Check Expected<FileEntryRef> for error. @@ -347,6 +348,7 @@ ASSERT_FALSE(!F1Also); ASSERT_FALSE(!F1Again); ASSERT_FALSE(!F1Redirect); + ASSERT_FALSE(!F1RedirectAgain); ASSERT_FALSE(!F2); // Check names. @@ -354,6 +356,7 @@ EXPECT_EQ("dir/f1.cpp", F1Again->getName()); EXPECT_EQ("dir/f1-also.cpp", F1Also->getName()); EXPECT_EQ("dir/f1.cpp", F1Redirect->getName()); + EXPECT_EQ("dir/f1.cpp", F1RedirectAgain->getName()); EXPECT_EQ("dir/f2.cpp", F2->getName()); EXPECT_EQ("dir/f1.cpp", F1->getNameAsRequested()); @@ -363,6 +366,7 @@ EXPECT_EQ(&F1->getFileEntry(), *F1); EXPECT_EQ(*F1, &F1->getFileEntry()); EXPECT_EQ(&F1->getFileEntry(), &F1Redirect->getFileEntry()); + EXPECT_EQ(&F1->getFileEntry(), &F1RedirectAgain->getFileEntry()); EXPECT_NE(&F2->getFileEntry(), *F1); EXPECT_NE(*F1, &F2->getFileEntry()); @@ -371,6 +375,7 @@ EXPECT_EQ(*F1, *F1Again); EXPECT_EQ(*F1, *F1Redirect); EXPECT_EQ(*F1Also, *F1Redirect); + EXPECT_EQ(*F1, *F1RedirectAgain); EXPECT_NE(*F2, *F1); EXPECT_NE(*F2, *F1Also); EXPECT_NE(*F2, *F1Again); @@ -381,6 +386,7 @@ EXPECT_FALSE(F1->isSameRef(*F1Redirect)); EXPECT_FALSE(F1->isSameRef(*F1Also)); EXPECT_FALSE(F1->isSameRef(*F2)); + EXPECT_TRUE(F1Redirect->isSameRef(*F1RedirectAgain)); } // getFile() Should return the same entry as getVirtualFile if the file actually Index: clang/test/VFS/module-import.m =================================================================== --- clang/test/VFS/module-import.m +++ clang/test/VFS/module-import.m @@ -1,6 +1,7 @@ -// RUN: rm -rf %t +// RUN: rm -rf %t %t-unshared // RUN: sed -e "s@INPUT_DIR@%{/S:regex_replacement}/Inputs@g" -e "s@OUT_DIR@%{/t:regex_replacement}@g" %S/Inputs/vfsoverlay.yaml > %t.yaml // RUN: %clang_cc1 -Werror -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ivfsoverlay %t.yaml -I %t -fsyntax-only %s +// RUN: %clang_cc1 -Werror -fmodules -fno-modules-share-filemanager -fimplicit-module-maps -fmodules-cache-path=%t-unshared -ivfsoverlay %t.yaml -I %t -fsyntax-only %s @import not_real; @@ -18,9 +19,12 @@ // Override the module map (vfsoverlay2 on top) // RUN: sed -e "s@INPUT_DIR@%{/S:regex_replacement}/Inputs@g" -e "s@OUT_DIR@%{/t:regex_replacement}@g" %S/Inputs/vfsoverlay2.yaml > %t2.yaml // RUN: %clang_cc1 -Werror -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -I %t -fsyntax-only %s +// RUN: %clang_cc1 -Werror -fmodules -fno-modules-share-filemanager -fimplicit-module-maps -fmodules-cache-path=%t-unshared -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -I %t -fsyntax-only %s // vfsoverlay2 not present // RUN: not %clang_cc1 -Werror -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ivfsoverlay %t.yaml -I %t -fsyntax-only %s -DIMPORT2 2>&1 | FileCheck -check-prefix=CHECK-VFS2 %s +// RUN: not %clang_cc1 -Werror -fmodules -fno-modules-share-filemanager -fimplicit-module-maps -fmodules-cache-path=%t-unshared -ivfsoverlay %t.yaml -I %t -fsyntax-only %s -DIMPORT2 2>&1 | FileCheck -check-prefix=CHECK-VFS2 %s // vfsoverlay2 on the bottom // RUN: not %clang_cc1 -Werror -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ivfsoverlay %t2.yaml -ivfsoverlay %t.yaml -I %t -fsyntax-only %s -DIMPORT2 2>&1 | FileCheck -check-prefix=CHECK-VFS2 %s +// RUN: not %clang_cc1 -Werror -fmodules -fno-modules-share-filemanager -fimplicit-module-maps -fmodules-cache-path=%t-unshared -ivfsoverlay %t2.yaml -ivfsoverlay %t.yaml -I %t -fsyntax-only %s -DIMPORT2 2>&1 | FileCheck -check-prefix=CHECK-VFS2 %s Index: clang/test/Modules/submodule-in-private-mmap-vfs.m =================================================================== --- /dev/null +++ clang/test/Modules/submodule-in-private-mmap-vfs.m @@ -0,0 +1,38 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DIR|%/t|g" %t/vfs.json.in > %t/vfs.json +// RUN: %clang_cc1 -fmodules -fno-modules-share-filemanager -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t -I%t/Virtual -ivfsoverlay %t/vfs.json -fsyntax-only %t/tu.m -verify + +//--- Dir1/module.modulemap + +//--- Dir2/module.private.modulemap +module Foo_Private {} + +//--- vfs.json.in +{ + 'version': 0, + 'use-external-names': true, + 'roots': [ + { + 'name': 'DIR/Virtual', + 'type': 'directory', + 'contents': [ + { + 'name': 'module.modulemap', + 'type': 'file', + 'external-contents': 'DIR/Dir1/module.modulemap' + }, + { + 'name': 'module.private.modulemap', + 'type': 'file', + 'external-contents': 'DIR/Dir2/module.private.modulemap' + } + ] + } + ] +} + +//--- tu.m +@import Foo_Private; +// expected-no-diagnostics Index: clang/test/ClangScanDeps/modulemap-via-vfs.m =================================================================== --- clang/test/ClangScanDeps/modulemap-via-vfs.m +++ clang/test/ClangScanDeps/modulemap-via-vfs.m @@ -2,13 +2,15 @@ // RUN: split-file %s %t.dir // RUN: sed -e "s|DIR|%/t.dir|g" %t.dir/build/compile-commands.json.in > %t.dir/build/compile-commands.json // RUN: sed -e "s|DIR|%/t.dir|g" %t.dir/build/vfs.yaml.in > %t.dir/build/vfs.yaml -// RUN: clang-scan-deps -compilation-database %t.dir/build/compile-commands.json -j 1 -format experimental-full \ +// RUN: clang-scan-deps -compilation-database %t.dir/build/compile-commands.json \ +// RUN: -reuse-filemanager=0 -j 1 -format experimental-full \ // RUN: -mode preprocess-dependency-directives -generate-modules-path-args > %t.db // RUN: %deps-to-rsp %t.db --module-name=A > %t.A.cc1.rsp // RUN: cat %t.A.cc1.rsp | sed 's:\\\\\?:/:g' | FileCheck %s // CHECK-NOT: build/module.modulemap // CHECK: A/module.modulemap +// CHECK-NOT: build/module.modulemap //--- build/compile-commands.json.in @@ -17,6 +19,11 @@ "directory": "DIR", "command": "clang DIR/main.m -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -ivfsoverlay build/vfs.yaml", "file": "DIR/main.m" +}, +{ + "directory": "DIR", + "command": "clang DIR/main.m -Imodules/A -fmodules -Xclang -fno-modules-share-filemanager -fmodules-cache-path=DIR/module-cache-unshared -fimplicit-modules -fimplicit-module-maps -ivfsoverlay build/vfs.yaml", + "file": "DIR/main.m" } ] @@ -35,6 +42,7 @@ { "version": 0, "case-sensitive": "false", + "use-external-names": true, "roots": [ { "contents": [ Index: clang/lib/Frontend/CompilerInstance.cpp =================================================================== --- clang/lib/Frontend/CompilerInstance.cpp +++ clang/lib/Frontend/CompilerInstance.cpp @@ -1213,11 +1213,16 @@ ImportingInstance.getDiagnosticClient()), /*ShouldOwnClient=*/true); - // Note that this module is part of the module build stack, so that we - // can detect cycles in the module graph. - Instance.setFileManager(&ImportingInstance.getFileManager()); + if (FrontendOpts.ModulesShareFileManager) { + Instance.setFileManager(&ImportingInstance.getFileManager()); + } else { + Instance.createFileManager(&ImportingInstance.getVirtualFileSystem()); + } Instance.createSourceManager(Instance.getFileManager()); SourceManager &SourceMgr = Instance.getSourceManager(); + + // Note that this module is part of the module build stack, so that we + // can detect cycles in the module graph. SourceMgr.setModuleBuildStack( ImportingInstance.getSourceManager().getModuleBuildStack()); SourceMgr.pushModuleBuildStack(ModuleName, @@ -1303,12 +1308,16 @@ ModuleMapFile, ImportingInstance.getFileManager())) ModuleMapFile = PublicMMFile; + // FIXME: Update header search to keep FileEntryRef rather than rely on + // getLastRef(). + StringRef ModuleMapFilePath = + ModuleMapFile->getLastRef().getNameAsRequested(); + // Use the module map where this module resides. Result = compileModuleImpl( ImportingInstance, ImportLoc, Module->getTopLevelModuleName(), - FrontendInputFile(ModuleMapFile->getName(), IK, +Module->IsSystem), - ModMap.getModuleMapFileForUniquing(Module)->getName(), - ModuleFileName); + FrontendInputFile(ModuleMapFilePath, IK, +Module->IsSystem), + ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName); } else { // FIXME: We only need to fake up an input file here as a way of // transporting the module's directory to the module map parser. We should Index: clang/lib/Basic/FileManager.cpp =================================================================== --- clang/lib/Basic/FileManager.cpp +++ clang/lib/Basic/FileManager.cpp @@ -212,13 +212,7 @@ if (!SeenFileInsertResult.first->second) return llvm::errorCodeToError( SeenFileInsertResult.first->second.getError()); - // Construct and return and FileEntryRef, unless it's a redirect to another - // filename. - FileEntryRef::MapValue Value = *SeenFileInsertResult.first->second; - if (LLVM_LIKELY(Value.V.is<FileEntry *>())) - return FileEntryRef(*SeenFileInsertResult.first); - return FileEntryRef(*reinterpret_cast<const FileEntryRef::MapEntry *>( - Value.V.get<const void *>())); + return FileEntryRef(*SeenFileInsertResult.first); } // We've not seen this before. Fill it in. Index: clang/include/clang/Frontend/FrontendOptions.h =================================================================== --- clang/include/clang/Frontend/FrontendOptions.h +++ clang/include/clang/Frontend/FrontendOptions.h @@ -356,6 +356,9 @@ /// Output (and read) PCM files regardless of compiler errors. unsigned AllowPCMWithCompilerErrors : 1; + /// Whether to share the FileManager when building modules. + unsigned ModulesShareFileManager : 1; + CodeCompleteOptions CodeCompleteOpts; /// Specifies the output format of the AST. @@ -523,7 +526,7 @@ BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false), IncludeTimestamps(true), UseTemporary(true), OutputPathIndependentPCM(false), AllowPCMWithCompilerErrors(false), - TimeTraceGranularity(500) {} + ModulesShareFileManager(true), TimeTraceGranularity(500) {} /// getInputKindForExtension - Return the appropriate input kind for a file /// extension. For example, "c" would return Language::C. Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -6028,6 +6028,9 @@ Flag<["-"], "fallow-pch-with-different-modules-cache-path">, HelpText<"Accept a PCH file that was created with a different modules cache path">, MarshallingInfoFlag<PreprocessorOpts<"AllowPCHWithDifferentModulesCachePath">>; +def fno_modules_share_filemanager : Flag<["-"], "fno-modules-share-filemanager">, + HelpText<"Disable sharing the FileManager when building a module implicitly">, + MarshallingInfoNegativeFlag<FrontendOpts<"ModulesShareFileManager">>; def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">, HelpText<"Dump declarations that are deserialized from PCH, for testing">, MarshallingInfoFlag<PreprocessorOpts<"DumpDeserializedPCHDecls">>;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits