Use cmsys::auto_ptr to manage cmCompiledGeneratorExpressions

The compiled generator expressions need to outlive the creating
type. For the same reason, store the input string in a std::string.
This commit is contained in:
Stephen Kelly 2012-11-19 19:30:56 +01:00
parent 5ac16ea6e4
commit 76ea420fb9
6 changed files with 44 additions and 45 deletions

View File

@ -47,7 +47,7 @@ std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
{ {
return target->GetLocation(this->Config); return target->GetLocation(this->Config);
} }
return this->GE->Parse(argv0).Evaluate(this->Makefile, this->Config); return this->GE->Parse(argv0)->Evaluate(this->Makefile, this->Config);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -58,7 +58,7 @@ cmCustomCommandGenerator
cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c]; cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
for(unsigned int j=1;j < commandLine.size(); ++j) for(unsigned int j=1;j < commandLine.size(); ++j)
{ {
std::string arg = this->GE->Parse(commandLine[j]).Evaluate(this->Makefile, std::string arg = this->GE->Parse(commandLine[j])->Evaluate(this->Makefile,
this->Config); this->Config);
cmd += " "; cmd += " ";
if(this->OldStyle) if(this->OldStyle)

View File

@ -25,44 +25,29 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmGeneratorExpression::cmGeneratorExpression( cmGeneratorExpression::cmGeneratorExpression(
cmListFileBacktrace const& backtrace): cmListFileBacktrace const& backtrace):
Backtrace(backtrace), CompiledExpression(0) Backtrace(backtrace)
{ {
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const cmCompiledGeneratorExpression & cmsys::auto_ptr<cmCompiledGeneratorExpression>
cmGeneratorExpression::Parse(std::string const& input) cmGeneratorExpression::Parse(std::string const& input)
{ {
return this->Parse(input.c_str()); return this->Parse(input.c_str());
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const cmCompiledGeneratorExpression & cmsys::auto_ptr<cmCompiledGeneratorExpression>
cmGeneratorExpression::Parse(const char* input) cmGeneratorExpression::Parse(const char* input)
{ {
cmGeneratorExpressionLexer l; return cmsys::auto_ptr<cmCompiledGeneratorExpression>(
std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(input); new cmCompiledGeneratorExpression(
bool needsParsing = l.GetSawGeneratorExpression();
std::vector<cmGeneratorExpressionEvaluator*> evaluators;
if (needsParsing)
{
cmGeneratorExpressionParser p(tokens);
p.Parse(evaluators);
}
delete this->CompiledExpression;
this->CompiledExpression = new cmCompiledGeneratorExpression(
this->Backtrace, this->Backtrace,
evaluators, input));
input,
needsParsing);
return *this->CompiledExpression;
} }
cmGeneratorExpression::~cmGeneratorExpression() cmGeneratorExpression::~cmGeneratorExpression()
{ {
delete this->CompiledExpression;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -73,7 +58,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
{ {
if (!this->NeedsParsing) if (!this->NeedsParsing)
{ {
return this->Input; return this->Input.c_str();
} }
this->Output = ""; this->Output = "";
@ -108,12 +93,19 @@ const char *cmCompiledGeneratorExpression::Evaluate(
cmCompiledGeneratorExpression::cmCompiledGeneratorExpression( cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
cmListFileBacktrace const& backtrace, cmListFileBacktrace const& backtrace,
const std::vector<cmGeneratorExpressionEvaluator*> &evaluators, const char *input)
const char *input, bool needsParsing) : Backtrace(backtrace), Input(input ? input : "")
: Backtrace(backtrace), Evaluators(evaluators), Input(input),
NeedsParsing(needsParsing)
{ {
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens =
l.Tokenize(this->Input.c_str());
this->NeedsParsing = l.GetSawGeneratorExpression();
if (this->NeedsParsing)
{
cmGeneratorExpressionParser p(tokens);
p.Parse(this->Evaluators);
}
} }

View File

@ -14,10 +14,12 @@
#define cmGeneratorExpression_h #define cmGeneratorExpression_h
#include "cmStandardIncludes.h" #include "cmStandardIncludes.h"
#include "cmListFileCache.h"
#include <stack> #include <stack>
#include <cmsys/RegularExpression.hxx> #include <cmsys/RegularExpression.hxx>
#include <cmsys/auto_ptr.hxx>
class cmTarget; class cmTarget;
class cmMakefile; class cmMakefile;
@ -44,8 +46,9 @@ public:
cmGeneratorExpression(cmListFileBacktrace const& backtrace); cmGeneratorExpression(cmListFileBacktrace const& backtrace);
~cmGeneratorExpression(); ~cmGeneratorExpression();
const cmCompiledGeneratorExpression& Parse(std::string const& input); cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(
const cmCompiledGeneratorExpression& Parse(const char* input); std::string const& input);
cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(const char* input);
enum PreprocessContext { enum PreprocessContext {
StripAllGeneratorExpressions StripAllGeneratorExpressions
@ -59,7 +62,6 @@ private:
void operator=(const cmGeneratorExpression &); void operator=(const cmGeneratorExpression &);
cmListFileBacktrace const& Backtrace; cmListFileBacktrace const& Backtrace;
cmCompiledGeneratorExpression *CompiledExpression;
}; };
class cmCompiledGeneratorExpression class cmCompiledGeneratorExpression
@ -76,20 +78,24 @@ public:
~cmCompiledGeneratorExpression(); ~cmCompiledGeneratorExpression();
std::string GetInput() const
{
return this->Input;
}
private: private:
cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace, cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
const std::vector<cmGeneratorExpressionEvaluator*> &evaluators, const char *input);
const char *input, bool needsParsing);
friend class cmGeneratorExpression; friend class cmGeneratorExpression;
cmCompiledGeneratorExpression(const cmCompiledGeneratorExpression &); cmCompiledGeneratorExpression(const cmCompiledGeneratorExpression &);
void operator=(const cmCompiledGeneratorExpression &); void operator=(const cmCompiledGeneratorExpression &);
cmListFileBacktrace const& Backtrace; cmListFileBacktrace Backtrace;
const std::vector<cmGeneratorExpressionEvaluator*> Evaluators; std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
const char* const Input; const std::string Input;
const bool NeedsParsing; bool NeedsParsing;
mutable std::set<cmTarget*> Targets; mutable std::set<cmTarget*> Targets;
mutable std::string Output; mutable std::string Output;

View File

@ -267,7 +267,7 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
"INCLUDE_DIRECTORIES", 0, 0); "INCLUDE_DIRECTORIES", 0, 0);
cmSystemTools::ExpandListArgument(ge.Parse(prop) cmSystemTools::ExpandListArgument(ge.Parse(prop)
.Evaluate(this->Makefile, ->Evaluate(this->Makefile,
config, config,
false, false,
this->Target, this->Target,
@ -315,7 +315,7 @@ std::string cmGeneratorTarget::GetCompileDefinitions(const char *config)
cmGeneratorExpressionDAGChecker dagChecker(lfbt, cmGeneratorExpressionDAGChecker dagChecker(lfbt,
this->GetName(), this->GetName(),
defPropName, 0, 0); defPropName, 0, 0);
return ge.Parse(prop).Evaluate(this->Makefile, return ge.Parse(prop)->Evaluate(this->Makefile,
config, config,
false, false,
this->Target, this->Target,

View File

@ -1728,9 +1728,10 @@ cmTargetTraceDependencies
for(cmCustomCommandLine::const_iterator cli = cit->begin(); for(cmCustomCommandLine::const_iterator cli = cit->begin();
cli != cit->end(); ++cli) cli != cit->end(); ++cli)
{ {
const cmCompiledGeneratorExpression &cge = ge.Parse(*cli); const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
cge.Evaluate(this->Makefile, 0, true); = ge.Parse(*cli);
std::set<cmTarget*> geTargets = cge.GetTargets(); cge->Evaluate(this->Makefile, 0, true);
std::set<cmTarget*> geTargets = cge->GetTargets();
for(std::set<cmTarget*>::const_iterator it = geTargets.begin(); for(std::set<cmTarget*>::const_iterator it = geTargets.begin();
it != geTargets.end(); ++it) it != geTargets.end(); ++it)
{ {

View File

@ -112,7 +112,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
else else
{ {
// Use the command name given. // Use the command name given.
exe = ge.Parse(exe.c_str()).Evaluate(mf, config); exe = ge.Parse(exe.c_str())->Evaluate(mf, config);
cmSystemTools::ConvertToUnixSlashes(exe); cmSystemTools::ConvertToUnixSlashes(exe);
} }
@ -122,7 +122,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
for(std::vector<std::string>::const_iterator ci = command.begin()+1; for(std::vector<std::string>::const_iterator ci = command.begin()+1;
ci != command.end(); ++ci) ci != command.end(); ++ci)
{ {
os << " " << lg->EscapeForCMake(ge.Parse(*ci).Evaluate(mf, config)); os << " " << lg->EscapeForCMake(ge.Parse(*ci)->Evaluate(mf, config));
} }
// Finish the test command. // Finish the test command.