• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CONSTANT_EXPRESSION_H_
18 
19 #define CONSTANT_EXPRESSION_H_
20 
21 #include <android-base/macros.h>
22 #include <functional>
23 #include <memory>
24 #include <string>
25 #include <unordered_set>
26 #include <vector>
27 
28 #include "Reference.h"
29 #include "ScalarType.h"
30 
31 namespace android {
32 
33 struct LocalIdentifier;
34 
35 struct LiteralConstantExpression;
36 struct UnaryConstantExpression;
37 struct BinaryConstantExpression;
38 struct TernaryConstantExpression;
39 struct ReferenceConstantExpression;
40 
41 /**
42  * A constant expression is represented by a tree.
43  */
44 struct ConstantExpression {
45     static std::unique_ptr<ConstantExpression> Zero(ScalarType::Kind kind);
46     static std::unique_ptr<ConstantExpression> One(ScalarType::Kind kind);
47     static std::unique_ptr<ConstantExpression> ValueOf(ScalarType::Kind kind, uint64_t value);
48 
~ConstantExpressionConstantExpression49     virtual ~ConstantExpression() {}
50 
51     virtual bool isReferenceConstantExpression() const;
52 
53     // Proceeds recursive pass
54     // Makes sure to visit each node only once
55     // Used to provide lookup and lazy evaluation
56     status_t recursivePass(const std::function<status_t(ConstantExpression*)>& func,
57                            std::unordered_set<const ConstantExpression*>* visited,
58                            bool processBeforeDependencies);
59     status_t recursivePass(const std::function<status_t(const ConstantExpression*)>& func,
60                            std::unordered_set<const ConstantExpression*>* visited,
61                            bool processBeforeDependencies) const;
62 
63     // If this object is in an invalid state.
64     virtual status_t validate() const;
65 
66     // Evaluates current constant expression
67     // Doesn't call recursive evaluation, so must be called after dependencies
68     virtual void evaluate() = 0;
69 
70     std::vector<ConstantExpression*> getConstantExpressions();
71     virtual std::vector<const ConstantExpression*> getConstantExpressions() const = 0;
72 
73     std::vector<Reference<LocalIdentifier>*> getReferences();
74     virtual std::vector<const Reference<LocalIdentifier>*> getReferences() const;
75 
76     std::vector<Reference<Type>*> getTypeReferences();
77     virtual std::vector<const Reference<Type>*> getTypeReferences() const;
78 
79     // Recursive tree pass checkAcyclic return type.
80     // Stores cycle end for nice error messages.
81     struct CheckAcyclicStatus {
82         CheckAcyclicStatus(status_t status, const ConstantExpression* cycleEnd = nullptr,
83                            const ReferenceConstantExpression* lastReferenceExpression = nullptr);
84 
85         status_t status;
86 
87         // If a cycle is found, stores the end of cycle.
88         // While going back in recursion, this is used to stop printing the cycle.
89         const ConstantExpression* cycleEnd;
90 
91         // The last ReferenceConstantExpression visited on the cycle.
92         const ReferenceConstantExpression* lastReference;
93     };
94 
95     // Recursive tree pass that ensures that constant expressions definitions
96     // are acyclic.
97     CheckAcyclicStatus checkAcyclic(std::unordered_set<const ConstantExpression*>* visited,
98                                     std::unordered_set<const ConstantExpression*>* stack) const;
99 
100     /* Returns true iff the value has already been evaluated. */
101     bool isEvaluated() const;
102     /* Evaluated result in a string form with comment if applicable. */
103     std::string value() const;
104     /* Evaluated result in a string form with comment if applicable. */
105     std::string cppValue() const;
106     /* Evaluated result in a string form with comment if applicable. */
107     std::string javaValue() const;
108     /* Evaluated result in a string form, with given contextual kind. */
109     std::string value(ScalarType::Kind castKind) const;
110     /* Evaluated result in a string form, with given contextual kind. */
111     std::string cppValue(ScalarType::Kind castKind) const;
112     /* Evaluated result in a string form, with given contextual kind. */
113     std::string javaValue(ScalarType::Kind castKind) const;
114 
115     /* The expression representing this value for use in comments when the value is not needed */
116     const std::string& expression() const;
117 
118     /* Return a ConstantExpression that is 1 plus the original. */
119     std::unique_ptr<ConstantExpression> addOne(ScalarType::Kind baseKind);
120 
121     size_t castSizeT() const;
122 
123     // Marks that package proceeding is completed
124     // Post parse passes must be proceeded during owner package parsin
125     void setPostParseCompleted();
126 
127     /*
128      * Helper function for all cpp/javaValue methods.
129      * Returns a plain string (without any prefixes or suffixes, just the
130      * digits) converted from mValue.
131      */
132     std::string rawValue() const;
133     std::string rawValue(ScalarType::Kind castKind) const;
134 
135    private:
136     /* If the result value has been evaluated. */
137     bool mIsEvaluated = false;
138     /* The formatted expression. */
139     std::string mExpr;
140     /* The kind of the result value. */
141     ScalarType::Kind mValueKind;
142     /* The stored result value. */
143     uint64_t mValue;
144     /* true if description() does not offer more information than value(). */
145     bool mTrivialDescription = false;
146 
147     bool mIsPostParseCompleted = false;
148 
149     /*
150      * Helper function, gives suffix comment to add to value/cppValue/javaValue
151      */
152     std::string descriptionSuffix() const;
153 
154     /*
155      * Return the value casted to the given type.
156      * First cast it according to mValueKind, then cast it to T.
157      * Assumes !containsIdentifiers()
158      */
159     template <typename T>
160     T cast() const;
161 
162     friend struct LiteralConstantExpression;
163     friend struct UnaryConstantExpression;
164     friend struct BinaryConstantExpression;
165     friend struct TernaryConstantExpression;
166     friend struct ReferenceConstantExpression;
167     friend struct AttributeConstantExpression;
168 };
169 
170 struct LiteralConstantExpression : public ConstantExpression {
171     LiteralConstantExpression(ScalarType::Kind kind, uint64_t value);
172     LiteralConstantExpression(ScalarType::Kind kind, uint64_t value, const std::string& expr);
173     void evaluate() override;
174     std::vector<const ConstantExpression*> getConstantExpressions() const override;
175 
176     static LiteralConstantExpression* tryParse(const std::string& value);
177 };
178 
179 struct UnaryConstantExpression : public ConstantExpression {
180     UnaryConstantExpression(const std::string& mOp, ConstantExpression* value);
181     void evaluate() override;
182     std::vector<const ConstantExpression*> getConstantExpressions() const override;
183 
184    private:
185     ConstantExpression* const mUnary;
186     std::string mOp;
187 };
188 
189 struct BinaryConstantExpression : public ConstantExpression {
190     BinaryConstantExpression(ConstantExpression* lval, const std::string& op,
191                              ConstantExpression* rval);
192     void evaluate() override;
193     std::vector<const ConstantExpression*> getConstantExpressions() const override;
194 
195    private:
196     ConstantExpression* const mLval;
197     ConstantExpression* const mRval;
198     const std::string mOp;
199 };
200 
201 struct TernaryConstantExpression : public ConstantExpression {
202     TernaryConstantExpression(ConstantExpression* cond, ConstantExpression* trueVal,
203                               ConstantExpression* falseVal);
204     void evaluate() override;
205     std::vector<const ConstantExpression*> getConstantExpressions() const override;
206 
207    private:
208     ConstantExpression* const mCond;
209     ConstantExpression* const mTrueVal;
210     ConstantExpression* const mFalseVal;
211 };
212 
213 struct ReferenceConstantExpression : public ConstantExpression {
214     ReferenceConstantExpression(const Reference<LocalIdentifier>& value, const std::string& expr);
215 
216     bool isReferenceConstantExpression() const override;
217     void evaluate() override;
218     std::vector<const ConstantExpression*> getConstantExpressions() const override;
219     std::vector<const Reference<LocalIdentifier>*> getReferences() const override;
220 
221    private:
222     Reference<LocalIdentifier> mReference;
223 };
224 
225 // This constant expression is a compile-time calculatable expression based on another type
226 struct AttributeConstantExpression : public ConstantExpression {
227     AttributeConstantExpression(const Reference<Type>& value, const std::string& fqname,
228                                 const std::string& tag);
229 
230     status_t validate() const override;
231     void evaluate() override;
232 
233     std::vector<const ConstantExpression*> getConstantExpressions() const override;
234     std::vector<const Reference<Type>*> getTypeReferences() const override;
235 
236    private:
237     Reference<Type> mReference;
238     const std::string mTag;
239 };
240 
241 }  // namespace android
242 
243 #endif  // CONSTANT_EXPRESSION_H_
244