فهرست منبع

cmGeneratorExpressionEvaluator: Modernize memory management

Marc Chevrier 5 سال پیش
والد
کامیت
d74416a9cd

+ 8 - 0
Source/cmAlgorithms.h

@@ -145,6 +145,14 @@ void cmDeleteAll(Range const& r)
                 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>
 void cmAppend(std::vector<T*>& v, std::vector<std::unique_ptr<T>> const& r)
 {

+ 3 - 7
Source/cmGeneratorExpression.cxx

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

+ 1 - 1
Source/cmGeneratorExpression.h

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

+ 6 - 15
Source/cmGeneratorExpressionEvaluator.cxx

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

+ 10 - 6
Source/cmGeneratorExpressionEvaluator.h

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

+ 32 - 32
Source/cmGeneratorExpressionParser.cxx

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

+ 7 - 3
Source/cmGeneratorExpressionParser.h

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