[args] Fix gn args unstable output

Before this patch, the 'gn args --list --json' is non-deterministic
due to the fact that ArgumentsPerToolchain is unordered. This patch
fix this issue.

Bug: crbug.com/gn/83
Change-Id: Iacf469f99708c43d32b952da2727da2b279afd99
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/5060
Reviewed-by: Brett Wilson <brettw@google.com>
Commit-Queue: Haowei Wu <haowei@google.com>
diff --git a/tools/gn/args.cc b/tools/gn/args.cc
index d1d7611..802c373 100644
--- a/tools/gn/args.cc
+++ b/tools/gn/args.cc
@@ -4,6 +4,7 @@
 
 #include "tools/gn/args.h"
 
+#include "tools/gn/settings.h"
 #include "tools/gn/source_file.h"
 #include "tools/gn/string_utils.h"
 #include "tools/gn/variables.h"
@@ -267,9 +268,22 @@
 
   std::lock_guard<std::mutex> lock(lock_);
 
-  // Default values.
+  // Sort the keys from declared_arguments_per_toolchain_ so
+  // the return value will be deterministic.
+  std::vector<const Settings*> keys;
+  keys.reserve(declared_arguments_per_toolchain_.size());
   for (const auto& map_pair : declared_arguments_per_toolchain_) {
-    for (const auto& arg : map_pair.second)
+    keys.push_back(map_pair.first);
+  }
+  std::sort(keys.begin(), keys.end(),
+            [](const Settings* a, const Settings* b) -> bool {
+              return a->toolchain_label() < b->toolchain_label();
+            });
+
+  // Default values.
+  for (const auto& key : keys) {
+    const auto& value = declared_arguments_per_toolchain_[key];
+    for (const auto& arg : value)
       result.insert(std::make_pair(arg.first, ValueWithOverride(arg.second)));
   }