From d5dc4169ac1c4dd5abd385b1e8499119df88c657 Mon Sep 17 00:00:00 2001
From: Stephen Kelly <steveire@gmail.com>
Date: Sun, 31 May 2015 18:19:58 +0200
Subject: cmMakefile: Create a unified raii for function scopes.

---
 Source/cmFunctionCommand.cxx | 14 +++-----------
 Source/cmMakefile.cxx        | 33 +++++++++++++++++++++++++++++++++
 Source/cmMakefile.h          | 16 +++++++++++++++-
 3 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 001adb1..dc6d2d2 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -73,7 +73,6 @@ public:
   cmPolicies::PolicyMap Policies;
 };
 
-
 bool cmFunctionHelperCommand::InvokeInitialPass
 (const std::vector<cmListFileArgument>& args,
  cmExecutionStatus & inStatus)
@@ -93,14 +92,8 @@ bool cmFunctionHelperCommand::InvokeInitialPass
     return false;
     }
 
-  // we push a scope on the makefile
-  cmMakefile::ScopePushPop varScope(this->Makefile);
-  cmMakefile::LexicalPushPop lexScope(this->Makefile);
-  static_cast<void>(varScope);
-
-  // Push a weak policy scope which restores the policies recorded at
-  // function creation.
-  cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies);
+  cmMakefile::FunctionPushPop functionScope(this->Makefile,
+                                            this->Policies);
 
   // set the value of argc
   std::ostringstream strStream;
@@ -145,8 +138,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass
       {
       // The error message should have already included the call stack
       // so we do not need to report an error here.
-      lexScope.Quiet();
-      polScope.Quiet();
+      functionScope.Quiet();
       inStatus.SetNestedError(true);
       return false;
       }
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index b5d976a..7012701 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1562,6 +1562,26 @@ void cmMakefile::InitializeFromParent()
   this->ImportedTargets = parent->ImportedTargets;
 }
 
+void cmMakefile::PushFunctionScope(const cmPolicies::PolicyMap& pm)
+{
+  this->PushScope();
+
+  this->PushFunctionBlockerBarrier();
+
+  this->PushPolicy(true, pm);
+  this->PushPolicyBarrier();
+}
+
+void cmMakefile::PopFunctionScope(bool reportError)
+{
+  this->PopPolicyBarrier(reportError);
+  this->PopPolicy();
+
+  this->PopFunctionBlockerBarrier(reportError);
+
+  this->PopScope();
+}
+
 //----------------------------------------------------------------------------
 class cmMakefileCurrent
 {
@@ -5418,3 +5438,16 @@ AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const
     }
   return true;
 }
+
+
+cmMakefile::FunctionPushPop::FunctionPushPop(cmMakefile* mf,
+                                             cmPolicies::PolicyMap const& pm)
+  : Makefile(mf), ReportError(true)
+{
+  this->Makefile->PushFunctionScope(pm);
+}
+
+cmMakefile::FunctionPushPop::~FunctionPushPop()
+{
+  this->Makefile->PopFunctionScope(this->ReportError);
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 431ed08..ed9bc70 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -746,7 +746,21 @@ public:
   const std::vector<cmTestGenerator*>& GetTestGenerators() const
     { return this->TestGenerators; }
 
-  // push and pop variable scopes
+  class FunctionPushPop
+  {
+  public:
+    FunctionPushPop(cmMakefile* mf,
+                    cmPolicies::PolicyMap const& pm);
+    ~FunctionPushPop();
+
+    void Quiet() { this->ReportError = false; }
+  private:
+    cmMakefile* Makefile;
+    bool ReportError;
+  };
+
+  void PushFunctionScope(cmPolicies::PolicyMap const& pm);
+  void PopFunctionScope(bool reportError);
   void PushScope();
   void PopScope();
   void RaiseScope(const std::string& var, const char *value);
-- 
cgit v0.12