mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-09 15:20:56 -06:00
cmMakefile: Keep function blockers in a stack
Highlight the fact that we only ever operate on the top element.
This commit is contained in:
@@ -3061,15 +3061,7 @@ bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
|
||||
return false;
|
||||
}
|
||||
|
||||
// loop over all function blockers to see if any block this command
|
||||
// evaluate in reverse, this is critical for balanced IF statements etc
|
||||
for (auto const& pos : cmReverseRange(this->FunctionBlockers)) {
|
||||
if (pos->IsFunctionBlocked(lff, *this, status)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return this->FunctionBlockers.top()->IsFunctionBlocked(lff, *this, status);
|
||||
}
|
||||
|
||||
void cmMakefile::PushFunctionBlockerBarrier()
|
||||
@@ -3084,8 +3076,8 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
|
||||
this->FunctionBlockerBarriers.back();
|
||||
while (this->FunctionBlockers.size() > barrier) {
|
||||
std::unique_ptr<cmFunctionBlocker> fb(
|
||||
std::move(this->FunctionBlockers.back()));
|
||||
this->FunctionBlockers.pop_back();
|
||||
std::move(this->FunctionBlockers.top()));
|
||||
this->FunctionBlockers.pop();
|
||||
if (reportError) {
|
||||
// Report the context in which the unclosed block was opened.
|
||||
cmListFileContext const& lfc = fb->GetStartingContext();
|
||||
@@ -3216,46 +3208,36 @@ void cmMakefile::AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb)
|
||||
fb->SetStartingContext(this->GetExecutionContext());
|
||||
}
|
||||
|
||||
this->FunctionBlockers.push_back(std::move(fb));
|
||||
this->FunctionBlockers.push(std::move(fb));
|
||||
}
|
||||
|
||||
std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker(
|
||||
cmFunctionBlocker* fb, const cmListFileFunction& lff)
|
||||
{
|
||||
// Find the function blocker stack barrier for the current scope.
|
||||
// We only remove a blocker whose index is not less than the barrier.
|
||||
FunctionBlockersType::size_type barrier = 0;
|
||||
if (!this->FunctionBlockerBarriers.empty()) {
|
||||
barrier = this->FunctionBlockerBarriers.back();
|
||||
assert(!this->FunctionBlockers.empty());
|
||||
assert(this->FunctionBlockers.top().get() == fb);
|
||||
assert(this->FunctionBlockerBarriers.empty() ||
|
||||
this->FunctionBlockers.size() > this->FunctionBlockerBarriers.back());
|
||||
|
||||
// Warn if the arguments do not match, but always remove.
|
||||
if (!fb->ShouldRemove(lff, *this)) {
|
||||
cmListFileContext const& lfc = fb->GetStartingContext();
|
||||
cmListFileContext closingContext =
|
||||
cmListFileContext::FromCommandContext(lff, lfc.FilePath);
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e << "A logical block opening on the line\n"
|
||||
<< " " << lfc << "\n"
|
||||
<< "closes on the line\n"
|
||||
<< " " << closingContext << "\n"
|
||||
<< "with mis-matching arguments.";
|
||||
/* clang-format on */
|
||||
this->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
|
||||
}
|
||||
|
||||
// Search for the function blocker whose scope this command ends.
|
||||
for (FunctionBlockersType::size_type i = this->FunctionBlockers.size();
|
||||
i > barrier; --i) {
|
||||
auto pos = this->FunctionBlockers.begin() + (i - 1);
|
||||
if (pos->get() == fb) {
|
||||
// Warn if the arguments do not match, but always remove.
|
||||
if (!(*pos)->ShouldRemove(lff, *this)) {
|
||||
cmListFileContext const& lfc = fb->GetStartingContext();
|
||||
cmListFileContext closingContext =
|
||||
cmListFileContext::FromCommandContext(lff, lfc.FilePath);
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e << "A logical block opening on the line\n"
|
||||
<< " " << lfc << "\n"
|
||||
<< "closes on the line\n"
|
||||
<< " " << closingContext << "\n"
|
||||
<< "with mis-matching arguments.";
|
||||
/* clang-format on */
|
||||
this->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
|
||||
}
|
||||
std::unique_ptr<cmFunctionBlocker> b = std::move(*pos);
|
||||
this->FunctionBlockers.erase(pos);
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
return std::unique_ptr<cmFunctionBlocker>();
|
||||
auto b = std::move(this->FunctionBlockers.top());
|
||||
this->FunctionBlockers.pop();
|
||||
return b;
|
||||
}
|
||||
|
||||
std::string const& cmMakefile::GetHomeDirectory() const
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "cm_string_view.hxx"
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmFunctionBlocker.h"
|
||||
#include "cmListFileCache.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmNewLineStyle.h"
|
||||
@@ -39,6 +38,7 @@ class cmCustomCommandLines;
|
||||
class cmExecutionStatus;
|
||||
class cmExpandedCommandArgument;
|
||||
class cmExportBuildFileGenerator;
|
||||
class cmFunctionBlocker;
|
||||
class cmGeneratorExpressionEvaluationFile;
|
||||
class cmGlobalGenerator;
|
||||
class cmInstallGenerator;
|
||||
@@ -963,7 +963,9 @@ private:
|
||||
bool EnforceUniqueDir(const std::string& srcPath,
|
||||
const std::string& binPath) const;
|
||||
|
||||
typedef std::vector<std::unique_ptr<cmFunctionBlocker>> FunctionBlockersType;
|
||||
using FunctionBlockerPtr = std::unique_ptr<cmFunctionBlocker>;
|
||||
using FunctionBlockersType =
|
||||
std::stack<FunctionBlockerPtr, std::vector<FunctionBlockerPtr>>;
|
||||
FunctionBlockersType FunctionBlockers;
|
||||
std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
|
||||
void PushFunctionBlockerBarrier();
|
||||
|
||||
Reference in New Issue
Block a user