@@ -518,6 +518,52 @@ export int B = 44 + M;
518
518
EXPECT_EQ (HSOptsA.PrebuiltModuleFiles , HSOptsB.PrebuiltModuleFiles );
519
519
}
520
520
521
+ TEST_F (PrerequisiteModulesTests, DeduplicateReusablePrerequisiteModulesTest) {
522
+ MockDirectoryCompilationDatabase CDB (TestDir, FS);
523
+
524
+ CDB.addFile (" M.cppm" , R"cpp(
525
+ export module M;
526
+ export int M = 43;
527
+ )cpp" );
528
+ CDB.addFile (" A.cppm" , R"cpp(
529
+ export module A;
530
+ import M;
531
+ export int A = 43 + M;
532
+ )cpp" );
533
+ CDB.addFile (" B.cppm" , R"cpp(
534
+ export module B;
535
+ import M;
536
+ export int B = 44 + M;
537
+ )cpp" );
538
+
539
+ ModulesBuilder Builder (CDB);
540
+
541
+ std::unique_ptr<PrerequisiteModules> AInfo, BInfo;
542
+
543
+ // Trying to build A and B at the same time and check we will only build module M once.
544
+ AsyncTaskRunner ThreadPool;
545
+ ThreadPool.runAsync (" A Job" , [&] () {
546
+ AInfo = Builder.buildPrerequisiteModulesFor (getFullPath (" A.cppm" ), FS);
547
+ });
548
+ ThreadPool.runAsync (" B Job" , [&] () {
549
+ BInfo = Builder.buildPrerequisiteModulesFor (getFullPath (" B.cppm" ), FS);
550
+ });
551
+ ThreadPool.wait ();
552
+
553
+ EXPECT_TRUE (AInfo);
554
+ EXPECT_TRUE (BInfo);
555
+ HeaderSearchOptions HSOptsA (TestDir);
556
+ HeaderSearchOptions HSOptsB (TestDir);
557
+ AInfo->adjustHeaderSearchOptions (HSOptsA);
558
+ BInfo->adjustHeaderSearchOptions (HSOptsB);
559
+
560
+ EXPECT_FALSE (HSOptsA.PrebuiltModuleFiles .empty ());
561
+ EXPECT_FALSE (HSOptsB.PrebuiltModuleFiles .empty ());
562
+
563
+ // Check that we're reusing the module files.
564
+ EXPECT_EQ (HSOptsA.PrebuiltModuleFiles , HSOptsB.PrebuiltModuleFiles );
565
+ }
566
+
521
567
} // namespace
522
568
} // namespace clang::clangd
523
569
0 commit comments