cmState: Move PolicyState from cmMakefile.

Implement lexical scope checking in terms of the state stack instead
of barriers.
This commit is contained in:
Stephen Kelly 2015-07-26 13:04:09 +02:00
parent 52dbe654de
commit 757a1f5408
4 changed files with 135 additions and 97 deletions

View File

@ -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());
}
//----------------------------------------------------------------------------

View File

@ -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(

View File

@ -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>

View File

@ -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;