Browse Source

cmState: Move PolicyState from cmMakefile.

Implement lexical scope checking in terms of the state stack instead
of barriers.
Stephen Kelly 10 years ago
parent
commit
757a1f5408
4 changed files with 135 additions and 97 deletions
  1. 9 84
      Source/cmMakefile.cxx
  2. 0 13
      Source/cmMakefile.h
  3. 116 0
      Source/cmState.cxx
  4. 10 0
      Source/cmState.h

+ 9 - 84
Source/cmMakefile.cxx

@@ -192,9 +192,6 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator)
   this->StateSnapshot = this->StateSnapshot.GetState()
       ->CreatePolicyScopeSnapshot(this->StateSnapshot);
 
-  // Protect the directory-level policies.
-  this->PushPolicyBarrier();
-
   // Enter a policy level for this directory.
   this->PushPolicy();
 
@@ -239,11 +236,6 @@ cmMakefile::~cmMakefile()
   cmDeleteAll(this->FinalPassCommands);
   cmDeleteAll(this->FunctionBlockers);
   this->FunctionBlockers.clear();
-  if (this->PolicyStack.size() != 1)
-  {
-    cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
-      " popped properly");
-  }
 }
 
 //----------------------------------------------------------------------------
@@ -479,7 +471,6 @@ cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf,
         this->Makefile->ContextStack.back()->Name,
         this->Makefile->ContextStack.back()->Line,
         filenametoread);
-  this->Makefile->PushPolicyBarrier();
   if(!this->NoPolicyScope)
     {
     // Check CMP0011 to determine the policy scope type.
@@ -519,7 +510,8 @@ cmMakefile::IncludeScope::~IncludeScope()
     // one we pushed above.  If the entry is empty, then the included
     // script did not set any policies that might affect the includer so
     // we do not need to enforce the policy.
-    if(this->CheckCMP0011 && this->Makefile->PolicyStack.back().IsEmpty())
+    if(this->CheckCMP0011
+       && !this->Makefile->StateSnapshot.HasDefinedPolicyCMP0011())
       {
       this->CheckCMP0011 = false;
       }
@@ -535,9 +527,6 @@ cmMakefile::IncludeScope::~IncludeScope()
       }
     }
   this->Makefile->PopPolicyBarrier(this->ReportError);
-  this->Makefile->StateSnapshot =
-      this->Makefile->GetState()->Pop(this->Makefile->StateSnapshot);
-  assert(this->Makefile->StateSnapshot.IsValid());
 
   this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
 }
@@ -646,19 +635,12 @@ public:
           this->Makefile->StateSnapshot, name, line, filenametoread);
     assert(this->Makefile->StateSnapshot.IsValid());
 
-    this->Makefile->PushPolicyBarrier();
-
     this->Makefile->PushFunctionBlockerBarrier();
   }
 
   ~ListFileScope()
   {
     this->Makefile->PopPolicyBarrier(this->ReportError);
-
-    this->Makefile->StateSnapshot =
-        this->Makefile->GetState()->Pop(this->Makefile->StateSnapshot);
-    assert(this->Makefile->StateSnapshot.IsValid());
-
     this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
   }
 
@@ -1630,7 +1612,6 @@ void cmMakefile::PushFunctionScope(std::string const& fileName,
         this->ContextStack.back()->Name, this->ContextStack.back()->Line,
         fileName);
   assert(this->StateSnapshot.IsValid());
-  this->PushPolicyBarrier();
 
   this->Internal->PushDefinitions();
 
@@ -1650,8 +1631,6 @@ void cmMakefile::PopFunctionScope(bool reportError)
   this->PopPolicy();
 
   this->PopPolicyBarrier(reportError);
-  this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot);
-  assert(this->StateSnapshot.IsValid());
 
   this->PopFunctionBlockerBarrier(reportError);
 
