@@ -913,6 +913,51 @@ static std::string GetClangModulesCacheProperty() {
913913 return std::string (path);
914914}
915915
916+ static void ConfigureCASStorage (SwiftASTContext *m_ast_context,
917+ FileSpec CandidateConfigSearchPath) {
918+ // Config CAS from properties.
919+ llvm::cas::CASConfiguration cas_config;
920+ cas_config.CASPath =
921+ ModuleList::GetGlobalModuleListProperties ().GetCASOnDiskPath ().GetPath ();
922+ cas_config.PluginPath =
923+ ModuleList::GetGlobalModuleListProperties ().GetCASPluginPath ().GetPath ();
924+ cas_config.PluginOptions =
925+ ModuleList::GetGlobalModuleListProperties ().GetCASPluginOptions ();
926+
927+ auto &m_description = m_ast_context->GetDescription ();
928+
929+ if (!cas_config.CASPath .empty ()) {
930+ if (auto maybe_cas = cas_config.createDatabases ()) {
931+ m_ast_context->SetCASStorage (std::move (maybe_cas->first ),
932+ std::move (maybe_cas->second ));
933+ m_ast_context->GetCASOptions ().Config = cas_config;
934+ LOG_PRINTF (GetLog (LLDBLog::Types),
935+ " Setup CAS from module list properties with cas path: %s" ,
936+ cas_config.CASPath .c_str ());
937+ return ;
938+ } else
939+ llvm::consumeError (maybe_cas.takeError ());
940+ }
941+
942+ // Try search from candidiate path.
943+ auto search_config = llvm::cas::CASConfiguration::createFromSearchConfigFile (
944+ CandidateConfigSearchPath.GetPath ());
945+ if (!search_config)
946+ return ;
947+
948+ if (auto maybe_cas = search_config->second .createDatabases ()) {
949+ m_ast_context->SetCASStorage (std::move (maybe_cas->first ),
950+ std::move (maybe_cas->second ));
951+ m_ast_context->GetCASOptions ().Config = search_config->second ;
952+ LOG_PRINTF (GetLog (LLDBLog::Types), " Setup CAS from cas config file: %s" ,
953+ search_config->first .c_str ());
954+ return ;
955+ } else
956+ llvm::consumeError (maybe_cas.takeError ());
957+
958+ return ;
959+ }
960+
916961SwiftASTContext::ScopedDiagnostics::ScopedDiagnostics (
917962 swift::DiagnosticConsumer &consumer)
918963 : m_consumer(consumer),
@@ -1930,41 +1975,81 @@ void SwiftASTContext::AddExtraClangCC1Args(
19301975 return ;
19311976 }
19321977
1933- // Clear module cache key and other CAS options to load modules from disk
1934- // directly.
1935- invocation.getFrontendOpts ().ModuleCacheKeys .clear ();
1936- invocation.getCASOpts () = clang::CASOptions ();
1937-
1938- // Ignore CAS info inside modules when loading.
1939- invocation.getFrontendOpts ().ModuleLoadIgnoreCAS = true ;
1940-
19411978 // Add options to allow clang importer to do implicit module build.
19421979 invocation.getLangOpts ().ImplicitModules = true ;
19431980 invocation.getHeaderSearchOpts ().ImplicitModuleMaps = true ;
19441981 invocation.getHeaderSearchOpts ().ModuleCachePath =
19451982 GetCompilerInvocation ().getClangModuleCachePath ().str ();
19461983
1947- // Remove non-existing modules in a systematic way.
1948- auto CheckFileExists = [&](const std::string &file) -> bool {
1949- if (llvm::sys::fs::exists (file))
1950- return true ;
1951- std::string warn;
1952- llvm::raw_string_ostream (warn)
1953- << " Nonexistent explicit module file " << file;
1954- AddDiagnostic (eSeverityWarning, warn);
1955- return false ;
1956- };
1957- for (auto it = invocation.getHeaderSearchOpts ().PrebuiltModuleFiles .begin ();
1958- it != invocation.getHeaderSearchOpts ().PrebuiltModuleFiles .end ();) {
1959- if (!CheckFileExists (it->second ))
1960- it = invocation.getHeaderSearchOpts ().PrebuiltModuleFiles .erase (it);
1961- else
1962- ++it;
1984+ bool use_cas_module = m_cas && m_action_cache;
1985+ if (use_cas_module) {
1986+ // Load from CAS.
1987+ invocation.getCASOpts ().CASPath = GetCASOptions ().Config .CASPath ;
1988+ invocation.getCASOpts ().PluginPath = GetCASOptions ().Config .PluginPath ;
1989+ invocation.getCASOpts ().PluginOptions = GetCASOptions ().Config .PluginOptions ;
1990+
1991+ // Check the module availability in CAS, if not, fallback to regular load.
1992+ auto CheckModuleInCAS = [&](const std::string &key) {
1993+ auto id = m_cas->parseID (key);
1994+ if (!id) {
1995+ llvm::consumeError (id.takeError ());
1996+ return false ;
1997+ }
1998+ auto lookup = m_action_cache->get (*id);
1999+ if (!lookup) {
2000+ llvm::consumeError (lookup.takeError ());
2001+ return false ;
2002+ }
2003+ return (bool )*lookup;
2004+ };
2005+
2006+ use_cas_module = llvm::all_of (invocation.getFrontendOpts ().ModuleCacheKeys ,
2007+ [&](const auto &entry) {
2008+ auto exist = CheckModuleInCAS (entry.second );
2009+ if (!exist) {
2010+ LOG_PRINTF (
2011+ GetLog (LLDBLog::Types),
2012+ " module '%s' cannot be load "
2013+ " from CAS using key: %s, fallback to "
2014+ " load from file system" ,
2015+ entry.first .c_str (),
2016+ entry.second .c_str ());
2017+ }
2018+ return exist;
2019+ });
2020+ }
2021+
2022+ if (!use_cas_module) {
2023+ // Clear module cache key and other CAS options to load modules from disk
2024+ // directly.
2025+ invocation.getFrontendOpts ().ModuleCacheKeys .clear ();
2026+ invocation.getCASOpts () = clang::CASOptions ();
2027+
2028+ // Ignore CAS info inside modules when loading.
2029+ invocation.getFrontendOpts ().ModuleLoadIgnoreCAS = true ;
2030+
2031+ // Remove non-existing modules in a systematic way.
2032+ auto CheckFileExists = [&](const std::string &file) -> bool {
2033+ if (llvm::sys::fs::exists (file))
2034+ return true ;
2035+ std::string warn;
2036+ llvm::raw_string_ostream (warn)
2037+ << " Nonexistent explicit module file " << file;
2038+ AddDiagnostic (eSeverityWarning, warn);
2039+ return false ;
2040+ };
2041+ for (auto it = invocation.getHeaderSearchOpts ().PrebuiltModuleFiles .begin ();
2042+ it != invocation.getHeaderSearchOpts ().PrebuiltModuleFiles .end ();) {
2043+ if (!CheckFileExists (it->second ))
2044+ it = invocation.getHeaderSearchOpts ().PrebuiltModuleFiles .erase (it);
2045+ else
2046+ ++it;
2047+ }
2048+ invocation.getFrontendOpts ().ModuleFiles .erase (
2049+ llvm::remove_if (invocation.getFrontendOpts ().ModuleFiles ,
2050+ [&](const auto &mod) { return !CheckFileExists (mod); }),
2051+ invocation.getFrontendOpts ().ModuleFiles .end ());
19632052 }
1964- invocation.getFrontendOpts ().ModuleFiles .erase (
1965- llvm::remove_if (invocation.getFrontendOpts ().ModuleFiles ,
1966- [&](const auto &mod) { return !CheckFileExists (mod); }),
1967- invocation.getFrontendOpts ().ModuleFiles .end ());
19682053
19692054 invocation.generateCC1CommandLine (
19702055 [&](const llvm::Twine &arg) { dest.push_back (arg.str ()); });
@@ -2546,6 +2631,8 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
25462631 }
25472632 }
25482633
2634+ ConfigureCASStorage (swift_ast_sp.get (), module .GetFileSpec ());
2635+
25492636 // The serialized triple is the triple of the last binary
25502637 // __swiftast section that was processed. Instead of relying on
25512638 // the section contents order, we overwrite the triple in the
@@ -3027,6 +3114,8 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
30273114 }
30283115 }
30293116
3117+ ConfigureCASStorage (swift_ast_sp.get (), sc.module_sp ->GetFileSpec ());
3118+
30303119 std::string resource_dir = HostInfo::GetSwiftResourceDir (
30313120 triple, swift_ast_sp->GetPlatformSDKPath ());
30323121 ConfigureResourceDirs (swift_ast_sp->GetCompilerInvocation (), resource_dir,
0 commit comments