浏览代码

cmMakefile: Keep function blockers in a stack

Highlight the fact that we only ever operate on the top element.
Regina Pfeifer 6 年之前
父节点
当前提交
020478dbea
共有 2 个文件被更改,包括 30 次插入46 次删除
  1. 26 44
      Source/cmMakefile.cxx
  2. 4 2
      Source/cmMakefile.h

+ 26 - 44
Source/cmMakefile.cxx

@@ -3061,15 +3061,7 @@ bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
     return false;
     return false;
   }
   }
 
 
-  // loop over all function blockers to see if any block this command
-  // evaluate in reverse, this is critical for balanced IF statements etc
-  for (auto const& pos : cmReverseRange(this->FunctionBlockers)) {
-    if (pos->IsFunctionBlocked(lff, *this, status)) {
-      return true;
-    }
-  }
-
-  return false;
+  return this->FunctionBlockers.top()->IsFunctionBlocked(lff, *this, status);
 }
 }
 
 
 void cmMakefile::PushFunctionBlockerBarrier()
 void cmMakefile::PushFunctionBlockerBarrier()
@@ -3084,8 +3076,8 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
     this->FunctionBlockerBarriers.back();
     this->FunctionBlockerBarriers.back();
   while (this->FunctionBlockers.size() > barrier) {
   while (this->FunctionBlockers.size() > barrier) {
     std::unique_ptr<cmFunctionBlocker> fb(
     std::unique_ptr<cmFunctionBlocker> fb(
-      std::move(this->FunctionBlockers.back()));
-    this->FunctionBlockers.pop_back();
+      std::move(this->FunctionBlockers.top()));
+    this->FunctionBlockers.pop();
     if (reportError) {
     if (reportError) {
       // Report the context in which the unclosed block was opened.
       // Report the context in which the unclosed block was opened.
       cmListFileContext const& lfc = fb->GetStartingContext();
       cmListFileContext const& lfc = fb->GetStartingContext();
@@ -3216,46 +3208,36 @@ void cmMakefile::AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb)
     fb->SetStartingContext(this->GetExecutionContext());
     fb->SetStartingContext(this->GetExecutionContext());
   }
   }
 
 
-  this->FunctionBlockers.push_back(std::move(fb));
+  this->FunctionBlockers.push(std::move(fb));
 }
 }
 
 
 std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker(
 std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker(
   cmFunctionBlocker* fb, const cmListFileFunction& lff)
   cmFunctionBlocker* fb, const cmListFileFunction& lff)
 {
 {
-  // Find the function blocker stack barrier for the current scope.
-  // We only remove a blocker whose index is not less than the barrier.
-  FunctionBlockersType::size_type barrier = 0;
-  if (!this->FunctionBlockerBarriers.empty()) {
-    barrier = this->FunctionBlockerBarriers.back();
-  }
-
-  // Search for the function blocker whose scope this command ends.
-  for (FunctionBlockersType::size_type i = this->FunctionBlockers.size();
-       i > barrier; --i) {
-    auto pos = this->FunctionBlockers.begin() + (i - 1);
-    if (pos->get() == fb) {
-      // Warn if the arguments do not match, but always remove.
-      if (!(*pos)->ShouldRemove(lff, *this)) {
-        cmListFileContext const& lfc = fb->GetStartingContext();
-        cmListFileContext closingContext =
-          cmListFileContext::FromCommandContext(lff, lfc.FilePath);
-        std::ostringstream e;
-        /* clang-format off */
-        e << "A logical block opening on the line\n"
-          << "  " << lfc << "\n"
-          << "closes on the line\n"
-          << "  " << closingContext << "\n"
-          << "with mis-matching arguments.";
-        /* clang-format on */
-        this->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
-      }
-      std::unique_ptr<cmFunctionBlocker> b = std::move(*pos);
-      this->FunctionBlockers.erase(pos);
-      return b;
-    }
+  assert(!this->FunctionBlockers.empty());
+  assert(this->FunctionBlockers.top().get() == fb);
+  assert(this->FunctionBlockerBarriers.empty() ||
+         this->FunctionBlockers.size() > this->FunctionBlockerBarriers.back());
+
+  // Warn if the arguments do not match, but always remove.
+  if (!fb->ShouldRemove(lff, *this)) {
+    cmListFileContext const& lfc = fb->GetStartingContext();
+    cmListFileContext closingContext =
+      cmListFileContext::FromCommandContext(lff, lfc.FilePath);
+    std::ostringstream e;
+    /* clang-format off */
+    e << "A logical block opening on the line\n"
+      << "  " << lfc << "\n"
+      << "closes on the line\n"
+      << "  " << closingContext << "\n"
+      << "with mis-matching arguments.";
+    /* clang-format on */
+    this->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
   }
   }
 
 
-  return std::unique_ptr<cmFunctionBlocker>();
+  auto b = std::move(this->FunctionBlockers.top());
+  this->FunctionBlockers.pop();
+  return b;
 }
 }
 
 
 std::string const& cmMakefile::GetHomeDirectory() const
 std::string const& cmMakefile::GetHomeDirectory() const

+ 4 - 2
Source/cmMakefile.h

@@ -20,7 +20,6 @@
 #include "cm_string_view.hxx"
 #include "cm_string_view.hxx"
 
 
 #include "cmAlgorithms.h"
 #include "cmAlgorithms.h"
-#include "cmFunctionBlocker.h"
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
 #include "cmMessageType.h"
 #include "cmMessageType.h"
 #include "cmNewLineStyle.h"
 #include "cmNewLineStyle.h"
@@ -39,6 +38,7 @@ class cmCustomCommandLines;
 class cmExecutionStatus;
 class cmExecutionStatus;
 class cmExpandedCommandArgument;
 class cmExpandedCommandArgument;
 class cmExportBuildFileGenerator;
 class cmExportBuildFileGenerator;
+class cmFunctionBlocker;
 class cmGeneratorExpressionEvaluationFile;
 class cmGeneratorExpressionEvaluationFile;
 class cmGlobalGenerator;
 class cmGlobalGenerator;
 class cmInstallGenerator;
 class cmInstallGenerator;
@@ -963,7 +963,9 @@ private:
   bool EnforceUniqueDir(const std::string& srcPath,
   bool EnforceUniqueDir(const std::string& srcPath,
                         const std::string& binPath) const;
                         const std::string& binPath) const;
 
 
-  typedef std::vector<std::unique_ptr<cmFunctionBlocker>> FunctionBlockersType;
+  using FunctionBlockerPtr = std::unique_ptr<cmFunctionBlocker>;
+  using FunctionBlockersType =
+    std::stack<FunctionBlockerPtr, std::vector<FunctionBlockerPtr>>;
   FunctionBlockersType FunctionBlockers;
   FunctionBlockersType FunctionBlockers;
   std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
   std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
   void PushFunctionBlockerBarrier();
   void PushFunctionBlockerBarrier();