@@ -1675,7 +1654,6 @@ void cmMakefile::PushMacroScope(std::string const& fileName,
         this->ContextStack.back()->Name, this->ContextStack.back()->Line,
         fileName);
   assert(this->StateSnapshot.IsValid());
-  this->PushPolicyBarrier();
 
   this->PushFunctionBlockerBarrier();
 
@@ -1687,9 +1665,6 @@ void cmMakefile::PopMacroScope(bool reportError)
   this->PopPolicy();
   this->PopPolicyBarrier(reportError);
 
-  this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot);
-  assert(this->StateSnapshot.IsValid());
-
   this->PopFunctionBlockerBarrier(reportError);
 }
 
@@ -1710,7 +1685,6 @@ public:
     this->Makefile->StateSnapshot.SetListFile(currentStart);
     this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()
         ->CreatePolicyScopeSnapshot(this->Makefile->StateSnapshot);
-    this->Makefile->PushPolicyBarrier();
     this->Makefile->PushFunctionBlockerBarrier();
 
     this->GG = mf->GetGlobalGenerator();
@@ -1727,8 +1701,6 @@ public:
   {
     this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
     this->Makefile->PopPolicyBarrier(this->ReportError);
-    this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()
-        ->Pop(this->Makefile->StateSnapshot);
 #if defined(CMAKE_BUILD_WITH_CMAKE)
     this->GG->GetFileLockPool().PopFileScope();
 #endif
@@ -4759,30 +4731,7 @@ const char* cmMakefile::GetDefineFlagsCMP0059() const
 cmPolicies::PolicyStatus
 cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const
 {
-  cmPolicies::PolicyStatus status = cmPolicies::GetPolicyStatus(id);
-
-  if(status == cmPolicies::REQUIRED_ALWAYS ||
-     status == cmPolicies::REQUIRED_IF_USED)
-    {
-    return status;
-    }
-
-  cmLocalGenerator* lg = this->LocalGenerator;
-  while(lg)
-    {
-    cmMakefile const* mf = lg->GetMakefile();
-    for(PolicyStackType::const_reverse_iterator psi =
-        mf->PolicyStack.rbegin(); psi != mf->PolicyStack.rend(); ++psi)
-      {
-      if(psi->IsDefined(id))
-        {
-        status = psi->Get(id);
-        return status;
-        }
-      }
-    lg = lg->GetParent();
-    }
-  return status;
+  return this->StateSnapshot.GetPolicy(id);
 }
 
 //----------------------------------------------------------------------------
@@ -4831,15 +4780,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
     return false;
     }
 
-  // Update the policy stack from the top to the top-most strong entry.
-  bool previous_was_weak = true;
-  for(PolicyStackType::reverse_iterator psi = this->PolicyStack.rbegin();
-      previous_was_weak && psi != this->PolicyStack.rend(); ++psi)
-    {
-    psi->Set(id, status);
-    previous_was_weak = psi->Weak;
-    }
-
+  this->StateSnapshot.SetPolicy(id, status);
   return true;
 }
 
