resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmGeneratorExpressionDAGChecker.h
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #pragma once
4
5 #include "cmConfigure.h" // IWYU pragma: keep
6
7 #include <map>
8 #include <set>
9 #include <string>
10
11 #include "cmListFileCache.h"
12
13 struct GeneratorExpressionContent;
14 struct cmGeneratorExpressionContext;
15 class cmGeneratorTarget;
16
17 #define CM_SELECT_BOTH(F, A1, A2) F(A1, A2)
18 #define CM_SELECT_FIRST(F, A1, A2) F(A1)
19 #define CM_SELECT_SECOND(F, A1, A2) F(A2)
20
21 #define CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, SELECT)                       \
22   SELECT(F, EvaluatingIncludeDirectories, INCLUDE_DIRECTORIES)                \
23   SELECT(F, EvaluatingSystemIncludeDirectories, SYSTEM_INCLUDE_DIRECTORIES)   \
24   SELECT(F, EvaluatingCompileDefinitions, COMPILE_DEFINITIONS)                \
25   SELECT(F, EvaluatingCompileOptions, COMPILE_OPTIONS)                        \
26   SELECT(F, EvaluatingAutoUicOptions, AUTOUIC_OPTIONS)                        \
27   SELECT(F, EvaluatingSources, SOURCES)                                       \
28   SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES)                      \
29   SELECT(F, EvaluatingLinkOptions, LINK_OPTIONS)                              \
30   SELECT(F, EvaluatingLinkDirectories, LINK_DIRECTORIES)                      \
31   SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS)                              \
32   SELECT(F, EvaluatingPrecompileHeaders, PRECOMPILE_HEADERS)
33
34 #define CM_FOR_EACH_TRANSITIVE_PROPERTY(F)                                    \
35   CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH)
36
37 #define CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(F)                             \
38   CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_FIRST)
39
40 #define CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(F)                               \
41   CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_SECOND)
42
43 struct cmGeneratorExpressionDAGChecker
44 {
45   cmGeneratorExpressionDAGChecker(cmListFileBacktrace backtrace,
46                                   cmGeneratorTarget const* target,
47                                   std::string property,
48                                   const GeneratorExpressionContent* content,
49                                   cmGeneratorExpressionDAGChecker* parent);
50   cmGeneratorExpressionDAGChecker(cmGeneratorTarget const* target,
51                                   std::string property,
52                                   const GeneratorExpressionContent* content,
53                                   cmGeneratorExpressionDAGChecker* parent);
54
55   enum Result
56   {
57     DAG,
58     SELF_REFERENCE,
59     CYCLIC_REFERENCE,
60     ALREADY_SEEN
61   };
62
63   Result Check() const;
64
65   void ReportError(cmGeneratorExpressionContext* context,
66                    const std::string& expr);
67
68   bool EvaluatingGenexExpression() const;
69   bool EvaluatingPICExpression() const;
70   bool EvaluatingCompileExpression() const;
71   bool EvaluatingLinkExpression() const;
72   bool EvaluatingLinkOptionsExpression() const;
73
74   enum class ForGenex
75   {
76     ANY,
77     LINK_LIBRARY,
78     LINK_GROUP
79   };
80   bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr,
81                                ForGenex genex = ForGenex::ANY) const;
82
83 #define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
84
85   CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD)
86
87 #undef DECLARE_TRANSITIVE_PROPERTY_METHOD
88
89   bool GetTransitivePropertiesOnly() const;
90   void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; }
91
92   cmGeneratorExpressionDAGChecker const* Top() const;
93   cmGeneratorTarget const* TopTarget() const;
94
95 private:
96   Result CheckGraph() const;
97   void Initialize();
98
99   const cmGeneratorExpressionDAGChecker* const Parent;
100   cmGeneratorTarget const* Target;
101   const std::string Property;
102   mutable std::map<cmGeneratorTarget const*, std::set<std::string>> Seen;
103   const GeneratorExpressionContent* const Content;
104   const cmListFileBacktrace Backtrace;
105   Result CheckResult;
106   bool TransitivePropertiesOnly;
107 };