1414//
1515// ===----------------------------------------------------------------------===//
1616
17- #include " swift/Basic/LLVMInitialize.h"
1817#include " swift/Basic/InitializeSwiftModules.h"
19- #include " swift/DriverTool/DriverTool .h"
18+ #include " swift/Basic/LLVMInitialize .h"
2019#include " swift/DependencyScan/DependencyScanImpl.h"
2120#include " swift/DependencyScan/DependencyScanningTool.h"
2221#include " swift/DependencyScan/StringUtils.h"
23- #include " swift/Frontend/CachingUtils.h"
22+ #include " swift/DriverTool/DriverTool.h"
23+ #include " swift/Frontend/CompileJobCacheKey.h"
2424#include " swift/Option/Options.h"
25+ #include " clang/CAS/CASOptions.h"
26+ #include " llvm/CAS/ActionCache.h"
27+ #include " llvm/CAS/BuiltinUnifiedCASDatabases.h"
2528#include " llvm/CAS/ObjectStore.h"
29+ #include " llvm/Support/Error.h"
30+ #include < memory>
2631
2732using namespace swift ::dependencies;
28- using namespace swift ::cas;
33+
34+ namespace {
35+ // / Helper class to manage CAS/Caching from libSwiftScan C APIs.
36+ class SwiftScanCAS {
37+ public:
38+ // Compute the CASID for PCH output from invocation.
39+ llvm::Expected<std::string> computeCacheKey (llvm::ArrayRef<const char *> Args,
40+ llvm::StringRef InputPath,
41+ swift::file_types::ID OutputKind);
42+
43+ // Store content into CAS.
44+ llvm::Expected<std::string> storeContent (llvm::StringRef Content);
45+
46+ // Construct SwiftScanCAS.
47+ static llvm::Expected<SwiftScanCAS *>
48+ createSwiftScanCAS (llvm::StringRef Path);
49+
50+ static llvm::Expected<SwiftScanCAS *>
51+ createSwiftScanCAS (clang::CASOptions &CASOpts);
52+
53+ private:
54+ SwiftScanCAS (std::shared_ptr<llvm::cas::ObjectStore> CAS,
55+ std::shared_ptr<llvm::cas::ActionCache> Cache)
56+ : CAS(CAS), Cache(Cache) {}
57+
58+ std::shared_ptr<llvm::cas::ObjectStore> CAS;
59+ std::shared_ptr<llvm::cas::ActionCache> Cache;
60+ };
61+ } // namespace
2962
3063DEFINE_SIMPLE_CONVERSION_FUNCTIONS (DependencyScanningTool, swiftscan_scanner_t )
31- DEFINE_SIMPLE_CONVERSION_FUNCTIONS(CachingTool, swiftscan_cas_t )
64+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(clang::CASOptions, swiftscan_cas_options_t )
65+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SwiftScanCAS, swiftscan_cas_t )
3266
3367// === Private Cleanup Functions -------------------------------------------===//
3468
@@ -671,26 +705,58 @@ swiftscan_diagnostics_set_dispose(swiftscan_diagnostic_set_t* diagnostics){
671705
672706// === CAS Functions ----------------------------------------------------------//
673707
674- swiftscan_cas_t swiftscan_cas_create (const char *path) {
675- std::string CASPath (path);
676- if (CASPath.empty ())
677- CASPath = llvm::cas::getDefaultOnDiskCASPath ();
708+ swiftscan_cas_options_t swiftscan_cas_options_create () {
709+ clang::CASOptions *CASOpts = new clang::CASOptions ();
710+ return wrap (CASOpts);
711+ }
712+
713+ void swiftscan_cas_options_dispose (swiftscan_cas_options_t options) {
714+ delete unwrap (options);
715+ }
716+
717+ void swiftscan_cas_options_set_ondisk_path (swiftscan_cas_options_t options,
718+ const char *path) {
719+ unwrap (options)->CASPath = path;
720+ }
721+
722+ void swiftscan_cas_options_set_plugin_path (swiftscan_cas_options_t options,
723+ const char *path) {
724+ unwrap (options)->PluginPath = path;
725+ }
726+
727+ bool swiftscan_cas_options_set_option (swiftscan_cas_options_t options,
728+ const char *name, const char *value,
729+ swiftscan_string_ref_t *error) {
730+ unwrap (options)->PluginOptions .emplace_back (name, value);
731+ return false ;
732+ }
678733
679- CachingTool *tool = new CachingTool (CASPath);
680- if (!tool->isValid ()) {
681- delete tool;
734+ swiftscan_cas_t
735+ swiftscan_cas_create_from_options (swiftscan_cas_options_t options,
736+ swiftscan_string_ref_t *error) {
737+ clang::CASOptions *opts = unwrap (options);
738+ auto cas = SwiftScanCAS::createSwiftScanCAS (*opts);
739+ if (!cas) {
740+ *error =
741+ swift::c_string_utils::create_clone (toString (cas.takeError ()).c_str ());
682742 return nullptr ;
683743 }
684- return wrap (tool );
744+ return wrap (*cas );
685745}
686746
687747void swiftscan_cas_dispose (swiftscan_cas_t cas) { delete unwrap (cas); }
688748
689- swiftscan_string_ref_t
690- swiftscan_cas_store (swiftscan_cas_t cas, uint8_t *data, unsigned size) {
749+ swiftscan_string_ref_t swiftscan_cas_store (swiftscan_cas_t cas, uint8_t *data,
750+ unsigned size,
751+ swiftscan_string_ref_t *error) {
691752 llvm::StringRef StrContent ((char *)data, size);
692753 auto ID = unwrap (cas)->storeContent (StrContent);
693- return swift::c_string_utils::create_clone (ID.c_str ());
754+ if (!ID) {
755+ *error =
756+ swift::c_string_utils::create_clone (toString (ID.takeError ()).c_str ());
757+ return swift::c_string_utils::create_null ();
758+ }
759+ return swift::c_string_utils::create_clone (ID->c_str ());
694760}
695761
696762static swift::file_types::ID
@@ -713,14 +779,62 @@ getFileTypeFromScanOutputKind(swiftscan_output_kind_t kind) {
713779
714780swiftscan_string_ref_t
715781swiftscan_compute_cache_key (swiftscan_cas_t cas, int argc, const char **argv,
716- const char *input, swiftscan_output_kind_t kind) {
782+ const char *input, swiftscan_output_kind_t kind,
783+ swiftscan_string_ref_t *error) {
717784 std::vector<const char *> Compilation;
718785 for (int i = 0 ; i < argc; ++i)
719786 Compilation.push_back (argv[i]);
720787
721788 auto ID = unwrap (cas)->computeCacheKey (Compilation, input,
722789 getFileTypeFromScanOutputKind (kind));
723- return swift::c_string_utils::create_clone (ID.c_str ());
790+ if (!ID) {
791+ *error =
792+ swift::c_string_utils::create_clone (toString (ID.takeError ()).c_str ());
793+ return swift::c_string_utils::create_null ();
794+ }
795+ return swift::c_string_utils::create_clone (ID->c_str ());
796+ }
797+
798+ llvm::Expected<SwiftScanCAS *>
799+ SwiftScanCAS::createSwiftScanCAS (llvm::StringRef Path) {
800+ clang::CASOptions Opts;
801+ Opts.CASPath = Path;
802+
803+ return createSwiftScanCAS (Opts);
804+ }
805+
806+ llvm::Expected<SwiftScanCAS *>
807+ SwiftScanCAS::createSwiftScanCAS (clang::CASOptions &CASOpts) {
808+ auto DB = CASOpts.getOrCreateDatabases ();
809+ if (!DB)
810+ return DB.takeError ();
811+
812+ return new SwiftScanCAS (std::move (DB->first ), std::move (DB->second ));
813+ }
814+
815+ llvm::Expected<std::string>
816+ SwiftScanCAS::computeCacheKey (llvm::ArrayRef<const char *> Args,
817+ llvm::StringRef InputPath,
818+ swift::file_types::ID OutputKind) {
819+ auto BaseKey = swift::createCompileJobBaseCacheKey (*CAS, Args);
820+ if (!BaseKey)
821+ return BaseKey.takeError ();
822+
823+ auto Key = swift::createCompileJobCacheKeyForOutput (*CAS, *BaseKey, InputPath,
824+ OutputKind);
825+ if (!Key)
826+ return Key.takeError ();
827+
828+ return CAS->getID (*Key).toString ();
829+ }
830+
831+ llvm::Expected<std::string>
832+ SwiftScanCAS::storeContent (llvm::StringRef Content) {
833+ auto Result = CAS->storeFromString ({}, Content);
834+ if (!Result)
835+ return Result.takeError ();
836+
837+ return CAS->getID (*Result).toString ();
724838}
725839
726840// === Experimental Compiler Invocation Functions ------------------------===//
0 commit comments