@@ -4850,7 +4791,6 @@ cmMakefile::PolicyPushPop::PolicyPushPop(cmMakefile* m, bool weak,
 {
   this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()
       ->CreatePolicyScopeSnapshot(this->Makefile->StateSnapshot);
-  this->Makefile->PushPolicyBarrier();
   this->Makefile->PushPolicy(weak, pm);
 }
 
@@ -4859,43 +4799,28 @@ cmMakefile::PolicyPushPop::~PolicyPushPop()
 {
   this->Makefile->PopPolicy();
   this->Makefile->PopPolicyBarrier(this->ReportError);
-  this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()
-      ->Pop(this->Makefile->StateSnapshot);
 }
 
 //----------------------------------------------------------------------------
 void cmMakefile::PushPolicy(bool weak, cmPolicies::PolicyMap const& pm)
 {
-  // Allocate a new stack entry.
-  this->PolicyStack.push_back(PolicyStackEntry(pm, weak));
+  this->StateSnapshot.PushPolicy(pm, weak);
 }
 
 //----------------------------------------------------------------------------
 void cmMakefile::PopPolicy()
 {
-  if(this->PolicyStack.size() > this->PolicyBarriers.back())
-    {
-    this->PolicyStack.pop_back();
-    }
-  else
+  if (!this->StateSnapshot.PopPolicy())
     {
     this->IssueMessage(cmake::FATAL_ERROR,
                        "cmake_policy POP without matching PUSH");
     }
 }
 
-//----------------------------------------------------------------------------
-void cmMakefile::PushPolicyBarrier()
-{
-  this->PolicyBarriers.push_back(this->PolicyStack.size());
-}
-
 //----------------------------------------------------------------------------
 void cmMakefile::PopPolicyBarrier(bool reportError)
 {
-  // Remove any extra entries pushed on the barrier.
-  PolicyStackType::size_type barrier = this->PolicyBarriers.back();
-  while(this->PolicyStack.size() > barrier)
+  while (!this->StateSnapshot.CanPopPolicyScope())
     {
     if(reportError)
       {
@@ -4906,8 +4831,8 @@ void cmMakefile::PopPolicyBarrier(bool reportError)
     this->PopPolicy();
     }
 
-  // Remove the barrier.
-  this->PolicyBarriers.pop_back();
+  this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot);
+  assert(this->StateSnapshot.IsValid());
 }
 
 //----------------------------------------------------------------------------

+ 0 - 13
Source/cmMakefile.h

@@ -909,7 +909,6 @@ private:
   void PushPolicy(bool weak = false,
                   cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
   void PopPolicy();
-  void PushPolicyBarrier();
   void PopPolicyBarrier(bool reportError = true);
   friend class cmCMakePolicyCommand;
   class IncludeScope;
@@ -919,18 +918,6 @@ private:
   class BuildsystemFileScope;
   friend class BuildsystemFileScope;
 
-  // stack of policy settings
-  struct PolicyStackEntry: public cmPolicies::PolicyMap
-  {
-    typedef cmPolicies::PolicyMap derived;
-    PolicyStackEntry(bool w = false): derived(), Weak(w) {}
-    PolicyStackEntry(derived const& d, bool w = false): derived(d), Weak(w) {}
-    PolicyStackEntry(PolicyStackEntry const& r): derived(r), Weak(r.Weak) {}
-    bool Weak;
-  };
-  typedef std::vector<PolicyStackEntry> PolicyStackType;
-  PolicyStackType PolicyStack;
-  std::vector<PolicyStackType::size_type> PolicyBarriers;
 
   // CMP0053 == old
   cmake::MessageType ExpandVariablesInStringOld(

+ 116 - 0
Source/cmState.cxx

@@ -21,6 +21,9 @@
 struct cmState::SnapshotDataType
 {
   cmState::PositionType DirectoryParent;
+  cmLinkedTree<cmState::PolicyStackEntry>::iterator Policies;
+  cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyRoot;
+  cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyScope;
   cmState::SnapshotType SnapshotType;
   cmLinkedTree<std::string>::iterator ExecutionListFile;
   cmLinkedTree<cmState::BuildsystemDirectoryStateType>::iterator
@@ -32,6 +35,15 @@ struct cmState::SnapshotDataType
   std::vector<std::string>::size_type CompileOptionsPosition;
 };
 
+struct cmState::PolicyStackEntry: public cmPolicies::PolicyMap
+{
+  typedef cmPolicies::PolicyMap derived;
+  PolicyStackEntry(bool w = false): derived(), Weak(w) {}
+  PolicyStackEntry(derived const& d, bool w): derived(d), Weak(w) {}
+  PolicyStackEntry(PolicyStackEntry const& r): derived(r), Weak(r.Weak) {}
+  bool Weak;
+};
+
 struct cmState::BuildsystemDirectoryStateType
 {
   cmState::PositionType DirectoryEnd;
@@ -256,6 +268,13 @@ cmState::Snapshot cmState::Reset()
   it->DirectoryEnd = pos;
   }
 
+  this->PolicyStack.Clear();
+  pos->Policies = this->PolicyStack.Root();
+  pos->PolicyRoot = this->PolicyStack.Root();
+  pos->PolicyScope = this->PolicyStack.Root();
+  assert(pos->Policies.IsValid());
+  assert(pos->PolicyRoot.IsValid());
+
   this->DefineProperty
     ("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY,
      "", "", true);
@@ -726,6 +745,11 @@ cmState::Snapshot cmState::CreateBaseSnapshot()
   pos->CompileDefinitionsPosition = 0;
   pos->CompileOptionsPosition = 0;
   pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->Policies = this->PolicyStack.Root();
+  pos->PolicyRoot = this->PolicyStack.Root();
+  pos->PolicyScope = this->PolicyStack.Root();
+  assert(pos->Policies.IsValid());
+  assert(pos->PolicyRoot.IsValid());
   return cmState::Snapshot(this, pos);
 }
 
@@ -747,6 +771,11 @@ cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,
       this->ExecutionListFiles.Extend(
         originSnapshot.Position->ExecutionListFile);
   pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->Policies = originSnapshot.Position->Policies;
+  pos->PolicyRoot = originSnapshot.Position->Policies;
+  pos->PolicyScope = originSnapshot.Position->Policies;
+  assert(pos->Policies.IsValid());
+  assert(pos->PolicyRoot.IsValid());
   return cmState::Snapshot(this, pos);
 }
 
@@ -764,6 +793,7 @@ cmState::CreateFunctionCallSnapshot(cmState::Snapshot originSnapshot,
   pos->ExecutionListFile = this->ExecutionListFiles.Extend(
         originSnapshot.Position->ExecutionListFile, fileName);
   pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->PolicyScope = originSnapshot.Position->Policies;
   return cmState::Snapshot(this, pos);
 }
 
@@ -782,6 +812,7 @@ cmState::CreateMacroCallSnapshot(cmState::Snapshot originSnapshot,
   pos->ExecutionListFile = this->ExecutionListFiles.Extend(
         originSnapshot.Position->ExecutionListFile, fileName);
   pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->PolicyScope = originSnapshot.Position->Policies;
   return cmState::Snapshot(this, pos);
 }
 
@@ -799,6 +830,7 @@ cmState::CreateCallStackSnapshot(cmState::Snapshot originSnapshot,
   pos->ExecutionListFile = this->ExecutionListFiles.Extend(
         originSnapshot.Position->ExecutionListFile, fileName);
   pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->PolicyScope = originSnapshot.Position->Policies;
   return cmState::Snapshot(this, pos);
 }
 
@@ -816,6 +848,7 @@ cmState::CreateInlineListFileSnapshot(cmState::Snapshot originSnapshot,
   pos->ExecutionListFile = this->ExecutionListFiles.Extend(
         originSnapshot.Position->ExecutionListFile, fileName);
   pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->PolicyScope = originSnapshot.Position->Policies;
   return cmState::Snapshot(this, pos);
 }
 
@@ -826,6 +859,7 @@ cmState::CreatePolicyScopeSnapshot(cmState::Snapshot originSnapshot)
                                                *originSnapshot.Position);
   pos->SnapshotType = PolicyScopeType;
   pos->BuildSystemDirectory->DirectoryEnd = pos;
