Merge pull request #1791 from neheb/exp

[clang-tidy] add explicit to single argument constructors
diff --git a/.clang-tidy b/.clang-tidy
index df4c1ed..e0afd47 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,13 +1,17 @@
 ---
 Checks: '
   ,readability-avoid-const-params-in-decls,
+  ,readability-inconsistent-declaration-parameter-name,
   ,readability-non-const-parameter,
   ,readability-redundant-string-cstr,
   ,readability-redundant-string-init,
+  ,readability-simplify-boolean-expr,
 '
 WarningsAsErrors: '
   ,readability-avoid-const-params-in-decls,
+  ,readability-inconsistent-declaration-parameter-name,
   ,readability-non-const-parameter,
   ,readability-redundant-string-cstr,
   ,readability-redundant-string-init,
+  ,readability-simplify-boolean-expr,
 '
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 9062d98..cd55262 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -123,3 +123,24 @@
     - name: clang-tidy
       run: /usr/lib/llvm-10/share/clang/run-clang-tidy.py -header-filter=src
       working-directory: build-clang
+
+  build-with-python:
+    runs-on: [ubuntu-latest]
+    container:
+      image: ${{ matrix.image }}
+    strategy:
+      matrix:
+        image: ['ubuntu:14.04', 'ubuntu:16.04', 'ubuntu:18.04']
+    steps:
+    - uses: actions/checkout@v2
+    - name: Install dependencies
+      run: |
+        apt update
+        apt install -y g++ python3
+    - name: ${{ matrix.image }}
+      run: |
+        python3 configure.py --bootstrap
+        ./ninja all
+        ./ninja_test --gtest_filter=-SubprocessTest.SetWithLots
+        python3 misc/ninja_syntax_test.py
+        ./misc/output_test.py
diff --git a/.gitignore b/.gitignore
index dca1129..b9a45a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,7 @@
 
 # Qt Creator project files
 /CMakeLists.txt.user
+
+# clangd
+/.clangd/
+/compile_commands.json
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index e5d7d2b..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-matrix:
-  include:
-    - os: linux
-      dist: precise
-      compiler: gcc
-    - os: linux
-      dist: precise
-      compiler: clang
-    - os: linux
-      dist: trusty
-      compiler: gcc
-    - os: linux
-      dist: trusty
-      compiler: clang
-    - os: linux
-      dist: xenial
-      compiler: gcc
-    - os: linux
-      dist: xenial
-      compiler: clang
-    - os: osx
-      osx_image: xcode10
-    - os: osx
-      osx_image: xcode10.1
-sudo: false
-language: cpp
-before_install:
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install re2c             ; fi
-  - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then choco install re2c python ; fi
-script:
-  - ./misc/ci.py
-  - python3 configure.py --bootstrap
-  - ./ninja all
-  - ./ninja_test --gtest_filter=-SubprocessTest.SetWithLots
-  - ./misc/ninja_syntax_test.py
-  - ./misc/output_test.py
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7f03c35..3e4bafa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,7 +18,9 @@
 # --- compiler flags
 if(MSVC)
 	set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
-	string(APPEND CMAKE_CXX_FLAGS " /W4 /GR- /Zc:__cplusplus")
+	string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+	string(APPEND CMAKE_CXX_FLAGS " /W4 /wd4100 /wd4267 /wd4706 /wd4702 /wd4244 /GR- /Zc:__cplusplus")
+	add_definitions(-D_CRT_SECURE_NO_WARNINGS)
 else()
 	include(CheckCXXCompilerFlag)
 	check_cxx_compiler_flag(-Wno-deprecated flag_no_deprecated)
diff --git a/src/build.cc b/src/build.cc
index 2fb2aa4..2007d82 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -318,8 +318,8 @@
   want_.clear();
 }
 
