blob: 9f20fd5dfc20e64091759c4bb4813d46496974e6 [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
Timur Iskhakov891a8662017-08-25 21:53:48 -070054 // Proceeds recursive pass
55 // Makes sure to visit each node only once
56 // Used to provide lookup and lazy evaluation
57 status_t recursivePass(const std::function<status_t(ConstantExpression*)>& func,
Timur Iskhakov82c048e2017-09-09 01:20:53 -070058 std::unordered_set<const ConstantExpression*>* visited,
59 bool processBeforeDependencies);
Timur Iskhakovb58f4182017-08-29 15:19:24 -070060 status_t recursivePass(const std::function<status_t(const ConstantExpression*)>& func,
Timur Iskhakov82c048e2017-09-09 01:20:53 -070061 std::unordered_set<const ConstantExpression*>* visited,
62 bool processBeforeDependencies) const;
Timur Iskhakov891a8662017-08-25 21:53:48 -070063
Steven Moreland12f0ab12018-11-02 17:27:37 -070064 // If this object is in an invalid state.
65 virtual status_t validate() const;
66
Timur Iskhakov891a8662017-08-25 21:53:48 -070067 // Evaluates current constant expression
68 // Doesn't call recursive evaluation, so must be called after dependencies
Timur Iskhakov7296af12017-08-09 21:52:48 +000069 virtual void evaluate() = 0;
Colin Crossa549b712017-08-09 18:33:22 +000070
Timur Iskhakovb58f4182017-08-29 15:19:24 -070071 std::vector<ConstantExpression*> getConstantExpressions();
72 virtual std::vector<const ConstantExpression*> getConstantExpressions() const = 0;
Timur Iskhakov891a8662017-08-25 21:53:48 -070073
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070074 std::vector<Reference<LocalIdentifier>*> getReferences();
75 virtual std::vector<const Reference<LocalIdentifier>*> getReferences() const;
76
Steven Moreland12f0ab12018-11-02 17:27:37 -070077 std::vector<Reference<Type>*> getTypeReferences();
78 virtual std::vector<const Reference<Type>*> getTypeReferences() const;
79
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070080 // Recursive tree pass checkAcyclic return type.
81 // Stores cycle end for nice error messages.
82 struct CheckAcyclicStatus {
Timur Iskhakova6d33882017-09-01 13:02:09 -070083 CheckAcyclicStatus(status_t status, const ConstantExpression* cycleEnd = nullptr,
84 const ReferenceConstantExpression* lastReferenceExpression = nullptr);
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070085
86 status_t status;
87
88 // If a cycle is found, stores the end of cycle.
89 // While going back in recursion, this is used to stop printing the cycle.
90 const ConstantExpression* cycleEnd;
Timur Iskhakova6d33882017-09-01 13:02:09 -070091
92 // The last ReferenceConstantExpression visited on the cycle.
93 const ReferenceConstantExpression* lastReference;
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070094 };
95
96 // Recursive tree pass that ensures that constant expressions definitions
97 // are acyclic.
98 CheckAcyclicStatus checkAcyclic(std::unordered_set<const ConstantExpression*>* visited,
99 std::unordered_set<const ConstantExpression*>* stack) const;
100
Timur Iskhakov7296af12017-08-09 21:52:48 +0000101 /* Returns true iff the value has already been evaluated. */
102 bool isEvaluated() const;
Steven Morelandf21962d2018-08-09 12:44:40 -0700103 /* Evaluated result in a string form with comment if applicable. */
Yifan Hongfc610cd2016-09-22 13:34:45 -0700104 std::string value() const;
Steven Morelandf21962d2018-08-09 12:44:40 -0700105 /* Evaluated result in a string form with comment if applicable. */
Yifan Hongf24fa852016-09-23 11:03:15 -0700106 std::string cppValue() 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 javaValue() const;
Yifan Hong57886972016-08-17 10:42:15 -0700109 /* Evaluated result in a string form, with given contextual kind. */
Yifan Hongc07b2022016-11-08 12:44:24 -0800110 std::string value(ScalarType::Kind castKind) const;
111 /* Evaluated result in a string form, with given contextual kind. */
Yifan Hongfc610cd2016-09-22 13:34:45 -0700112 std::string cppValue(ScalarType::Kind castKind) const;
Yifan Hong19ca75a2016-08-31 10:20:03 -0700113 /* Evaluated result in a string form, with given contextual kind. */
Yifan Hongfc610cd2016-09-22 13:34:45 -0700114 std::string javaValue(ScalarType::Kind castKind) const;
Steven Morelandf21962d2018-08-09 12:44:40 -0700115
116 /* The expression representing this value for use in comments when the value is not needed */
117 const std::string& expression() const;
118
Yifan Hongf24fa852016-09-23 11:03:15 -0700119 /* Return a ConstantExpression that is 1 plus the original. */
Timur Iskhakov7296af12017-08-09 21:52:48 +0000120 std::unique_ptr<ConstantExpression> addOne(ScalarType::Kind baseKind);
Yifan Honge77ca132016-09-27 10:49:05 -0700121
122 size_t castSizeT() const;
Yifan Hong52165692016-08-12 18:06:40 -0700123
Timur Iskhakov35930c42017-08-28 18:49:54 -0700124 // Marks that package proceeding is completed
125 // Post parse passes must be proceeded during owner package parsin
126 void setPostParseCompleted();
127
Steven Morelandf21962d2018-08-09 12:44:40 -0700128 /*
129 * Helper function for all cpp/javaValue methods.
130 * Returns a plain string (without any prefixes or suffixes, just the
131 * digits) converted from mValue.
132 */
133 std::string rawValue() const;
134 std::string rawValue(ScalarType::Kind castKind) const;
135
Timur Iskhakov7296af12017-08-09 21:52:48 +0000136 private:
137 /* If the result value has been evaluated. */
138 bool mIsEvaluated = false;
Yifan Hong57886972016-08-17 10:42:15 -0700139 /* The formatted expression. */
Neel Mehta3b414a82019-07-02 15:47:48 -0700140 const std::string mExpr;
Yifan Hongf24fa852016-09-23 11:03:15 -0700141 /* The kind of the result value. */
Yifan Hong57886972016-08-17 10:42:15 -0700142 ScalarType::Kind mValueKind;
Yifan Hongf24fa852016-09-23 11:03:15 -0700143 /* The stored result value. */
Yifan Hong57886972016-08-17 10:42:15 -0700144 uint64_t mValue;
Yifan Hong5706a432016-11-02 09:44:18 -0700145 /* true if description() does not offer more information than value(). */
146 bool mTrivialDescription = false;
Yifan Hong52165692016-08-12 18:06:40 -0700147
Timur Iskhakov35930c42017-08-28 18:49:54 -0700148 bool mIsPostParseCompleted = false;
149
Yifan Hongf24fa852016-09-23 11:03:15 -0700150 /*
Steven Morelandf21962d2018-08-09 12:44:40 -0700151 * Helper function, gives suffix comment to add to value/cppValue/javaValue
Yifan Hongf24fa852016-09-23 11:03:15 -0700152 */
Steven Morelandf21962d2018-08-09 12:44:40 -0700153 std::string descriptionSuffix() const;
Yifan Honge77ca132016-09-27 10:49:05 -0700154
155 /*
156 * Return the value casted to the given type.
157 * First cast it according to mValueKind, then cast it to T.
158 * Assumes !containsIdentifiers()
159 */
Timur Iskhakov7296af12017-08-09 21:52:48 +0000160 template <typename T>
161 T cast() const;
162
163 friend struct LiteralConstantExpression;
164 friend struct UnaryConstantExpression;
165 friend struct BinaryConstantExpression;
166 friend struct TernaryConstantExpression;
167 friend struct ReferenceConstantExpression;
Steven Moreland12f0ab12018-11-02 17:27:37 -0700168 friend struct AttributeConstantExpression;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000169};
170
171struct LiteralConstantExpression : public ConstantExpression {
172 LiteralConstantExpression(ScalarType::Kind kind, uint64_t value);
Steven Moreland77943692018-08-09 12:53:42 -0700173 LiteralConstantExpression(ScalarType::Kind kind, uint64_t value, const std::string& expr);
Timur Iskhakov7296af12017-08-09 21:52:48 +0000174 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700175 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Steven Morelandd9d6dcb2017-09-20 15:55:39 -0700176
177 static LiteralConstantExpression* tryParse(const std::string& value);
Timur Iskhakov7296af12017-08-09 21:52:48 +0000178};
179
180struct UnaryConstantExpression : public ConstantExpression {
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700181 UnaryConstantExpression(const std::string& mOp, ConstantExpression* value);
Timur Iskhakov7296af12017-08-09 21:52:48 +0000182 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700183 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000184
185 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700186 ConstantExpression* const mUnary;
187 std::string mOp;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000188};
189
190struct BinaryConstantExpression : public ConstantExpression {
191 BinaryConstantExpression(ConstantExpression* lval, const std::string& op,
192 ConstantExpression* rval);
193 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700194 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000195
196 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700197 ConstantExpression* const mLval;
198 ConstantExpression* const mRval;
199 const std::string mOp;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000200};
201
202struct TernaryConstantExpression : public ConstantExpression {
203 TernaryConstantExpression(ConstantExpression* cond, ConstantExpression* trueVal,
204 ConstantExpression* falseVal);
205 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700206 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000207
208 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700209 ConstantExpression* const mCond;
210 ConstantExpression* const mTrueVal;
211 ConstantExpression* const mFalseVal;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000212};
213
214struct ReferenceConstantExpression : public ConstantExpression {
215 ReferenceConstantExpression(const Reference<LocalIdentifier>& value, const std::string& expr);
Timur Iskhakova6d33882017-09-01 13:02:09 -0700216
217 bool isReferenceConstantExpression() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000218 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700219 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov77dd65c2017-08-31 22:46:56 -0700220 std::vector<const Reference<LocalIdentifier>*> getReferences() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000221
222 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700223 Reference<LocalIdentifier> mReference;
Yifan Hong52165692016-08-12 18:06:40 -0700224};
225
Steven Moreland12f0ab12018-11-02 17:27:37 -0700226// This constant expression is a compile-time calculatable expression based on another type
227struct AttributeConstantExpression : public ConstantExpression {
228 AttributeConstantExpression(const Reference<Type>& value, const std::string& fqname,
229 const std::string& tag);
230
231 status_t validate() const override;
232 void evaluate() override;
233
234 std::vector<const ConstantExpression*> getConstantExpressions() const override;
235 std::vector<const Reference<Type>*> getTypeReferences() const override;
236
237 private:
238 Reference<Type> mReference;
239 const std::string mTag;
240};
241
Yifan Hong52165692016-08-12 18:06:40 -0700242} // namespace android
243
244#endif // CONSTANT_EXPRESSION_H_