+  pos->PolicyScope = originSnapshot.Position->Policies;
   return cmState::Snapshot(this, pos);
 }
 
@@ -1005,6 +1039,88 @@ cmState::Snapshot cmState::Snapshot::GetCallStackParent() const
   return snapshot;
 }
 
+void cmState::Snapshot::PushPolicy(cmPolicies::PolicyMap entry, bool weak)
+{
+  PositionType pos = this->Position;
+  pos->Policies =
+      this->State->PolicyStack.Extend(pos->Policies,
+                                      PolicyStackEntry(entry, weak));
+}
+
+bool cmState::Snapshot::PopPolicy()
+{
+  PositionType pos = this->Position;
+  if (pos->Policies == pos->PolicyScope)
+    {
+    return false;
+    }
+  ++pos->Policies;
+  return true;
+}
+
+bool cmState::Snapshot::CanPopPolicyScope()
+{
+  return this->Position->Policies == this->Position->PolicyScope;
+}
+
+void cmState::Snapshot::SetPolicy(cmPolicies::PolicyID id,
+                                  cmPolicies::PolicyStatus status)
+{
+  // Update the policy stack from the top to the top-most strong entry.
+  bool previous_was_weak = true;
+  for(cmLinkedTree<PolicyStackEntry>::iterator psi = this->Position->Policies;
+      previous_was_weak && psi != this->Position->PolicyRoot; ++psi)
+    {
+    psi->Set(id, status);
+    previous_was_weak = psi->Weak;
+    }
+}
+
+cmPolicies::PolicyStatus
+cmState::Snapshot::GetPolicy(cmPolicies::PolicyID id) const
+{
+  cmPolicies::PolicyStatus status = cmPolicies::GetPolicyStatus(id);
+
+  if(status == cmPolicies::REQUIRED_ALWAYS ||
+     status == cmPolicies::REQUIRED_IF_USED)
+    {
+    return status;
+    }
+
+  cmLinkedTree<BuildsystemDirectoryStateType>::iterator dir =
+      this->Position->BuildSystemDirectory;
+
+  while (true)
+    {
+    assert(dir.IsValid());
+    cmLinkedTree<PolicyStackEntry>::iterator leaf =
+        dir->DirectoryEnd->Policies;
+    cmLinkedTree<PolicyStackEntry>::iterator root =
+        dir->DirectoryEnd->PolicyRoot;
+    for( ; leaf != root; ++leaf)
+      {
+      if(leaf->IsDefined(id))
+        {
+        status = leaf->Get(id);
+        return status;
+        }
+      }
+    cmState::PositionType e = dir->DirectoryEnd;
+    cmState::PositionType p = e->DirectoryParent;
+    if (p == this->State->SnapshotData.Root())
+      {
+      break;
+      }
+    dir = p->BuildSystemDirectory;
+    }
+  return status;
+}
+
+bool cmState::Snapshot::HasDefinedPolicyCMP0011()
+{
+  return !this->Position->Policies->IsEmpty();
+}
+
 static const std::string cmPropertySentinal = std::string();
 
 template<typename T, typename U, typename V>

