cmGeneratorExpressionEvaluator: Modernize memory management

This commit is contained in:
Marc Chevrier
2019-12-05 16:09:27 +01:00
parent 8ee4f372aa
commit d74416a9cd
7 changed files with 67 additions and 64 deletions

View File

@@ -145,6 +145,14 @@ void cmDeleteAll(Range const& r)
ContainerAlgorithms::DefaultDeleter<Range>()); ContainerAlgorithms::DefaultDeleter<Range>());
} }
template <typename T>
void cmAppend(std::vector<std::unique_ptr<T>>& v,
std::vector<std::unique_ptr<T>>&& r)
{
std::transform(r.begin(), r.end(), std::back_inserter(v),
[](std::unique_ptr<T>& item) { return std::move(item); });
}
template <typename T> template <typename T>
void cmAppend(std::vector<T*>& v, std::vector<std::unique_ptr<T>> const& r) void cmAppend(std::vector<T*>& v, std::vector<std::unique_ptr<T>> const& r)
{ {

View File

@@ -8,7 +8,6 @@
#include "cmsys/RegularExpression.hxx" #include "cmsys/RegularExpression.hxx"
#include "cmAlgorithms.h"
#include "cmGeneratorExpressionContext.h" #include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionDAGChecker.h" #include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionEvaluator.h" #include "cmGeneratorExpressionEvaluator.h"
@@ -22,6 +21,8 @@ cmGeneratorExpression::cmGeneratorExpression(cmListFileBacktrace backtrace)
{ {
} }
cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() = default;
cmGeneratorExpression::~cmGeneratorExpression() = default; cmGeneratorExpression::~cmGeneratorExpression() = default;
std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse( std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
@@ -86,7 +87,7 @@ const std::string& cmCompiledGeneratorExpression::EvaluateWithContext(
this->Output.clear(); this->Output.clear();
for (const cmGeneratorExpressionEvaluator* it : this->Evaluators) { for (const auto& it : this->Evaluators) {
this->Output += it->Evaluate(&context, dagChecker); this->Output += it->Evaluate(&context, dagChecker);
this->SeenTargetProperties.insert(context.SeenTargetProperties.cbegin(), this->SeenTargetProperties.insert(context.SeenTargetProperties.cbegin(),
@@ -129,11 +130,6 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
} }
} }
cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression()
{
cmDeleteAll(this->Evaluators);
}
std::string cmGeneratorExpression::StripEmptyListElements( std::string cmGeneratorExpression::StripEmptyListElements(
const std::string& input) const std::string& input)
{ {

View File

@@ -163,7 +163,7 @@ private:
friend class cmGeneratorExpression; friend class cmGeneratorExpression;
cmListFileBacktrace Backtrace; cmListFileBacktrace Backtrace;
std::vector<cmGeneratorExpressionEvaluator*> Evaluators; std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>> Evaluators;
const std::string Input; const std::string Input;
bool NeedsEvaluation; bool NeedsEvaluation;
bool EvaluateForBuildsystem; bool EvaluateForBuildsystem;

View File

@@ -2,10 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */ file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorExpressionEvaluator.h" #include "cmGeneratorExpressionEvaluator.h"
#include <algorithm>
#include <sstream> #include <sstream>
#include "cmAlgorithms.h"
#include "cmGeneratorExpressionContext.h" #include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionNode.h" #include "cmGeneratorExpressionNode.h"
@@ -16,6 +14,8 @@ GeneratorExpressionContent::GeneratorExpressionContent(
{ {
} }
GeneratorExpressionContent::~GeneratorExpressionContent() = default;
std::string GeneratorExpressionContent::GetOriginalExpression() const std::string GeneratorExpressionContent::GetOriginalExpression() const
{ {
return std::string(this->StartContent, this->ContentLength); return std::string(this->StartContent, this->ContentLength);
@@ -25,14 +25,13 @@ std::string GeneratorExpressionContent::ProcessArbitraryContent(
const cmGeneratorExpressionNode* node, const std::string& identifier, const cmGeneratorExpressionNode* node, const std::string& identifier,
cmGeneratorExpressionContext* context, cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker, cmGeneratorExpressionDAGChecker* dagChecker,
std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit) const
pit) const
{ {
std::string result; std::string result;
const auto pend = this->ParamChildren.end(); const auto pend = this->ParamChildren.end();
for (; pit != pend; ++pit) { for (; pit != pend; ++pit) {
for (cmGeneratorExpressionEvaluator* pExprEval : *pit) { for (auto& pExprEval : *pit) {
if (node->RequiresLiteralInput()) { if (node->RequiresLiteralInput()) {
if (pExprEval->GetType() != cmGeneratorExpressionEvaluator::Text) { if (pExprEval->GetType() != cmGeneratorExpressionEvaluator::Text) {
reportError(context, this->GetOriginalExpression(), reportError(context, this->GetOriginalExpression(),
@@ -64,8 +63,7 @@ std::string GeneratorExpressionContent::Evaluate(
{ {
std::string identifier; std::string identifier;
{ {
for (cmGeneratorExpressionEvaluator* pExprEval : for (auto& pExprEval : this->IdentifierChildren) {
this->IdentifierChildren) {
identifier += pExprEval->Evaluate(context, dagChecker); identifier += pExprEval->Evaluate(context, dagChecker);
if (context->HadError) { if (context->HadError) {
return std::string(); return std::string();
@@ -126,7 +124,7 @@ std::string GeneratorExpressionContent::EvaluateParameters(
return std::string(); return std::string();
} }
std::string parameter; std::string parameter;
for (cmGeneratorExpressionEvaluator* pExprEval : *pit) { for (auto& pExprEval : *pit) {
parameter += pExprEval->Evaluate(context, dagChecker); parameter += pExprEval->Evaluate(context, dagChecker);
if (context->HadError) { if (context->HadError) {
return std::string(); return std::string();
@@ -174,10 +172,3 @@ std::string GeneratorExpressionContent::EvaluateParameters(
} }
return std::string(); return std::string();
} }
GeneratorExpressionContent::~GeneratorExpressionContent()
{
cmDeleteAll(this->IdentifierChildren);
std::for_each(this->ParamChildren.begin(), this->ParamChildren.end(),
cmDeleteAll<std::vector<cmGeneratorExpressionEvaluator*>>);
}

View File

@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep #include "cmConfigure.h" // IWYU pragma: keep
#include <cstddef> #include <cstddef>
#include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@@ -36,6 +37,9 @@ struct cmGeneratorExpressionEvaluator
cmGeneratorExpressionDAGChecker*) const = 0; cmGeneratorExpressionDAGChecker*) const = 0;
}; };
using cmGeneratorExpressionEvaluatorVector =
std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>>;
struct TextContent : public cmGeneratorExpressionEvaluator struct TextContent : public cmGeneratorExpressionEvaluator
{ {
TextContent(const char* start, size_t length) TextContent(const char* start, size_t length)
@@ -68,13 +72,13 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator
{ {
GeneratorExpressionContent(const char* startContent, size_t length); GeneratorExpressionContent(const char* startContent, size_t length);
void SetIdentifier(std::vector<cmGeneratorExpressionEvaluator*> identifier) void SetIdentifier(cmGeneratorExpressionEvaluatorVector&& identifier)
{ {
this->IdentifierChildren = std::move(identifier); this->IdentifierChildren = std::move(identifier);
} }
void SetParameters( void SetParameters(
std::vector<std::vector<cmGeneratorExpressionEvaluator*>> parameters) std::vector<cmGeneratorExpressionEvaluatorVector>&& parameters)
{ {
this->ParamChildren = std::move(parameters); this->ParamChildren = std::move(parameters);
} }
@@ -102,12 +106,12 @@ private:
const cmGeneratorExpressionNode* node, const std::string& identifier, const cmGeneratorExpressionNode* node, const std::string& identifier,
cmGeneratorExpressionContext* context, cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker, cmGeneratorExpressionDAGChecker* dagChecker,
std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit)
pit) const; const;
private: private:
std::vector<cmGeneratorExpressionEvaluator*> IdentifierChildren; cmGeneratorExpressionEvaluatorVector IdentifierChildren;
std::vector<std::vector<cmGeneratorExpressionEvaluator*>> ParamChildren; std::vector<cmGeneratorExpressionEvaluatorVector> ParamChildren;
const char* StartContent; const char* StartContent;
size_t ContentLength; size_t ContentLength;
}; };

View File

@@ -6,6 +6,9 @@
#include <cstddef> #include <cstddef>
#include <utility> #include <utility>
#include <cm/memory>
#include <cmext/memory>
#include "cmAlgorithms.h" #include "cmAlgorithms.h"
#include "cmGeneratorExpressionEvaluator.h" #include "cmGeneratorExpressionEvaluator.h"
@@ -17,7 +20,7 @@ cmGeneratorExpressionParser::cmGeneratorExpressionParser(
} }
void cmGeneratorExpressionParser::Parse( void cmGeneratorExpressionParser::Parse(
std::vector<cmGeneratorExpressionEvaluator*>& result) cmGeneratorExpressionEvaluatorVector& result)
{ {
it = this->Tokens.begin(); it = this->Tokens.begin();
@@ -27,40 +30,38 @@ void cmGeneratorExpressionParser::Parse(
} }
static void extendText( static void extendText(
std::vector<cmGeneratorExpressionEvaluator*>& result, cmGeneratorExpressionEvaluatorVector& result,
std::vector<cmGeneratorExpressionToken>::const_iterator it) std::vector<cmGeneratorExpressionToken>::const_iterator it)
{ {
if (!result.empty() && if (!result.empty() &&
(*(result.end() - 1))->GetType() == (*(result.end() - 1))->GetType() ==
cmGeneratorExpressionEvaluator::Text) { cmGeneratorExpressionEvaluator::Text) {
TextContent* textContent = static_cast<TextContent*>(*(result.end() - 1)); cm::static_reference_cast<TextContent>(*(result.end() - 1))
textContent->Extend(it->Length); .Extend(it->Length);
} else { } else {
TextContent* textContent = new TextContent(it->Content, it->Length); auto textContent = cm::make_unique<TextContent>(it->Content, it->Length);
result.push_back(textContent); result.push_back(std::move(textContent));
} }
} }
static void extendResult( static void extendResult(
std::vector<cmGeneratorExpressionEvaluator*>& result, cmGeneratorExpressionParser::cmGeneratorExpressionEvaluatorVector& result,
const std::vector<cmGeneratorExpressionEvaluator*>& contents) cmGeneratorExpressionParser::cmGeneratorExpressionEvaluatorVector&& contents)
{ {
if (!result.empty() && if (!result.empty() &&
(*(result.end() - 1))->GetType() == (*(result.end() - 1))->GetType() ==
cmGeneratorExpressionEvaluator::Text && cmGeneratorExpressionEvaluator::Text &&
contents.front()->GetType() == cmGeneratorExpressionEvaluator::Text) { contents.front()->GetType() == cmGeneratorExpressionEvaluator::Text) {
TextContent* textContent = static_cast<TextContent*>(*(result.end() - 1)); cm::static_reference_cast<TextContent>(*(result.end() - 1))
textContent->Extend( .Extend(
static_cast<TextContent*>(contents.front())->GetLength()); cm::static_reference_cast<TextContent>(contents.front()).GetLength());
delete contents.front(); contents.erase(contents.begin());
cmAppend(result, contents.begin() + 1, contents.end());
} else {
cmAppend(result, contents);
} }
cmAppend(result, std::move(contents));
} }
void cmGeneratorExpressionParser::ParseGeneratorExpression( void cmGeneratorExpressionParser::ParseGeneratorExpression(
std::vector<cmGeneratorExpressionEvaluator*>& result) cmGeneratorExpressionEvaluatorVector& result)
{ {
assert(this->it != this->Tokens.end()); assert(this->it != this->Tokens.end());
unsigned int nestedLevel = this->NestingLevel; unsigned int nestedLevel = this->NestingLevel;
@@ -68,7 +69,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
auto startToken = this->it - 1; auto startToken = this->it - 1;
std::vector<cmGeneratorExpressionEvaluator*> identifier; cmGeneratorExpressionEvaluatorVector identifier;
while (this->it->TokenType != cmGeneratorExpressionToken::EndExpression && while (this->it->TokenType != cmGeneratorExpressionToken::EndExpression &&
this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator) { this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator) {
if (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) { if (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) {
@@ -87,18 +88,18 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
if (this->it != this->Tokens.end() && if (this->it != this->Tokens.end() &&
this->it->TokenType == cmGeneratorExpressionToken::EndExpression) { this->it->TokenType == cmGeneratorExpressionToken::EndExpression) {
GeneratorExpressionContent* content = new GeneratorExpressionContent( auto content = cm::make_unique<GeneratorExpressionContent>(
startToken->Content, startToken->Content,
this->it->Content - startToken->Content + this->it->Length); this->it->Content - startToken->Content + this->it->Length);
assert(this->it != this->Tokens.end()); assert(this->it != this->Tokens.end());
++this->it; ++this->it;
--this->NestingLevel; --this->NestingLevel;
content->SetIdentifier(std::move(identifier)); content->SetIdentifier(std::move(identifier));
result.push_back(content); result.push_back(std::move(content));
return; return;
} }
std::vector<std::vector<cmGeneratorExpressionEvaluator*>> parameters; std::vector<cmGeneratorExpressionEvaluatorVector> parameters;
std::vector<std::vector<cmGeneratorExpressionToken>::const_iterator> std::vector<std::vector<cmGeneratorExpressionToken>::const_iterator>
commaTokens; commaTokens;
std::vector<cmGeneratorExpressionToken>::const_iterator colonToken; std::vector<cmGeneratorExpressionToken>::const_iterator colonToken;
@@ -169,7 +170,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
// treat the '$<' as having been plain text, along with the // treat the '$<' as having been plain text, along with the
// corresponding : and , tokens that might have been found. // corresponding : and , tokens that might have been found.
extendText(result, startToken); extendText(result, startToken);
extendResult(result, identifier); extendResult(result, std::move(identifier));
if (!parameters.empty()) { if (!parameters.empty()) {
extendText(result, colonToken); extendText(result, colonToken);
@@ -179,7 +180,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
assert(parameters.size() > commaTokens.size()); assert(parameters.size() > commaTokens.size());
for (; pit != pend; ++pit, ++commaIt) { for (; pit != pend; ++pit, ++commaIt) {
if (!pit->empty() && !emptyParamTermination) { if (!pit->empty() && !emptyParamTermination) {
extendResult(result, *pit); extendResult(result, std::move(*pit));
} }
if (commaIt != commaTokens.end()) { if (commaIt != commaTokens.end()) {
extendText(result, *commaIt); extendText(result, *commaIt);
@@ -193,15 +194,15 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
size_t contentLength = size_t contentLength =
((this->it - 1)->Content - startToken->Content) + (this->it - 1)->Length; ((this->it - 1)->Content - startToken->Content) + (this->it - 1)->Length;
GeneratorExpressionContent* content = auto content = cm::make_unique<GeneratorExpressionContent>(
new GeneratorExpressionContent(startToken->Content, contentLength); startToken->Content, contentLength);
content->SetIdentifier(std::move(identifier)); content->SetIdentifier(std::move(identifier));
content->SetParameters(std::move(parameters)); content->SetParameters(std::move(parameters));
result.push_back(content); result.push_back(std::move(content));
} }
void cmGeneratorExpressionParser::ParseContent( void cmGeneratorExpressionParser::ParseContent(
std::vector<cmGeneratorExpressionEvaluator*>& result) cmGeneratorExpressionEvaluatorVector& result)
{ {
assert(this->it != this->Tokens.end()); assert(this->it != this->Tokens.end());
switch (this->it->TokenType) { switch (this->it->TokenType) {
@@ -213,17 +214,16 @@ void cmGeneratorExpressionParser::ParseContent(
// A comma in 'plain text' could have split text that should // A comma in 'plain text' could have split text that should
// otherwise be continuous. Extend the last text content instead of // otherwise be continuous. Extend the last text content instead of
// creating a new one. // creating a new one.
TextContent* textContent = cm::static_reference_cast<TextContent>(*(result.end() - 1))
static_cast<TextContent*>(*(result.end() - 1)); .Extend(this->it->Length);
textContent->Extend(this->it->Length);
assert(this->it != this->Tokens.end()); assert(this->it != this->Tokens.end());
++this->it; ++this->it;
return; return;
} }
} }
cmGeneratorExpressionEvaluator* n = auto n =
new TextContent(this->it->Content, this->it->Length); cm::make_unique<TextContent>(this->it->Content, this->it->Length);
result.push_back(n); result.push_back(std::move(n));
assert(this->it != this->Tokens.end()); assert(this->it != this->Tokens.end());
++this->it; ++this->it;
return; return;

View File

@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep #include "cmConfigure.h" // IWYU pragma: keep
#include <memory>
#include <vector> #include <vector>
#include "cmGeneratorExpressionLexer.h" #include "cmGeneratorExpressionLexer.h"
@@ -15,11 +16,14 @@ struct cmGeneratorExpressionParser
{ {
cmGeneratorExpressionParser(std::vector<cmGeneratorExpressionToken> tokens); cmGeneratorExpressionParser(std::vector<cmGeneratorExpressionToken> tokens);
void Parse(std::vector<cmGeneratorExpressionEvaluator*>& result); using cmGeneratorExpressionEvaluatorVector =
std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>>;
void Parse(cmGeneratorExpressionEvaluatorVector& result);
private: private:
void ParseContent(std::vector<cmGeneratorExpressionEvaluator*>&); void ParseContent(cmGeneratorExpressionEvaluatorVector&);
void ParseGeneratorExpression(std::vector<cmGeneratorExpressionEvaluator*>&); void ParseGeneratorExpression(cmGeneratorExpressionEvaluatorVector&);
private: private:
std::vector<cmGeneratorExpressionToken>::const_iterator it; std::vector<cmGeneratorExpressionToken>::const_iterator it;