Merge topic 'cmState-policies'

757a1f54 cmState: Move PolicyState from cmMakefile.
52dbe654 cmState: Record the end position of each directory.
65a5e0c6 cmLinkedTree: Add Clear API.
34835433 cmState: Add Type for policy scope.
af0de01c cmState: Remove call stack parent tracking.
6ae8b30b cmMakefile: Move policy barriers inside cmState scopes.
a5fc17b5 cmMakefile: Re-order policy entries and barriers.
0a01e6c6 cmState: Add Snapshot Type accessor.
f0005bb4 Tests: Verify generate-time policy scope behavior.
This commit is contained in:
Brad King 2015-08-06 09:38:24 -04:00 committed by CMake Topic Stage
commit 73e3de381d
16 changed files with 248 additions and 127 deletions

View File

@ -155,6 +155,12 @@ public:
return iterator(this, 1); return iterator(this, 1);
} }
void Clear()
{
this->UpPositions.clear();
this->Data.clear();
}
private: private:
T& GetReference(PositionType pos) T& GetReference(PositionType pos)
{ {

View File

@ -190,12 +190,12 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator)
this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)"); this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
this->cmNamedCurly.compile("^[A-Za-z0-9/_.+-]+{"); this->cmNamedCurly.compile("^[A-Za-z0-9/_.+-]+{");
this->StateSnapshot = this->StateSnapshot.GetState()
->CreatePolicyScopeSnapshot(this->StateSnapshot);
// Enter a policy level for this directory. // Enter a policy level for this directory.
this->PushPolicy(); this->PushPolicy();
// Protect the directory-level policies.
this->PushPolicyBarrier();
// push empty loop block // push empty loop block
this->PushLoopBlockBarrier(); this->PushLoopBlockBarrier();
@ -240,11 +240,6 @@ cmMakefile::~cmMakefile()
this->EvaluationFiles.clear(); this->EvaluationFiles.clear();
this->FunctionBlockers.clear(); this->FunctionBlockers.clear();
if (this->PolicyStack.size() != 1)
{
cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
" popped properly");
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -472,6 +467,14 @@ cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf,
Makefile(mf), NoPolicyScope(noPolicyScope), Makefile(mf), NoPolicyScope(noPolicyScope),
CheckCMP0011(false), ReportError(true) CheckCMP0011(false), ReportError(true)
{ {
this->Makefile->PushFunctionBlockerBarrier();
this->Makefile->StateSnapshot =
this->Makefile->GetState()->CreateCallStackSnapshot(
this->Makefile->StateSnapshot,
this->Makefile->ContextStack.back()->Name,
this->Makefile->ContextStack.back()->Line,
filenametoread);
if(!this->NoPolicyScope) if(!this->NoPolicyScope)
{ {
// Check CMP0011 to determine the policy scope type. // Check CMP0011 to determine the policy scope type.
@ -500,37 +503,19 @@ cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf,
break; break;
} }
} }
// The included file cannot pop our policy scope.
this->Makefile->PushPolicyBarrier();
this->Makefile->PushFunctionBlockerBarrier();
this->Makefile->StateSnapshot =
this->Makefile->GetState()->CreateCallStackSnapshot(
this->Makefile->StateSnapshot,
this->Makefile->ContextStack.back()->Name,
this->Makefile->ContextStack.back()->Line,
filenametoread);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmMakefile::IncludeScope::~IncludeScope() cmMakefile::IncludeScope::~IncludeScope()
{ {
this->Makefile->StateSnapshot =
this->Makefile->GetState()->Pop(this->Makefile->StateSnapshot);
assert(this->Makefile->StateSnapshot.IsValid());
this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
// Enforce matching policy scopes inside the included file.
this->Makefile->PopPolicyBarrier(this->ReportError);
if(!this->NoPolicyScope) if(!this->NoPolicyScope)
{ {
// If we need to enforce policy CMP0011 then the top entry is the // If we need to enforce policy CMP0011 then the top entry is the
// one we pushed above. If the entry is empty, then the included // one we pushed above. If the entry is empty, then the included
// script did not set any policies that might affect the includer so // script did not set any policies that might affect the includer so
// we do not need to enforce the policy. // 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; this->CheckCMP0011 = false;
} }
@ -545,6 +530,9 @@ cmMakefile::IncludeScope::~IncludeScope()
this->EnforceCMP0011(); this->EnforceCMP0011();
} }
} }
this->Makefile->PopPolicyBarrier(this->ReportError);
this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -639,8 +627,6 @@ public:
ListFileScope(cmMakefile* mf, std::string const& filenametoread) ListFileScope(cmMakefile* mf, std::string const& filenametoread)
: Makefile(mf), ReportError(true) : Makefile(mf), ReportError(true)
{ {
this->Makefile->PushPolicyBarrier();
long line = 0; long line = 0;
std::string name; std::string name;
if (!this->Makefile->ContextStack.empty()) if (!this->Makefile->ContextStack.empty())
@ -652,17 +638,14 @@ public:
this->Makefile->GetState()->CreateInlineListFileSnapshot( this->Makefile->GetState()->CreateInlineListFileSnapshot(
this->Makefile->StateSnapshot, name, line, filenametoread); this->Makefile->StateSnapshot, name, line, filenametoread);
assert(this->Makefile->StateSnapshot.IsValid()); assert(this->Makefile->StateSnapshot.IsValid());
this->Makefile->PushFunctionBlockerBarrier(); this->Makefile->PushFunctionBlockerBarrier();
} }
~ListFileScope() ~ListFileScope()
{ {
this->Makefile->StateSnapshot =
this->Makefile->GetState()->Pop(this->Makefile->StateSnapshot);
assert(this->Makefile->StateSnapshot.IsValid());
this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
this->Makefile->PopPolicyBarrier(this->ReportError); this->Makefile->PopPolicyBarrier(this->ReportError);
this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
} }
void Quiet() { this->ReportError = false; } void Quiet() { this->ReportError = false; }
@ -1662,16 +1645,13 @@ void cmMakefile::PushFunctionScope(std::string const& fileName,
this->PushFunctionBlockerBarrier(); this->PushFunctionBlockerBarrier();
this->PushPolicy(true, pm); this->PushPolicy(true, pm);
this->PushPolicyBarrier();
} }
void cmMakefile::PopFunctionScope(bool reportError) void cmMakefile::PopFunctionScope(bool reportError)
{ {
this->PopPolicyBarrier(reportError);
this->PopPolicy(); this->PopPolicy();
this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot); this->PopPolicyBarrier(reportError);
assert(this->StateSnapshot.IsValid());
this->PopFunctionBlockerBarrier(reportError); this->PopFunctionBlockerBarrier(reportError);
@ -1699,16 +1679,12 @@ void cmMakefile::PushMacroScope(std::string const& fileName,
this->PushFunctionBlockerBarrier(); this->PushFunctionBlockerBarrier();
this->PushPolicy(true, pm); this->PushPolicy(true, pm);
this->PushPolicyBarrier();
} }
void cmMakefile::PopMacroScope(bool reportError) void cmMakefile::PopMacroScope(bool reportError)
{ {
this->PopPolicyBarrier(reportError);
this->PopPolicy(); this->PopPolicy();
this->PopPolicyBarrier(reportError);
this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot);
assert(this->StateSnapshot.IsValid());
this->PopFunctionBlockerBarrier(reportError); this->PopFunctionBlockerBarrier(reportError);
} }
@ -1728,7 +1704,8 @@ public:
this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource(); this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource();
currentStart += "/CMakeLists.txt"; currentStart += "/CMakeLists.txt";
this->Makefile->StateSnapshot.SetListFile(currentStart); this->Makefile->StateSnapshot.SetListFile(currentStart);
this->Makefile->PushPolicyBarrier(); this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()
->CreatePolicyScopeSnapshot(this->Makefile->StateSnapshot);
this->Makefile->PushFunctionBlockerBarrier(); this->Makefile->PushFunctionBlockerBarrier();
this->GG = mf->GetGlobalGenerator(); this->GG = mf->GetGlobalGenerator();
@ -4775,30 +4752,7 @@ const char* cmMakefile::GetDefineFlagsCMP0059() const
cmPolicies::PolicyStatus cmPolicies::PolicyStatus
cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const
{ {
cmPolicies::PolicyStatus status = cmPolicies::GetPolicyStatus(id); return this->StateSnapshot.GetPolicy(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;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -4847,15 +4801,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
return false; return false;
} }
// Update the policy stack from the top to the top-most strong entry. this->StateSnapshot.SetPolicy(id, status);
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;
}
return true; return true;
} }
@ -4864,50 +4810,38 @@ cmMakefile::PolicyPushPop::PolicyPushPop(cmMakefile* m, bool weak,
cmPolicies::PolicyMap const& pm): cmPolicies::PolicyMap const& pm):
Makefile(m), ReportError(true) Makefile(m), ReportError(true)
{ {
this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()
->CreatePolicyScopeSnapshot(this->Makefile->StateSnapshot);
this->Makefile->PushPolicy(weak, pm); this->Makefile->PushPolicy(weak, pm);
this->Makefile->PushPolicyBarrier();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmMakefile::PolicyPushPop::~PolicyPushPop() cmMakefile::PolicyPushPop::~PolicyPushPop()
{ {
this->Makefile->PopPolicyBarrier(this->ReportError);
this->Makefile->PopPolicy(); this->Makefile->PopPolicy();
this->Makefile->PopPolicyBarrier(this->ReportError);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmMakefile::PushPolicy(bool weak, cmPolicies::PolicyMap const& pm) void cmMakefile::PushPolicy(bool weak, cmPolicies::PolicyMap const& pm)
{ {
// Allocate a new stack entry. this->StateSnapshot.PushPolicy(pm, weak);
this->PolicyStack.push_back(PolicyStackEntry(pm, weak));
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmMakefile::PopPolicy() void cmMakefile::PopPolicy()
{ {
if(this->PolicyStack.size() > this->PolicyBarriers.back()) if (!this->StateSnapshot.PopPolicy())
{
this->PolicyStack.pop_back();
}
else
{ {
this->IssueMessage(cmake::FATAL_ERROR, this->IssueMessage(cmake::FATAL_ERROR,
"cmake_policy POP without matching PUSH"); "cmake_policy POP without matching PUSH");
} }
} }
//----------------------------------------------------------------------------
void cmMakefile::PushPolicyBarrier()
{
this->PolicyBarriers.push_back(this->PolicyStack.size());
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmMakefile::PopPolicyBarrier(bool reportError) void cmMakefile::PopPolicyBarrier(bool reportError)
{ {
// Remove any extra entries pushed on the barrier. while (!this->StateSnapshot.CanPopPolicyScope())
PolicyStackType::size_type barrier = this->PolicyBarriers.back();
while(this->PolicyStack.size() > barrier)
{ {
if(reportError) if(reportError)
{ {
@ -4918,8 +4852,8 @@ void cmMakefile::PopPolicyBarrier(bool reportError)
this->PopPolicy(); this->PopPolicy();
} }
// Remove the barrier. this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot);
this->PolicyBarriers.pop_back(); assert(this->StateSnapshot.IsValid());
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -918,7 +918,6 @@ private:
void PushPolicy(bool weak = false, void PushPolicy(bool weak = false,
cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap()); cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
void PopPolicy(); void PopPolicy();
void PushPolicyBarrier();
void PopPolicyBarrier(bool reportError = true); void PopPolicyBarrier(bool reportError = true);
friend class cmCMakePolicyCommand; friend class cmCMakePolicyCommand;
class IncludeScope; class IncludeScope;
@ -928,18 +927,6 @@ private:
class BuildsystemFileScope; class BuildsystemFileScope;
friend 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 // CMP0053 == old
cmake::MessageType ExpandVariablesInStringOld( cmake::MessageType ExpandVariablesInStringOld(

View File

@ -20,8 +20,10 @@
struct cmState::SnapshotDataType struct cmState::SnapshotDataType
{ {
cmState::PositionType CallStackParent;
cmState::PositionType DirectoryParent; cmState::PositionType DirectoryParent;
cmLinkedTree<cmState::PolicyStackEntry>::iterator Policies;
cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyRoot;
cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyScope;
cmState::SnapshotType SnapshotType; cmState::SnapshotType SnapshotType;
cmLinkedTree<std::string>::iterator ExecutionListFile; cmLinkedTree<std::string>::iterator ExecutionListFile;
cmLinkedTree<cmState::BuildsystemDirectoryStateType>::iterator cmLinkedTree<cmState::BuildsystemDirectoryStateType>::iterator
@ -33,8 +35,19 @@ struct cmState::SnapshotDataType
std::vector<std::string>::size_type CompileOptionsPosition; 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 struct cmState::BuildsystemDirectoryStateType
{ {
cmState::PositionType DirectoryEnd;
std::string Location; std::string Location;
std::string OutputLocation; std::string OutputLocation;
@ -240,6 +253,9 @@ cmState::Snapshot cmState::Reset()
this->GlobalProperties.clear(); this->GlobalProperties.clear();
this->PropertyDefinitions.clear(); this->PropertyDefinitions.clear();
PositionType pos = this->SnapshotData.Truncate();
this->ExecutionListFiles.Truncate();
{ {
cmLinkedTree<BuildsystemDirectoryStateType>::iterator it = cmLinkedTree<BuildsystemDirectoryStateType>::iterator it =
this->BuildsystemDirectory.Truncate(); this->BuildsystemDirectory.Truncate();
@ -249,9 +265,15 @@ cmState::Snapshot cmState::Reset()
it->CompileDefinitionsBacktraces.clear(); it->CompileDefinitionsBacktraces.clear();
it->CompileOptions.clear(); it->CompileOptions.clear();
it->CompileOptionsBacktraces.clear(); it->CompileOptionsBacktraces.clear();
it->DirectoryEnd = pos;
} }
PositionType pos = this->SnapshotData.Truncate();
this->ExecutionListFiles.Truncate(); 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 this->DefineProperty
("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, ("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY,
@ -722,6 +744,12 @@ cmState::Snapshot cmState::CreateBaseSnapshot()
pos->IncludeDirectoryPosition = 0; pos->IncludeDirectoryPosition = 0;
pos->CompileDefinitionsPosition = 0; pos->CompileDefinitionsPosition = 0;
pos->CompileOptionsPosition = 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); return cmState::Snapshot(this, pos);
} }
@ -732,7 +760,6 @@ cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,
{ {
assert(originSnapshot.IsValid()); assert(originSnapshot.IsValid());
PositionType pos = this->SnapshotData.Extend(originSnapshot.Position); PositionType pos = this->SnapshotData.Extend(originSnapshot.Position);
pos->CallStackParent = originSnapshot.Position;
pos->EntryPointLine = entryPointLine; pos->EntryPointLine = entryPointLine;
pos->EntryPointCommand = entryPointCommand; pos->EntryPointCommand = entryPointCommand;
pos->DirectoryParent = originSnapshot.Position; pos->DirectoryParent = originSnapshot.Position;
@ -743,6 +770,12 @@ cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,
pos->ExecutionListFile = pos->ExecutionListFile =
this->ExecutionListFiles.Extend( this->ExecutionListFiles.Extend(
originSnapshot.Position->ExecutionListFile); 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); return cmState::Snapshot(this, pos);
} }
@ -754,12 +787,13 @@ cmState::CreateFunctionCallSnapshot(cmState::Snapshot originSnapshot,
{ {
PositionType pos = this->SnapshotData.Extend(originSnapshot.Position, PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
*originSnapshot.Position); *originSnapshot.Position);
pos->CallStackParent = originSnapshot.Position;
pos->EntryPointLine = entryPointLine; pos->EntryPointLine = entryPointLine;
pos->EntryPointCommand = entryPointCommand; pos->EntryPointCommand = entryPointCommand;
pos->SnapshotType = FunctionCallType; pos->SnapshotType = FunctionCallType;
pos->ExecutionListFile = this->ExecutionListFiles.Extend( pos->ExecutionListFile = this->ExecutionListFiles.Extend(
originSnapshot.Position->ExecutionListFile, fileName); originSnapshot.Position->ExecutionListFile, fileName);
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
return cmState::Snapshot(this, pos); return cmState::Snapshot(this, pos);
} }
@ -772,12 +806,13 @@ cmState::CreateMacroCallSnapshot(cmState::Snapshot originSnapshot,
{ {
PositionType pos = this->SnapshotData.Extend(originSnapshot.Position, PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
*originSnapshot.Position); *originSnapshot.Position);
pos->CallStackParent = originSnapshot.Position;
pos->EntryPointLine = entryPointLine; pos->EntryPointLine = entryPointLine;
pos->EntryPointCommand = entryPointCommand; pos->EntryPointCommand = entryPointCommand;
pos->SnapshotType = MacroCallType; pos->SnapshotType = MacroCallType;
pos->ExecutionListFile = this->ExecutionListFiles.Extend( pos->ExecutionListFile = this->ExecutionListFiles.Extend(
originSnapshot.Position->ExecutionListFile, fileName); originSnapshot.Position->ExecutionListFile, fileName);
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
return cmState::Snapshot(this, pos); return cmState::Snapshot(this, pos);
} }
@ -789,12 +824,13 @@ cmState::CreateCallStackSnapshot(cmState::Snapshot originSnapshot,
{ {
PositionType pos = this->SnapshotData.Extend(originSnapshot.Position, PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
*originSnapshot.Position); *originSnapshot.Position);
pos->CallStackParent = originSnapshot.Position;
pos->EntryPointLine = entryPointLine; pos->EntryPointLine = entryPointLine;
pos->EntryPointCommand = entryPointCommand; pos->EntryPointCommand = entryPointCommand;
pos->SnapshotType = CallStackType; pos->SnapshotType = CallStackType;
pos->ExecutionListFile = this->ExecutionListFiles.Extend( pos->ExecutionListFile = this->ExecutionListFiles.Extend(
originSnapshot.Position->ExecutionListFile, fileName); originSnapshot.Position->ExecutionListFile, fileName);
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
return cmState::Snapshot(this, pos); return cmState::Snapshot(this, pos);
} }
@ -806,12 +842,24 @@ cmState::CreateInlineListFileSnapshot(cmState::Snapshot originSnapshot,
{ {
PositionType pos = this->SnapshotData.Extend(originSnapshot.Position, PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
*originSnapshot.Position); *originSnapshot.Position);
pos->CallStackParent = originSnapshot.Position;
pos->EntryPointLine = entryPointLine; pos->EntryPointLine = entryPointLine;
pos->EntryPointCommand = entryPointCommand; pos->EntryPointCommand = entryPointCommand;
pos->SnapshotType = InlineListFileType; pos->SnapshotType = InlineListFileType;
pos->ExecutionListFile = this->ExecutionListFiles.Extend( pos->ExecutionListFile = this->ExecutionListFiles.Extend(
originSnapshot.Position->ExecutionListFile, fileName); originSnapshot.Position->ExecutionListFile, fileName);
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
return cmState::Snapshot(this, pos);
}
cmState::Snapshot
cmState::CreatePolicyScopeSnapshot(cmState::Snapshot originSnapshot)
{
PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
*originSnapshot.Position);
pos->SnapshotType = PolicyScopeType;
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
return cmState::Snapshot(this, pos); return cmState::Snapshot(this, pos);
} }
@ -826,12 +874,9 @@ cmState::Snapshot cmState::Pop(cmState::Snapshot originSnapshot)
prevPos->BuildSystemDirectory->CompileDefinitions.size(); prevPos->BuildSystemDirectory->CompileDefinitions.size();
prevPos->CompileOptionsPosition = prevPos->CompileOptionsPosition =
prevPos->BuildSystemDirectory->CompileOptions.size(); prevPos->BuildSystemDirectory->CompileOptions.size();
prevPos->BuildSystemDirectory->DirectoryEnd = prevPos;
if (prevPos == this->SnapshotData.Root()) return Snapshot(this, prevPos);
{
return Snapshot(this, prevPos);
}
return Snapshot(this, originSnapshot.Position->CallStackParent);
} }
cmState::Snapshot::Snapshot(cmState* state) cmState::Snapshot::Snapshot(cmState* state)
@ -847,6 +892,11 @@ cmState::Snapshot::Snapshot(cmState* state, PositionType position)
} }
cmState::SnapshotType cmState::Snapshot::GetType() const
{
return this->Position->SnapshotType;
}
const char* cmState::Directory::GetCurrentSource() const const char* cmState::Directory::GetCurrentSource() const
{ {
return this->DirectoryState->Location.c_str(); return this->DirectoryState->Location.c_str();
@ -964,13 +1014,22 @@ cmState::Snapshot cmState::Snapshot::GetCallStackParent() const
assert(this->Position != this->State->SnapshotData.Root()); assert(this->Position != this->State->SnapshotData.Root());
Snapshot snapshot; Snapshot snapshot;
if (this->Position->SnapshotType == cmState::BuildsystemDirectoryType) PositionType parentPos = this->Position;
while(parentPos->SnapshotType == cmState::PolicyScopeType)
{
++parentPos;
}
if (parentPos->SnapshotType == cmState::BuildsystemDirectoryType)
{ {
return snapshot; return snapshot;
} }
PositionType parentPos = this->Position;
++parentPos; ++parentPos;
while(parentPos->SnapshotType == cmState::PolicyScopeType)
{
++parentPos;
}
if (parentPos == this->State->SnapshotData.Root()) if (parentPos == this->State->SnapshotData.Root())
{ {
return snapshot; return snapshot;
@ -980,6 +1039,88 @@ cmState::Snapshot cmState::Snapshot::GetCallStackParent() const
return snapshot; 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(); static const std::string cmPropertySentinal = std::string();
template<typename T, typename U, typename V> template<typename T, typename U, typename V>

View File

@ -17,6 +17,7 @@
#include "cmPropertyMap.h" #include "cmPropertyMap.h"
#include "cmLinkedTree.h" #include "cmLinkedTree.h"
#include "cmAlgorithms.h" #include "cmAlgorithms.h"
#include "cmPolicies.h"
class cmake; class cmake;
class cmCommand; class cmCommand;
@ -24,6 +25,7 @@ class cmCommand;
class cmState class cmState
{ {
struct SnapshotDataType; struct SnapshotDataType;
struct PolicyStackEntry;
struct BuildsystemDirectoryStateType; struct BuildsystemDirectoryStateType;
typedef cmLinkedTree<SnapshotDataType>::iterator PositionType; typedef cmLinkedTree<SnapshotDataType>::iterator PositionType;
friend class Snapshot; friend class Snapshot;
@ -37,7 +39,8 @@ public:
FunctionCallType, FunctionCallType,
MacroCallType, MacroCallType,
CallStackType, CallStackType,
InlineListFileType InlineListFileType,
PolicyScopeType
}; };
class Directory; class Directory;
@ -56,9 +59,17 @@ public:
bool IsValid() const; bool IsValid() const;
Snapshot GetBuildsystemDirectoryParent() const; Snapshot GetBuildsystemDirectoryParent() const;
Snapshot GetCallStackParent() const; Snapshot GetCallStackParent() const;
SnapshotType GetType() const;
void InitializeFromParent(); 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; cmState* GetState() const;
Directory GetDirectory() const; Directory GetDirectory() const;
@ -147,6 +158,7 @@ public:
const std::string& entryPointCommand, const std::string& entryPointCommand,
long entryPointLine, long entryPointLine,
std::string const& fileName); std::string const& fileName);
Snapshot CreatePolicyScopeSnapshot(Snapshot originSnapshot);
Snapshot Pop(Snapshot originSnapshot); Snapshot Pop(Snapshot originSnapshot);
enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC, enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC,
@ -254,6 +266,7 @@ private:
cmLinkedTree<std::string> ExecutionListFiles; cmLinkedTree<std::string> ExecutionListFiles;
cmLinkedTree<PolicyStackEntry> PolicyStack;
cmLinkedTree<SnapshotDataType> SnapshotData; cmLinkedTree<SnapshotDataType> SnapshotData;
std::vector<std::string> SourceDirectoryComponents; std::vector<std::string> SourceDirectoryComponents;

View File

@ -146,6 +146,7 @@ add_RunCMake_test(TargetSources)
add_RunCMake_test(find_dependency) add_RunCMake_test(find_dependency)
add_RunCMake_test(CompileDefinitions) add_RunCMake_test(CompileDefinitions)
add_RunCMake_test(CompileFeatures) add_RunCMake_test(CompileFeatures)
add_RunCMake_test(PolicyScope)
add_RunCMake_test(WriteCompilerDetectionHeader) add_RunCMake_test(WriteCompilerDetectionHeader)
if(NOT WIN32) if(NOT WIN32)
add_RunCMake_test(PositionIndependentCode) add_RunCMake_test(PositionIndependentCode)

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 2.8.12)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)

View File

@ -0,0 +1,4 @@
include(RunCMake)
run_cmake(parent-dir-generate-time)
run_cmake(dir-in-macro-generate-time)

View File

@ -0,0 +1,5 @@
CMake Warning \(dev\) at dir1/CMakeLists.txt:5 \(target_compile_definitions\):
Policy CMP0044 is not set: Case sensitive <LANG>_COMPILER_ID generator
expressions. Run "cmake --help-policy CMP0044" for policy details. Use
the cmake_policy command to set the policy and suppress this warning.
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@ -0,0 +1,2 @@
include(dir-in-macro-include.cmake)

View File

@ -0,0 +1,6 @@
enable_language(CXX)
# This does not affect dir1 despite being set before the add_subdirectory.
cmake_policy(SET CMP0044 NEW)
add_subdirectory(dir1)

View File

@ -0,0 +1,5 @@
add_library(foo STATIC foo.cpp)
string(TOLOWER ${CMAKE_CXX_COMPILER_ID} compiler_id)
target_compile_definitions(foo PRIVATE Foo=$<CXX_COMPILER_ID:${compiler_id}>)

View File

@ -0,0 +1,5 @@
int main()
{
return 0;
}

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,7 @@
enable_language(CXX)
add_subdirectory(dir1)
# This affects dir1 despite being set after the add_subdirectory.
cmake_policy(SET CMP0044 NEW)