+ 10 - 0
Source/cmState.h

@@ -17,6 +17,7 @@
 #include "cmPropertyMap.h"
 #include "cmLinkedTree.h"
 #include "cmAlgorithms.h"
+#include "cmPolicies.h"
 
 class cmake;
 class cmCommand;
@@ -24,6 +25,7 @@ class cmCommand;
 class cmState
 {
   struct SnapshotDataType;
+  struct PolicyStackEntry;
   struct BuildsystemDirectoryStateType;
   typedef cmLinkedTree<SnapshotDataType>::iterator PositionType;
   friend class Snapshot;
@@ -61,6 +63,13 @@ public:
 
     void InitializeFromParent();
 
+    void SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status);
+    cmPolicies::PolicyStatus GetPolicy(cmPolicies::PolicyID id) const;
+    bool HasDefinedPolicyCMP0011();
+    void PushPolicy(cmPolicies::PolicyMap entry, bool weak);
+    bool PopPolicy();
+    bool CanPopPolicyScope();
+
     cmState* GetState() const;
 
     Directory GetDirectory() const;
@@ -257,6 +266,7 @@ private:
 
   cmLinkedTree<std::string> ExecutionListFiles;
 
+  cmLinkedTree<PolicyStackEntry> PolicyStack;
   cmLinkedTree<SnapshotDataType> SnapshotData;
 
   std::vector<std::string> SourceDirectoryComponents;