@@ -330,38 +330,46 @@ handleMakeDependencyToolResult(const std::string &Input,
330330 return false ;
331331}
332332
333- static llvm::json::Array toJSONSorted (const llvm::StringSet<> &Set) {
334- std::vector<llvm::StringRef> Strings;
335- for (auto &&I : Set)
336- Strings.push_back (I.getKey ());
333+ template <typename Container>
334+ static auto toJSONStrings (llvm::json::OStream &JOS, Container &&Strings) {
335+ return [&JOS, Strings = std::forward<Container>(Strings)] {
336+ for (StringRef Str : Strings)
337+ JOS.value (Str);
338+ };
339+ }
340+
341+ static auto toJSONSorted (llvm::json::OStream &JOS,
342+ const llvm::StringSet<> &Set) {
343+ SmallVector<StringRef> Strings (Set.keys ());
337344 llvm::sort (Strings);
338- return llvm::json::Array (Strings);
345+ return toJSONStrings (JOS, std::move (Strings) );
339346}
340347
341348// Technically, we don't need to sort the dependency list to get determinism.
342349// Leaving these be will simply preserve the import order.
343- static llvm::json::Array toJSONSorted ( std::vector<ModuleID> V) {
350+ static auto toJSONSorted ( llvm::json::OStream &JOS, std::vector<ModuleID> V) {
344351 llvm::sort (V);
345-
346- llvm::json::Array Ret;
347- for (const ModuleID &MID : V)
348- Ret.push_back (llvm::json::Object (
349- {{" module-name" , MID.ModuleName }, {" context-hash" , MID.ContextHash }}));
350- return Ret;
352+ return [&JOS, V = std::move (V)] {
353+ for (const ModuleID &MID : V)
354+ JOS.object ([&] {
355+ JOS.attribute (" context-hash" , StringRef (MID.ContextHash ));
356+ JOS.attribute (" module-name" , StringRef (MID.ModuleName ));
357+ });
358+ };
351359}
352360
353- static llvm::json::Array
354- toJSONSorted (llvm::SmallVector<Module::LinkLibrary, 2 > &LinkLibs) {
355- llvm::sort (LinkLibs, [](const Module::LinkLibrary &lhs,
356- const Module::LinkLibrary &rhs) {
357- return lhs.Library < rhs.Library ;
361+ static auto toJSONSorted (llvm::json::OStream &JOS,
362+ SmallVector<Module::LinkLibrary, 2 > LinkLibs) {
363+ llvm::sort (LinkLibs, [](const auto &LHS, const auto &RHS) {
364+ return LHS.Library < RHS.Library ;
358365 });
359-
360- llvm::json::Array Ret;
361- for (const Module::LinkLibrary &LL : LinkLibs)
362- Ret.push_back (llvm::json::Object (
363- {{" link-name" , LL.Library }, {" isFramework" , LL.IsFramework }}));
364- return Ret;
366+ return [&JOS, LinkLibs = std::move (LinkLibs)] {
367+ for (const auto &LL : LinkLibs)
368+ JOS.object ([&] {
369+ JOS.attribute (" isFramework" , LL.IsFramework );
370+ JOS.attribute (" link-name" , StringRef (LL.Library ));
371+ });
372+ };
365373}
366374
367375// Thread safe.
@@ -450,58 +458,65 @@ class FullDeps {
450458 ModuleIDs.push_back (M.first );
451459 llvm::sort (ModuleIDs);
452460
453- using namespace llvm ::json;
454-
455- Array OutModules;
456- for (auto &&ModID : ModuleIDs) {
457- auto &MD = Modules[ModID];
458- Object O{{" name" , MD.ID .ModuleName },
459- {" context-hash" , MD.ID .ContextHash },
460- {" file-deps" , toJSONSorted (MD.FileDeps )},
461- {" clang-module-deps" , toJSONSorted (MD.ClangModuleDeps )},
462- {" clang-modulemap-file" , MD.ClangModuleMapFile },
463- {" command-line" , MD.getBuildArguments ()},
464- {" link-libraries" , toJSONSorted (MD.LinkLibraries )}};
465- OutModules.push_back (std::move (O));
466- }
467-
468- Array TUs;
469- for (auto &&I : Inputs) {
470- Array Commands;
471- if (I.DriverCommandLine .empty ()) {
472- for (const auto &Cmd : I.Commands ) {
473- Object O{
474- {" input-file" , I.FileName },
475- {" clang-context-hash" , I.ContextHash },
476- {" file-deps" , I.FileDeps },
477- {" clang-module-deps" , toJSONSorted (I.ModuleDeps )},
478- {" executable" , Cmd.Executable },
479- {" command-line" , Cmd.Arguments },
480- };
481- Commands.push_back (std::move (O));
461+ llvm::json::OStream JOS (OS, /* IndentSize=*/ 2 );
462+
463+ JOS.object ([&] {
464+ JOS.attributeArray (" modules" , [&] {
465+ for (auto &&ModID : ModuleIDs) {
466+ auto &MD = Modules[ModID];
467+ JOS.object ([&] {
468+ JOS.attributeArray (" clang-module-deps" ,
469+ toJSONSorted (JOS, MD.ClangModuleDeps ));
470+ JOS.attribute (" clang-modulemap-file" ,
471+ StringRef (MD.ClangModuleMapFile ));
472+ JOS.attributeArray (" command-line" ,
473+ toJSONStrings (JOS, MD.getBuildArguments ()));
474+ JOS.attribute (" context-hash" , StringRef (MD.ID .ContextHash ));
475+ JOS.attributeArray (" file-deps" , toJSONSorted (JOS, MD.FileDeps ));
476+ JOS.attributeArray (" link-libraries" ,
477+ toJSONSorted (JOS, MD.LinkLibraries ));
478+ JOS.attribute (" name" , StringRef (MD.ID .ModuleName ));
479+ });
482480 }
483- } else {
484- Object O{
485- {" input-file" , I.FileName },
486- {" clang-context-hash" , I.ContextHash },
487- {" file-deps" , I.FileDeps },
488- {" clang-module-deps" , toJSONSorted (I.ModuleDeps )},
489- {" executable" , " clang" },
490- {" command-line" , I.DriverCommandLine },
491- };
492- Commands.push_back (std::move (O));
493- }
494- TUs.push_back (Object{
495- {" commands" , std::move (Commands)},
496481 });
497- }
498-
499- Object Output{
500- {" modules" , std::move (OutModules)},
501- {" translation-units" , std::move (TUs)},
502- };
503482
504- OS << llvm::formatv (" {0:2}\n " , Value (std::move (Output)));
483+ JOS.attributeArray (" translation-units" , [&] {
484+ for (auto &&I : Inputs) {
485+ JOS.object ([&] {
486+ JOS.attributeArray (" commands" , [&] {
487+ if (I.DriverCommandLine .empty ()) {
488+ for (const auto &Cmd : I.Commands ) {
489+ JOS.object ([&] {
490+ JOS.attribute (" clang-context-hash" ,
491+ StringRef (I.ContextHash ));
492+ JOS.attributeArray (" clang-module-deps" ,
493+ toJSONSorted (JOS, I.ModuleDeps ));
494+ JOS.attributeArray (" command-line" ,
495+ toJSONStrings (JOS, Cmd.Arguments ));
496+ JOS.attribute (" executable" , StringRef (Cmd.Executable ));
497+ JOS.attributeArray (" file-deps" ,
498+ toJSONStrings (JOS, I.FileDeps ));
499+ JOS.attribute (" input-file" , StringRef (I.FileName ));
500+ });
501+ }
502+ } else {
503+ JOS.object ([&] {
504+ JOS.attribute (" clang-context-hash" , StringRef (I.ContextHash ));
505+ JOS.attributeArray (" clang-module-deps" ,
506+ toJSONSorted (JOS, I.ModuleDeps ));
507+ JOS.attributeArray (" command-line" ,
508+ toJSONStrings (JOS, I.DriverCommandLine ));
509+ JOS.attribute (" executable" , " clang" );
510+ JOS.attributeArray (" file-deps" ,
511+ toJSONStrings (JOS, I.FileDeps ));
512+ JOS.attribute (" input-file" , StringRef (I.FileName ));
513+ });
514+ }
515+ });
516+ });
517+ }
518+ });
519+ });
505520 }
506521
507522private:
0 commit comments