blob: d45465e38f02952d56ae3c960ae05e2ddb274a15 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
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
Yifan Hong52165692016-08-12 18:06:40 -070017#ifndef CONSTANT_EXPRESSION_H_
18
19#define CONSTANT_EXPRESSION_H_
20
21#include <android-base/macros.h>
Timur Iskhakov891a8662017-08-25 21:53:48 -070022#include <functional>
Timur Iskhakov7296af12017-08-09 21:52:48 +000023#include <memory>
Yifan Hong52165692016-08-12 18:06:40 -070024#include <string>
Timur Iskhakov891a8662017-08-25 21:53:48 -070025#include <unordered_set>
26#include <vector>
Timur Iskhakov7296af12017-08-09 21:52:48 +000027
28#include "Reference.h"
Yifan Hong57886972016-08-17 10:42:15 -070029#include "ScalarType.h"
Yifan Hong52165692016-08-12 18:06:40 -070030
31namespace android {
32
Timur Iskhakov7296af12017-08-09 21:52:48 +000033struct LocalIdentifier;
34
35struct LiteralConstantExpression;
36struct UnaryConstantExpression;
37struct BinaryConstantExpression;
38struct TernaryConstantExpression;
39struct ReferenceConstantExpression;
40
Yifan Hong52165692016-08-12 18:06:40 -070041/**
42 * A constant expression is represented by a tree.
43 */
44struct ConstantExpression {
Timur Iskhakov7296af12017-08-09 21:52:48 +000045 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);
Yifan Hong57886972016-08-17 10:42:15 -070048
Neel Mehta3b414a82019-07-02 15:47:48 -070049 ConstantExpression(const std::string& expr);
Timur Iskhakov7296af12017-08-09 21:52:48 +000050 virtual ~ConstantExpression() {}
Yifan Hong57886972016-08-17 10:42:15 -070051
Timur Iskhakova6d33882017-09-01 13:02:09 -070052 virtual bool isReferenceConstantExpression() const;
53
Neel Mehta1ca3e782019-07-18 15:16:22 -070054 void surroundWithParens();
55
Timur Iskhakov891a8662017-08-25 21:53:48 -070056 // Proceeds recursive pass
57 // Makes sure to visit each node only once
58 // Used to provide lookup and lazy evaluation
59 status_t recursivePass(const std::function<status_t(ConstantExpression*)>& func,
Timur Iskhakov82c048e2017-09-09 01:20:53 -070060 std::unordered_set<const ConstantExpression*>* visited,
61 bool processBeforeDependencies);
Timur Iskhakovb58f4182017-08-29 15:19:24 -070062 status_t recursivePass(const std::function<status_t(const ConstantExpression*)>& func,
Timur Iskhakov82c048e2017-09-09 01:20:53 -070063 std::unordered_set<const ConstantExpression*>* visited,
64 bool processBeforeDependencies) const;
Timur Iskhakov891a8662017-08-25 21:53:48 -070065
Steven Moreland12f0ab12018-11-02 17:27:37 -070066 // If this object is in an invalid state.
67 virtual status_t validate() const;
68
Timur Iskhakov891a8662017-08-25 21:53:48 -070069 // Evaluates current constant expression
70 // Doesn't call recursive evaluation, so must be called after dependencies
Timur Iskhakov7296af12017-08-09 21:52:48 +000071 virtual void evaluate() = 0;
Colin Crossa549b712017-08-09 18:33:22 +000072
Timur Iskhakovb58f4182017-08-29 15:19:24 -070073 std::vector<ConstantExpression*> getConstantExpressions();
74 virtual std::vector<const ConstantExpression*> getConstantExpressions() const = 0;
Timur Iskhakov891a8662017-08-25 21:53:48 -070075
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070076 std::vector<Reference<LocalIdentifier>*> getReferences();
77 virtual std::vector<const Reference<LocalIdentifier>*> getReferences() const;
78
Steven Moreland12f0ab12018-11-02 17:27:37 -070079 std::vector<Reference<Type>*> getTypeReferences();
80 virtual std::vector<const Reference<Type>*> getTypeReferences() const;
81
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070082 // Recursive tree pass checkAcyclic return type.
83 // Stores cycle end for nice error messages.
84 struct CheckAcyclicStatus {
Timur Iskhakova6d33882017-09-01 13:02:09 -070085 CheckAcyclicStatus(status_t status, const ConstantExpression* cycleEnd = nullptr,
86 const ReferenceConstantExpression* lastReferenceExpression = nullptr);
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070087
88 status_t status;
89
90 // If a cycle is found, stores the end of cycle.
91 // While going back in recursion, this is used to stop printing the cycle.
92 const ConstantExpression* cycleEnd;
Timur Iskhakova6d33882017-09-01 13:02:09 -070093
94 // The last ReferenceConstantExpression visited on the cycle.
95 const ReferenceConstantExpression* lastReference;
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070096 };
97
98 // Recursive tree pass that ensures that constant expressions definitions
99 // are acyclic.
100 CheckAcyclicStatus checkAcyclic(std::unordered_set<const ConstantExpression*>* visited,
101 std::unordered_set<const ConstantExpression*>* stack) const;
102
Timur Iskhakov7296af12017-08-09 21:52:48 +0000103 /* Returns true iff the value has already been evaluated. */
104 bool isEvaluated() const;
Steven Morelandf21962d2018-08-09 12:44:40 -0700105 /* Evaluated result in a string form with comment if applicable. */
Yifan Hongfc610cd2016-09-22 13:34:45 -0700106 std::string value() const;
Steven Morelandf21962d2018-08-09 12:44:40 -0700107 /* Evaluated result in a string form with comment if applicable. */
Yifan Hongf24fa852016-09-23 11:03:15 -0700108 std::string cppValue() const;
Steven Morelandf21962d2018-08-09 12:44:40 -0700109 /* Evaluated result in a string form with comment if applicable. */
Yifan Hongf24fa852016-09-23 11:03:15 -0700110 std::string javaValue() const;
Yifan Hong57886972016-08-17 10:42:15 -0700111 /* Evaluated result in a string form, with given contextual kind. */
Yifan Hongc07b2022016-11-08 12:44:24 -0800112 std::string value(ScalarType::Kind castKind) const;
113 /* Evaluated result in a string form, with given contextual kind. */
Yifan Hongfc610cd2016-09-22 13:34:45 -0700114 std::string cppValue(ScalarType::Kind castKind) const;
Yifan Hong19ca75a2016-08-31 10:20:03 -0700115 /* Evaluated result in a string form, with given contextual kind. */
Yifan Hongfc610cd2016-09-22 13:34:45 -0700116 std::string javaValue(ScalarType::Kind castKind) const;
Steven Morelandf21962d2018-08-09 12:44:40 -0700117
118 /* The expression representing this value for use in comments when the value is not needed */
119 const std::string& expression() const;
120
Yifan Hongf24fa852016-09-23 11:03:15 -0700121 /* Return a ConstantExpression that is 1 plus the original. */
Timur Iskhakov7296af12017-08-09 21:52:48 +0000122 std::unique_ptr<ConstantExpression> addOne(ScalarType::Kind baseKind);
Yifan Honge77ca132016-09-27 10:49:05 -0700123
124 size_t castSizeT() const;
Yifan Hong52165692016-08-12 18:06:40 -0700125
Timur Iskhakov35930c42017-08-28 18:49:54 -0700126 // Marks that package proceeding is completed
127 // Post parse passes must be proceeded during owner package parsin
128 void setPostParseCompleted();
129
Steven Morelandf21962d2018-08-09 12:44:40 -0700130 /*
131 * Helper function for all cpp/javaValue methods.
132 * Returns a plain string (without any prefixes or suffixes, just the
133 * digits) converted from mValue.
134 */
135 std::string rawValue() const;
136 std::string rawValue(ScalarType::Kind castKind) const;
137
Timur Iskhakov7296af12017-08-09 21:52:48 +0000138 private:
139 /* If the result value has been evaluated. */
140 bool mIsEvaluated = false;
Yifan Hong57886972016-08-17 10:42:15 -0700141 /* The formatted expression. */
Neel Mehta1ca3e782019-07-18 15:16:22 -0700142 std::string mExpr;
Yifan Hongf24fa852016-09-23 11:03:15 -0700143 /* The kind of the result value. */
Yifan Hong57886972016-08-17 10:42:15 -0700144 ScalarType::Kind mValueKind;
Yifan Hongf24fa852016-09-23 11:03:15 -0700145 /* The stored result value. */
Yifan Hong57886972016-08-17 10:42:15 -0700146 uint64_t mValue;
Yifan Hong5706a432016-11-02 09:44:18 -0700147 /* true if description() does not offer more information than value(). */
148 bool mTrivialDescription = false;
Yifan Hong52165692016-08-12 18:06:40 -0700149
Timur Iskhakov35930c42017-08-28 18:49:54 -0700150 bool mIsPostParseCompleted = false;
151
Yifan Hongf24fa852016-09-23 11:03:15 -0700152 /*
Steven Morelandf21962d2018-08-09 12:44:40 -0700153 * Helper function, gives suffix comment to add to value/cppValue/javaValue
Yifan Hongf24fa852016-09-23 11:03:15 -0700154 */
Steven Morelandf21962d2018-08-09 12:44:40 -0700155 std::string descriptionSuffix() const;
Yifan Honge77ca132016-09-27 10:49:05 -0700156
157 /*
158 * Return the value casted to the given type.
159 * First cast it according to mValueKind, then cast it to T.
160 * Assumes !containsIdentifiers()
161 */
Timur Iskhakov7296af12017-08-09 21:52:48 +0000162 template <typename T>
163 T cast() const;
164
165 friend struct LiteralConstantExpression;
166 friend struct UnaryConstantExpression;
167 friend struct BinaryConstantExpression;
168 friend struct TernaryConstantExpression;
169 friend struct ReferenceConstantExpression;
Steven Moreland12f0ab12018-11-02 17:27:37 -0700170 friend struct AttributeConstantExpression;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000171};
172
173struct LiteralConstantExpression : public ConstantExpression {
174 LiteralConstantExpression(ScalarType::Kind kind, uint64_t value);
Steven Moreland77943692018-08-09 12:53:42 -0700175 LiteralConstantExpression(ScalarType::Kind kind, uint64_t value, const std::string& expr);
Timur Iskhakov7296af12017-08-09 21:52:48 +0000176 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700177 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Steven Morelandd9d6dcb2017-09-20 15:55:39 -0700178
179 static LiteralConstantExpression* tryParse(const std::string& value);
Timur Iskhakov7296af12017-08-09 21:52:48 +0000180};
181
182struct UnaryConstantExpression : public ConstantExpression {
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700183 UnaryConstantExpression(const std::string& mOp, ConstantExpression* value);
Timur Iskhakov7296af12017-08-09 21:52:48 +0000184 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700185 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000186
187 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700188 ConstantExpression* const mUnary;
189 std::string mOp;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000190};
191
192struct BinaryConstantExpression : public ConstantExpression {
193 BinaryConstantExpression(ConstantExpression* lval, const std::string& op,
194 ConstantExpression* rval);
195 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700196 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000197
198 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700199 ConstantExpression* const mLval;
200 ConstantExpression* const mRval;
201 const std::string mOp;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000202};
203
204struct TernaryConstantExpression : public ConstantExpression {
205 TernaryConstantExpression(ConstantExpression* cond, ConstantExpression* trueVal,
206 ConstantExpression* falseVal);
207 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700208 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000209
210 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700211 ConstantExpression* const mCond;
212 ConstantExpression* const mTrueVal;
213 ConstantExpression* const mFalseVal;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000214};
215
216struct ReferenceConstantExpression : public ConstantExpression {
217 ReferenceConstantExpression(const Reference<LocalIdentifier>& value, const std::string& expr);
Timur Iskhakova6d33882017-09-01 13:02:09 -0700218
219 bool isReferenceConstantExpression() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000220 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700221 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov77dd65c2017-08-31 22:46:56 -0700222 std::vector<const Reference<LocalIdentifier>*> getReferences() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000223
224 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700225 Reference<LocalIdentifier> mReference;
Yifan Hong52165692016-08-12 18:06:40 -0700226};
227
Steven Moreland12f0ab12018-11-02 17:27:37 -0700228// This constant expression is a compile-time calculatable expression based on another type
229struct AttributeConstantExpression : public ConstantExpression {
230 AttributeConstantExpression(const Reference<Type>& value, const std::string& fqname,
231 const std::string& tag);
232
233 status_t validate() const override;
234 void evaluate() override;
235
236 std::vector<const ConstantExpression*> getConstantExpressions() const override;
237 std::vector<const Reference<Type>*> getTypeReferences() const override;
238
239 private:
240 Reference<Type> mReference;
241 const std::string mTag;
242};
243
Yifan Hong52165692016-08-12 18:06:40 -0700244} // namespace android
245
246#endif // CONSTANT_EXPRESSION_H_