-bool Plan::AddTarget(const Node* node, string* err) {
-  return AddSubTarget(node, NULL, err, NULL);
+bool Plan::AddTarget(const Node* target, string* err) {
+  return AddSubTarget(target, NULL, err, NULL);
 }
 
 bool Plan::AddSubTarget(const Node* node, const Node* dependent, string* err,
@@ -381,7 +381,7 @@
 Edge* Plan::FindWork() {
   if (ready_.empty())
     return NULL;
-  set<Edge*>::iterator e = ready_.begin();
+  EdgeSet::iterator e = ready_.begin();
   Edge* edge = *e;
   ready_.erase(e);
   return edge;
@@ -782,16 +782,16 @@
   return node;
 }
 
-bool Builder::AddTarget(Node* node, string* err) {
-  if (!scan_.RecomputeDirty(node, err))
+bool Builder::AddTarget(Node* target, string* err) {
+  if (!scan_.RecomputeDirty(target, err))
     return false;
 
-  if (Edge* in_edge = node->in_edge()) {
+  if (Edge* in_edge = target->in_edge()) {
     if (in_edge->outputs_ready())
       return true;  // Nothing to do.
   }
 
-  if (!plan_.AddTarget(node, err))
+  if (!plan_.AddTarget(target, err))
     return false;
 
   return true;
diff --git a/src/build.h b/src/build.h
index 2798693..0a68478 100644
--- a/src/build.h
+++ b/src/build.h
@@ -19,7 +19,6 @@
 #include <map>
 #include <memory>
 #include <queue>
-#include <set>
 #include <string>
 #include <vector>
 
@@ -46,7 +45,7 @@
   /// Add a target to our plan (including all its dependencies).
   /// Returns false if we don't need to build this target; may
   /// fill in |err| with an error message if there's a problem.
-  bool AddTarget(const Node* node, std::string* err);
+  bool AddTarget(const Node* target, std::string* err);
 
   // Pop a ready edge off the queue of edges to build.
   // Returns NULL if there's no work to do.
@@ -122,7 +121,7 @@
   /// we want for the edge.
   std::map<Edge*, Want> want_;
 
-  std::set<Edge*> ready_;
+  EdgeSet ready_;
 
   Builder* builder_;
 
diff --git a/src/graph.h b/src/graph.h
index 4833f49..8c51782 100644
--- a/src/graph.h
+++ b/src/graph.h
@@ -15,6 +15,7 @@
 #ifndef NINJA_GRAPH_H_
 #define NINJA_GRAPH_H_
 
+#include <set>
 #include <string>
 #include <vector>
 
@@ -143,10 +144,11 @@
     VisitDone
   };
 
-  Edge() : rule_(NULL), pool_(NULL), dyndep_(NULL), env_(NULL),
-           mark_(VisitNone), outputs_ready_(false), deps_loaded_(false),
-           deps_missing_(false), implicit_deps_(0), order_only_deps_(0),
-           implicit_outs_(0) {}
+  Edge()
+      : rule_(NULL), pool_(NULL), dyndep_(NULL), env_(NULL), mark_(VisitNone),
+        id_(0), outputs_ready_(false), deps_loaded_(false),
+        deps_missing_(false), implicit_deps_(0), order_only_deps_(0),
+        implicit_outs_(0) {}
 
   /// Return true if all inputs' in-edges are ready.
   bool AllInputsReady() const;
@@ -176,6 +178,7 @@
   Node* dyndep_;
   BindingEnv* env_;
   VisitMark mark_;
+  size_t id_;
   bool outputs_ready_;
   bool deps_loaded_;
   bool deps_missing_;
@@ -218,6 +221,13 @@
   bool maybe_phonycycle_diagnostic() const;
 };
 
+struct EdgeCmp {
+  bool operator()(const Edge* a, const Edge* b) const {
+    return a->id_ < b->id_;
+  }
+};
+
+typedef std::set<Edge*, EdgeCmp> EdgeSet;
 
 /// ImplicitDepLoader loads implicit dependencies, as referenced via the
 /// "depfile" attribute in build files.
diff --git a/src/graphviz.h b/src/graphviz.h
index 601c9b2..3a3282e 100644
--- a/src/graphviz.h
+++ b/src/graphviz.h
@@ -18,6 +18,7 @@
 #include <set>
 
 #include "dyndep.h"
+#include "graph.h"
 
 struct DiskInterface;
 struct Node;
@@ -34,7 +35,7 @@
 
   DyndepLoader dyndep_loader_;
   std::set<Node*> visited_nodes_;
-  std::set<Edge*> visited_edges_;
+  EdgeSet visited_edges_;
 };
 
 #endif  // NINJA_GRAPHVIZ_H_
diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc
index 860a8fc..54ad3f4 100644
--- a/src/manifest_parser.cc
+++ b/src/manifest_parser.cc
@@ -202,10 +202,7 @@
       return false;
   } while (!eval.empty());
 
-  if (!ExpectToken(Lexer::NEWLINE, err))
-    return false;
-
-  return true;
+  return ExpectToken(Lexer::NEWLINE, err);
 }
 
 bool ManifestParser::ParseEdge(string* err) {
diff --git a/src/ninja.cc b/src/ninja.cc
index 471a023..eb97320 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -613,7 +613,7 @@
 }
 
 enum PrintCommandMode { PCM_Single, PCM_All };
