@@ -585,38 +585,46 @@ static bool useCAS() {
585585 return InMemoryCAS || !OnDiskCASPath.empty () || outputFormatRequiresCAS ();
586586}
587587
588- static llvm::json::Array toJSONSorted (const llvm::StringSet<> &Set) {
589- std::vector<llvm::StringRef> Strings;
590- for (auto &&I : Set)
591- Strings.push_back (I.getKey ());
588+ template <typename Container>
589+ static auto toJSONStrings (llvm::json::OStream &JOS, Container &&Strings) {
590+ return [&JOS, Strings = std::forward<Container>(Strings)] {
591+ for (StringRef Str : Strings)
592+ JOS.value (Str);
593+ };
594+ }
595+
596+ static auto toJSONSorted (llvm::json::OStream &JOS,
597+ const llvm::StringSet<> &Set) {
598+ SmallVector<StringRef> Strings (Set.keys ());
592599 llvm::sort (Strings);
593- return llvm::json::Array (Strings);
600+ return toJSONStrings (JOS, std::move (Strings) );
594601}
595602
596603// Technically, we don't need to sort the dependency list to get determinism.
597604// Leaving these be will simply preserve the import order.
598- static llvm::json::Array toJSONSorted ( std::vector<ModuleID> V) {
605+ static auto toJSONSorted ( llvm::json::OStream &JOS, std::vector<ModuleID> V) {
599606 llvm::sort (V);
600-
601- llvm::json::Array Ret;
602- for (const ModuleID &MID : V)
603- Ret.push_back (llvm::json::Object (
604- {{" module-name" , MID.ModuleName }, {" context-hash" , MID.ContextHash }}));
605- return Ret;
607+ return [&JOS, V = std::move (V)] {
608+ for (const ModuleID &MID : V)
609+ JOS.object ([&] {
610+ JOS.attribute (" context-hash" , StringRef (MID.ContextHash ));
611+ JOS.attribute (" module-name" , StringRef (MID.ModuleName ));
612+ });
613+ };
606614}
607615
608- static llvm::json::Array
609- toJSONSorted (llvm::SmallVector<Module::LinkLibrary, 2 > &LinkLibs) {
610- llvm::sort (LinkLibs, [](const Module::LinkLibrary &lhs,
611- const Module::LinkLibrary &rhs) {
612- return lhs.Library < rhs.Library ;
616+ static auto toJSONSorted (llvm::json::OStream &JOS,
617+ SmallVector<Module::LinkLibrary, 2 > LinkLibs) {
618+ llvm::sort (LinkLibs, [](const auto &LHS, const auto &RHS) {
619+ return LHS.Library < RHS.Library ;
613620 });
614-
615- llvm::json::Array Ret;
616- for (const Module::LinkLibrary &LL : LinkLibs)
617- Ret.push_back (llvm::json::Object (
618- {{" link-name" , LL.Library }, {" isFramework" , LL.IsFramework }}));
619- return Ret;
621+ return [&JOS, LinkLibs = std::move (LinkLibs)] {
622+ for (const auto &LL : LinkLibs)
623+ JOS.object ([&] {
624+ JOS.attribute (" isFramework" , LL.IsFramework );
625+ JOS.attribute (" link-name" , StringRef (LL.Library ));
626+ });
627+ };
620628}
621629
622630// Thread safe.
@@ -707,76 +715,90 @@ class FullDeps {
707715 ModuleIDs.push_back (M.first );
708716 llvm::sort (ModuleIDs);
709717
710- using namespace llvm ::json;
711-
712- Array OutModules;
713- for (auto &&ModID : ModuleIDs) {
714- auto &MD = Modules[ModID];
715- Object O{
716- {" name" , MD.ID .ModuleName },
717- {" context-hash" , MD.ID .ContextHash },
718- {" file-deps" , toJSONSorted (MD.FileDeps )},
719- {" clang-module-deps" , toJSONSorted (MD.ClangModuleDeps )},
720- {" clang-modulemap-file" , MD.ClangModuleMapFile },
721- {" command-line" , MD.getBuildArguments ()},
722- {" link-libraries" , toJSONSorted (MD.LinkLibraries )},
723- };
724- if (MD.ModuleCacheKey )
725- O.try_emplace (" cache-key" , MD.ModuleCacheKey );
726- if (MD.CASFileSystemRootID )
727- O.try_emplace (" casfs-root-id" , MD.CASFileSystemRootID ->toString ());
728- if (MD.IncludeTreeID )
729- O.try_emplace (" cas-include-tree-id" , MD.IncludeTreeID );
730- OutModules.push_back (std::move (O));
731- }
732-
733- Array TUs;
734- for (auto &&I : Inputs) {
735- Array Commands;
736- if (I.DriverCommandLine .empty ()) {
737- for (const auto &Cmd : I.Commands ) {
738- Object O{
739- {" input-file" , I.FileName },
740- {" clang-context-hash" , I.ContextHash },
741- {" file-deps" , I.FileDeps },
742- {" clang-module-deps" , toJSONSorted (I.ModuleDeps )},
743- {" executable" , Cmd.Executable },
744- {" command-line" , Cmd.Arguments },
745- };
746- if (Cmd.TUCacheKey )
747- O.try_emplace (" cache-key" , Cmd.TUCacheKey );
748- if (I.CASFileSystemRootID )
749- O.try_emplace (" casfs-root-id" , I.CASFileSystemRootID );
750- if (I.IncludeTreeID )
751- O.try_emplace (" cas-include-tree-id" , I.IncludeTreeID );
752- Commands.push_back (std::move (O));
718+ llvm::json::OStream JOS (OS, /* IndentSize=*/ 2 );
719+
720+ JOS.object ([&] {
721+ JOS.attributeArray (" modules" , [&] {
722+ for (auto &&ModID : ModuleIDs) {
723+ auto &MD = Modules[ModID];
724+ JOS.object ([&] {
725+ if (MD.ModuleCacheKey )
726+ JOS.attribute (" cache-key" , StringRef (*MD.ModuleCacheKey ));
727+ if (MD.IncludeTreeID )
728+ JOS.attribute (" cas-include-tree-id" ,
729+ StringRef (*MD.IncludeTreeID ));
730+ if (MD.CASFileSystemRootID )
731+ JOS.attribute (" casfs-root-id" ,
732+ StringRef (MD.CASFileSystemRootID ->toString ()));
733+
734+ JOS.attributeArray (" clang-module-deps" ,
735+ toJSONSorted (JOS, MD.ClangModuleDeps ));
736+ JOS.attribute (" clang-modulemap-file" ,
737+ StringRef (MD.ClangModuleMapFile ));
738+ JOS.attributeArray (" command-line" ,
739+ toJSONStrings (JOS, MD.getBuildArguments ()));
740+ JOS.attribute (" context-hash" , StringRef (MD.ID .ContextHash ));
741+ JOS.attributeArray (" file-deps" , toJSONSorted (JOS, MD.FileDeps ));
742+ JOS.attributeArray (" link-libraries" ,
743+ toJSONSorted (JOS, MD.LinkLibraries ));
744+ JOS.attribute (" name" , StringRef (MD.ID .ModuleName ));
745+ });
753746 }
754- } else {
755- Object O{
756- {" input-file" , I.FileName },
757- {" clang-context-hash" , I.ContextHash },
758- {" file-deps" , I.FileDeps },
759- {" clang-module-deps" , toJSONSorted (I.ModuleDeps )},
760- {" executable" , " clang" },
761- {" command-line" , I.DriverCommandLine },
762- };
763- if (I.CASFileSystemRootID )
764- O.try_emplace (" casfs-root-id" , I.CASFileSystemRootID );
765- if (I.IncludeTreeID )
766- O.try_emplace (" cas-include-tree-id" , I.IncludeTreeID );
767- Commands.push_back (std::move (O));
768- }
769- TUs.push_back (Object{
770- {" commands" , std::move (Commands)},
771747 });
772- }
773-
774- Object Output{
775- {" modules" , std::move (OutModules)},
776- {" translation-units" , std::move (TUs)},
777- };
778748
779- OS << llvm::formatv (" {0:2}\n " , Value (std::move (Output)));
749+ JOS.attributeArray (" translation-units" , [&] {
750+ for (auto &&I : Inputs) {
751+ JOS.object ([&] {
752+ JOS.attributeArray (" commands" , [&] {
753+ if (I.DriverCommandLine .empty ()) {
754+ for (const auto &Cmd : I.Commands ) {
755+ JOS.object ([&] {
756+ if (Cmd.TUCacheKey )
757+ JOS.attribute (" cache-key" , StringRef (*Cmd.TUCacheKey ));
758+ if (I.IncludeTreeID )
759+ JOS.attribute (" cas-include-tree-id" ,
760+ StringRef (*I.IncludeTreeID ));
761+ if (I.CASFileSystemRootID )
762+ JOS.attribute (" casfs-root-id" ,
763+ StringRef (*I.CASFileSystemRootID ));
764+
765+ JOS.attribute (" clang-context-hash" ,
766+ StringRef (I.ContextHash ));
767+ JOS.attributeArray (" clang-module-deps" ,
768+ toJSONSorted (JOS, I.ModuleDeps ));
769+ JOS.attributeArray (" command-line" ,
770+ toJSONStrings (JOS, Cmd.Arguments ));
771+ JOS.attribute (" executable" , StringRef (Cmd.Executable ));
772+ JOS.attributeArray (" file-deps" ,
773+ toJSONStrings (JOS, I.FileDeps ));
774+ JOS.attribute (" input-file" , StringRef (I.FileName ));
775+ });
776+ }
777+ } else {
778+ JOS.object ([&] {
779+ if (I.CASFileSystemRootID )
780+ JOS.attribute (" casfs-root-id" ,
781+ StringRef (*I.CASFileSystemRootID ));
782+ if (I.IncludeTreeID )
783+ JOS.attribute (" cas-include-tree-id" ,
784+ StringRef (*I.IncludeTreeID ));
785+
786+ JOS.attribute (" clang-context-hash" , StringRef (I.ContextHash ));
787+ JOS.attributeArray (" clang-module-deps" ,
788+ toJSONSorted (JOS, I.ModuleDeps ));
789+ JOS.attributeArray (" command-line" ,
790+ toJSONStrings (JOS, I.DriverCommandLine ));
791+ JOS.attribute (" executable" , " clang" );
792+ JOS.attributeArray (" file-deps" ,
793+ toJSONStrings (JOS, I.FileDeps ));
794+ JOS.attribute (" input-file" , StringRef (I.FileName ));
795+ });
796+ }
797+ });
798+ });
799+ }
800+ });
801+ });
780802 }
781803
782804private:
0 commit comments