From 0d8db250ceedf908a32c96c0a7e532f3fe9e61d9 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 10 Jun 2013 16:01:59 +0200 Subject: [PATCH] Use a preprocessor loop to manage the valid transitive properties. Hopefully this will prevent regressions when adding further transitive properties in the future. --- Source/cmExportTryCompileFileGenerator.cxx | 7 ++++--- Source/cmGeneratorExpressionDAGChecker.cxx | 10 ++++++--- Source/cmGeneratorExpressionDAGChecker.h | 18 +++++++++++++--- Source/cmGeneratorExpressionEvaluator.cxx | 24 ++++++++++++++-------- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index 29406dc09..e7b185a57 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -31,9 +31,10 @@ bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os) ImportPropertyMap properties; - this->FindTargets("INTERFACE_INCLUDE_DIRECTORIES", te, emittedDeps); - this->FindTargets("INTERFACE_COMPILE_DEFINITIONS", te, emittedDeps); - this->FindTargets("INTERFACE_COMPILE_OPTIONS", te, emittedDeps); +#define FIND_TARGETS(PROPERTY) \ + this->FindTargets(#PROPERTY, te, emittedDeps); + + CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(FIND_TARGETS) this->PopulateProperties(te, properties, emittedDeps); diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 6c6a7d4e0..3e03c099e 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -33,9 +33,13 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( } this->CheckResult = this->checkGraph(); - if (CheckResult == DAG && (top->EvaluatingIncludeDirectories() - || top->EvaluatingCompileDefinitions() - || top->EvaluatingCompileOptions())) +#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) \ + top->METHOD () || + + if (CheckResult == DAG && ( + CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(TEST_TRANSITIVE_PROPERTY_METHOD) + false) + ) { std::map >::const_iterator it = top->Seen.find(target); diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index 8d9fd76ab..85b13e50e 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -16,6 +16,16 @@ #include "cmGeneratorExpressionEvaluator.h" +#define CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(F) \ + F(EvaluatingIncludeDirectories) \ + F(EvaluatingCompileDefinitions) \ + F(EvaluatingCompileOptions) + +#define CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(F) \ + F(INTERFACE_INCLUDE_DIRECTORIES) \ + F(INTERFACE_COMPILE_DEFINITIONS) \ + F(INTERFACE_COMPILE_OPTIONS) + //---------------------------------------------------------------------------- struct cmGeneratorExpressionDAGChecker { @@ -38,9 +48,11 @@ struct cmGeneratorExpressionDAGChecker const std::string &expr); bool EvaluatingLinkLibraries(); - bool EvaluatingIncludeDirectories() const; - bool EvaluatingCompileDefinitions() const; - bool EvaluatingCompileOptions() const; + +#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) \ + bool METHOD () const; + +CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD) private: Result checkGraph() const; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 28f749d31..676fd2955 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -491,11 +491,13 @@ static const struct JoinNode : public cmGeneratorExpressionNode } } joinNode; +#define TRANSITIVE_PROPERTY_NAME(PROPERTY) \ + , #PROPERTY + //---------------------------------------------------------------------------- static const char* targetPropertyTransitiveWhitelist[] = { - "INTERFACE_INCLUDE_DIRECTORIES" - , "INTERFACE_COMPILE_DEFINITIONS" - , "INTERFACE_COMPILE_OPTIONS" + 0 + CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME) }; std::string getLinkedTargetsContent(const std::vector &libraries, @@ -675,7 +677,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode // No error. We just skip cyclic references. return std::string(); case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: - for (size_t i = 0; + for (size_t i = 1; i < (sizeof(targetPropertyTransitiveWhitelist) / sizeof(*targetPropertyTransitiveWhitelist)); ++i) @@ -703,9 +705,13 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } else { - assert(dagCheckerParent->EvaluatingIncludeDirectories() - || dagCheckerParent->EvaluatingCompileDefinitions() - || dagCheckerParent->EvaluatingCompileOptions()); +#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) \ + dagCheckerParent->METHOD () || + + assert( + CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD( + ASSERT_TRANSITIVE_PROPERTY_METHOD) + false); } } @@ -732,7 +738,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode cmTarget *headTarget = context->HeadTarget ? context->HeadTarget : target; - const char **transBegin = targetPropertyTransitiveWhitelist; + const char **transBegin = targetPropertyTransitiveWhitelist + 1; const char **transEnd = targetPropertyTransitiveWhitelist + (sizeof(targetPropertyTransitiveWhitelist) / sizeof(*targetPropertyTransitiveWhitelist)); @@ -798,7 +804,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode return linkedTargetsContent; } - for (size_t i = 0; + for (size_t i = 1; i < (sizeof(targetPropertyTransitiveWhitelist) / sizeof(*targetPropertyTransitiveWhitelist)); ++i)