-void PrintCommands(Edge* edge, set<Edge*>* seen, PrintCommandMode mode) {
+void PrintCommands(Edge* edge, EdgeSet* seen, PrintCommandMode mode) {
   if (!edge)
     return;
   if (!seen->insert(edge).second)
@@ -664,7 +664,7 @@
     return 1;
   }
 
-  set<Edge*> seen;
+  EdgeSet seen;
   for (vector<Node*>::iterator in = nodes.begin(); in != nodes.end(); ++in)
     PrintCommands((*in)->in_edge(), &seen, mode);
 
diff --git a/src/state.cc b/src/state.cc
index d3a9e29..a33d5a8 100644
--- a/src/state.cc
+++ b/src/state.cc
@@ -39,7 +39,7 @@
   delayed_.insert(edge);
 }
 
-void Pool::RetrieveReadyEdges(set<Edge*>* ready_queue) {
+void Pool::RetrieveReadyEdges(EdgeSet* ready_queue) {
   DelayedEdges::iterator it = delayed_.begin();
   while (it != delayed_.end()) {
     Edge* edge = *it;
@@ -62,14 +62,6 @@
   }
 }
 
-// static
-bool Pool::WeightedEdgeCmp(const Edge* a, const Edge* b) {
-  if (!a) return b;
-  if (!b) return false;
-  int weight_diff = a->weight() - b->weight();
-  return ((weight_diff < 0) || (weight_diff == 0 && a < b));
-}
-
 Pool State::kDefaultPool("", 0);
 Pool State::kConsolePool("console", 1);
 const Rule State::kPhonyRule("phony");
@@ -97,6 +89,7 @@
   edge->rule_ = rule;
   edge->pool_ = &State::kDefaultPool;
   edge->env_ = &bindings_;
+  edge->id_ = edges_.size();
   edges_.push_back(edge);
   return edge;
 }
diff --git a/src/state.h b/src/state.h
index f553ed4..72c5b33 100644
--- a/src/state.h
+++ b/src/state.h
@@ -21,6 +21,7 @@
 #include <vector>
 
 #include "eval_env.h"
+#include "graph.h"
 #include "hash_map.h"
 #include "util.h"
 
@@ -38,7 +39,7 @@
 /// completes).
 struct Pool {
   Pool(const std::string& name, int depth)
-    : name_(name), current_use_(0), depth_(depth), delayed_(&WeightedEdgeCmp) {}
+    : name_(name), current_use_(0), depth_(depth), delayed_() {}
 
   // A depth of 0 is infinite
   bool is_valid() const { return depth_ >= 0; }
@@ -61,7 +62,7 @@
   void DelayEdge(Edge* edge);
 
   /// Pool will add zero or more edges to the ready_queue
-  void RetrieveReadyEdges(std::set<Edge*>* ready_queue);
+  void RetrieveReadyEdges(EdgeSet* ready_queue);
 
   /// Dump the Pool and its edges (useful for debugging).
   void Dump() const;
@@ -74,9 +75,16 @@
   int current_use_;
   int depth_;
 
-  static bool WeightedEdgeCmp(const Edge* a, const Edge* b);
+  struct WeightedEdgeCmp {
+    bool operator()(const Edge* a, const Edge* b) const {
+      if (!a) return b;
+      if (!b) return false;
+      int weight_diff = a->weight() - b->weight();
+      return ((weight_diff < 0) || (weight_diff == 0 && EdgeCmp()(a, b)));
+    }
+  };
 
-  typedef std::set<Edge*,bool(*)(const Edge*, const Edge*)> DelayedEdges;
+  typedef std::set<Edge*, WeightedEdgeCmp> DelayedEdges;
   DelayedEdges delayed_;
 };