From 757a1f54085af4645ee1946329e24538162ac054 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 26 Jul 2015 13:04:09 +0200 Subject: cmState: Move PolicyState from cmMakefile. Implement lexical scope checking in terms of the state stack instead of barriers. --- Source/cmMakefile.cxx | 93 ++++------------------------------------ Source/cmMakefile.h | 13 ------ Source/cmState.cxx | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++ Source/cmState.h | 10 +++++ 4 files changed, 135 insertions(+), 97 deletions(-) diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 9fb3d06..a0a36ec 100644 --- a/Source/cmMakefile.cxx +++ b/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,25 +4799,18 @@ 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"); @@ -4885,17 +4818,9 @@ void cmMakefile::PopPolicy() } //---------------------------------------------------------------------------- -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()); } //---------------------------------------------------------------------------- diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 1e5c301..173914e 100644 --- a/Source/cmMakefile.h +++ b/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 PolicyStackType; - PolicyStackType PolicyStack; - std::vector PolicyBarriers; // CMP0053 == old cmake::MessageType ExpandVariablesInStringOld( diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 1d24ec6..f425861 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -21,6 +21,9 @@ struct cmState::SnapshotDataType { cmState::PositionType DirectoryParent; + cmLinkedTree::iterator Policies; + cmLinkedTree::iterator PolicyRoot; + cmLinkedTree::iterator PolicyScope; cmState::SnapshotType SnapshotType; cmLinkedTree::iterator ExecutionListFile; cmLinkedTree::iterator @@ -32,6 +35,15 @@ struct cmState::SnapshotDataType std::vector::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::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::iterator dir = + this->Position->BuildSystemDirectory; + + while (true) + { + assert(dir.IsValid()); + cmLinkedTree::iterator leaf = + dir->DirectoryEnd->Policies; + cmLinkedTree::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 diff --git a/Source/cmState.h b/Source/cmState.h index 63b60ef..07aa2a5 100644 --- a/Source/cmState.h +++ b/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::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 ExecutionListFiles; + cmLinkedTree PolicyStack; cmLinkedTree SnapshotData; std::vector SourceDirectoryComponents; -- cgit v0.12