• 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     // Evaluates current constant expression
64     // Doesn't call recursive evaluation, so must be called after dependencies
65     virtual void evaluate() = 0;
66 
67     std::vector<ConstantExpression*> getConstantExpressions();
68     virtual std::vector<const ConstantExpression*> getConstantExpressions() const = 0;
69 
70     std::vector<Reference<LocalIdentifier>*> getReferences();
71     virtual std::vector<const Reference<LocalIdentifier>*> getReferences() const;
72 
73     // Recursive tree pass checkAcyclic return type.
74     // Stores cycle end for nice error messages.
75     struct CheckAcyclicStatus {
76         CheckAcyclicStatus(status_t status, const ConstantExpression* cycleEnd = nullptr,
77                            const ReferenceConstantExpression* lastReferenceExpression = nullptr);
78 
79         status_t status;
80 
81         // If a cycle is found, stores the end of cycle.
82         // While going back in recursion, this is used to stop printing the cycle.
83         const ConstantExpression* cycleEnd;
84 
85         // The last ReferenceConstantExpression visited on the cycle.
86         const ReferenceConstantExpression* lastReference;
87     };
88 
89     // Recursive tree pass that ensures that constant expressions definitions
90     // are acyclic.
91     CheckAcyclicStatus checkAcyclic(std::unordered_set<const ConstantExpression*>* visited,
92                                     std::unordered_set<const ConstantExpression*>* stack) const;
93 
94     /* Returns true iff the value has already been evaluated. */
95     bool isEvaluated() const;
96     /* Evaluated result in a string form. */
97     std::string value() const;
98     /* Evaluated result in a string form. */
99     std::string cppValue() const;
100     /* Evaluated result in a string form. */
101     std::string javaValue() const;
102     /* Evaluated result in a string form, with given contextual kind. */
103     std::string value(ScalarType::Kind castKind) const;
104     /* Evaluated result in a string form, with given contextual kind. */
105     std::string cppValue(ScalarType::Kind castKind) const;
106     /* Evaluated result in a string form, with given contextual kind. */
107     std::string javaValue(ScalarType::Kind castKind) const;
108     /* Formatted expression with type. */
109     const std::string& description() const;
110     /* See mTrivialDescription */
111     bool descriptionIsTrivial() const;
112     /* Return a ConstantExpression that is 1 plus the original. */
113     std::unique_ptr<ConstantExpression> addOne(ScalarType::Kind baseKind);
114 
115     size_t castSizeT() const;
116 
117     // Marks that package proceeding is completed
118     // Post parse passes must be proceeded during owner package parsin
119     void setPostParseCompleted();
120 
121    private:
122     /* If the result value has been evaluated. */
123     bool mIsEvaluated = false;
124     /* The formatted expression. */
125     std::string mExpr;
126     /* The kind of the result value. */
127     ScalarType::Kind mValueKind;
128     /* The stored result value. */
129     uint64_t mValue;
130     /* true if description() does not offer more information than value(). */
131     bool mTrivialDescription = false;
132 
133     bool mIsPostParseCompleted = false;
134 
135     /*
136      * Helper function for all cpp/javaValue methods.
137      * Returns a plain string (without any prefixes or suffixes, just the
138      * digits) converted from mValue.
139      */
140     std::string rawValue(ScalarType::Kind castKind) const;
141 
142     /*
143      * Return the value casted to the given type.
144      * First cast it according to mValueKind, then cast it to T.
145      * Assumes !containsIdentifiers()
146      */
147     template <typename T>
148     T cast() const;
149 
150     friend struct LiteralConstantExpression;
151     friend struct UnaryConstantExpression;
152     friend struct BinaryConstantExpression;
153     friend struct TernaryConstantExpression;
154     friend struct ReferenceConstantExpression;
155 };
156 
157 struct LiteralConstantExpression : public ConstantExpression {
158     LiteralConstantExpression(ScalarType::Kind kind, uint64_t value);
159     void evaluate() override;
160     std::vector<const ConstantExpression*> getConstantExpressions() const override;
161 
162     static LiteralConstantExpression* tryParse(const std::string& value);
163 
164 private:
165     LiteralConstantExpression(ScalarType::Kind kind, uint64_t value, const std::string& expr);
166 };
167 
168 struct UnaryConstantExpression : public ConstantExpression {
169     UnaryConstantExpression(const std::string& mOp, ConstantExpression* value);
170     void evaluate() override;
171     std::vector<const ConstantExpression*> getConstantExpressions() const override;
172 
173    private:
174     ConstantExpression* const mUnary;
175     std::string mOp;
176 };
177 
178 struct BinaryConstantExpression : public ConstantExpression {
179     BinaryConstantExpression(ConstantExpression* lval, const std::string& op,
180                              ConstantExpression* rval);
181     void evaluate() override;
182     std::vector<const ConstantExpression*> getConstantExpressions() const override;
183 
184    private:
185     ConstantExpression* const mLval;
186     ConstantExpression* const mRval;
187     const std::string mOp;
188 };
189 
190 struct TernaryConstantExpression : public ConstantExpression {
191     TernaryConstantExpression(ConstantExpression* cond, ConstantExpression* trueVal,
192                               ConstantExpression* falseVal);
193     void evaluate() override;
194     std::vector<const ConstantExpression*> getConstantExpressions() const override;
195 
196    private:
197     ConstantExpression* const mCond;
198     ConstantExpression* const mTrueVal;
199     ConstantExpression* const mFalseVal;
200 };
201 
202 struct ReferenceConstantExpression : public ConstantExpression {
203     ReferenceConstantExpression(const Reference<LocalIdentifier>& value, const std::string& expr);
204 
205     bool isReferenceConstantExpression() const override;
206     void evaluate() override;
207     std::vector<const ConstantExpression*> getConstantExpressions() const override;
208     std::vector<const Reference<LocalIdentifier>*> getReferences() const override;
209 
210    private:
211     Reference<LocalIdentifier> mReference;
212 };
213 
214 }  // namespace android
215 
216 #endif  // CONSTANT_EXPRESSION_H_
217