blob: b77071669eef1462c8bd81b13cadfc07f3fceebb [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
Timur Iskhakov7296af12017-08-09 21:52:48 +000049 virtual ~ConstantExpression() {}
Yifan Hong57886972016-08-17 10:42:15 -070050
Timur Iskhakova6d33882017-09-01 13:02:09 -070051 virtual bool isReferenceConstantExpression() const;
52
Timur Iskhakov891a8662017-08-25 21:53:48 -070053 // 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,
Timur Iskhakov82c048e2017-09-09 01:20:53 -070057 std::unordered_set<const ConstantExpression*>* visited,
58 bool processBeforeDependencies);
Timur Iskhakovb58f4182017-08-29 15:19:24 -070059 status_t recursivePass(const std::function<status_t(const ConstantExpression*)>& func,
Timur Iskhakov82c048e2017-09-09 01:20:53 -070060 std::unordered_set<const ConstantExpression*>* visited,
61 bool processBeforeDependencies) const;
Timur Iskhakov891a8662017-08-25 21:53:48 -070062
Steven Moreland12f0ab12018-11-02 17:27:37 -070063 // If this object is in an invalid state.
64 virtual status_t validate() const;
65
Timur Iskhakov891a8662017-08-25 21:53:48 -070066 // Evaluates current constant expression
67 // Doesn't call recursive evaluation, so must be called after dependencies
Timur Iskhakov7296af12017-08-09 21:52:48 +000068 virtual void evaluate() = 0;
Colin Crossa549b712017-08-09 18:33:22 +000069
Timur Iskhakovb58f4182017-08-29 15:19:24 -070070 std::vector<ConstantExpression*> getConstantExpressions();
71 virtual std::vector<const ConstantExpression*> getConstantExpressions() const = 0;
Timur Iskhakov891a8662017-08-25 21:53:48 -070072
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070073 std::vector<Reference<LocalIdentifier>*> getReferences();
74 virtual std::vector<const Reference<LocalIdentifier>*> getReferences() const;
75
Steven Moreland12f0ab12018-11-02 17:27:37 -070076 std::vector<Reference<Type>*> getTypeReferences();
77 virtual std::vector<const Reference<Type>*> getTypeReferences() const;
78
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070079 // Recursive tree pass checkAcyclic return type.
80 // Stores cycle end for nice error messages.
81 struct CheckAcyclicStatus {
Timur Iskhakova6d33882017-09-01 13:02:09 -070082 CheckAcyclicStatus(status_t status, const ConstantExpression* cycleEnd = nullptr,
83 const ReferenceConstantExpression* lastReferenceExpression = nullptr);
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070084
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;
Timur Iskhakova6d33882017-09-01 13:02:09 -070090
91 // The last ReferenceConstantExpression visited on the cycle.
92 const ReferenceConstantExpression* lastReference;
Timur Iskhakov77dd65c2017-08-31 22:46:56 -070093 };
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
Timur Iskhakov7296af12017-08-09 21:52:48 +0000100 /* Returns true iff the value has already been evaluated. */
101 bool isEvaluated() const;
Steven Morelandf21962d2018-08-09 12:44:40 -0700102 /* Evaluated result in a string form with comment if applicable. */
Yifan Hongfc610cd2016-09-22 13:34:45 -0700103 std::string value() const;
Steven Morelandf21962d2018-08-09 12:44:40 -0700104 /* Evaluated result in a string form with comment if applicable. */
Yifan Hongf24fa852016-09-23 11:03:15 -0700105 std::string cppValue() const;
Steven Morelandf21962d2018-08-09 12:44:40 -0700106 /* Evaluated result in a string form with comment if applicable. */
Yifan Hongf24fa852016-09-23 11:03:15 -0700107 std::string javaValue() const;
Yifan Hong57886972016-08-17 10:42:15 -0700108 /* Evaluated result in a string form, with given contextual kind. */
Yifan Hongc07b2022016-11-08 12:44:24 -0800109 std::string value(ScalarType::Kind castKind) const;
110 /* Evaluated result in a string form, with given contextual kind. */
Yifan Hongfc610cd2016-09-22 13:34:45 -0700111 std::string cppValue(ScalarType::Kind castKind) const;
Yifan Hong19ca75a2016-08-31 10:20:03 -0700112 /* Evaluated result in a string form, with given contextual kind. */
Yifan Hongfc610cd2016-09-22 13:34:45 -0700113 std::string javaValue(ScalarType::Kind castKind) const;
Steven Morelandf21962d2018-08-09 12:44:40 -0700114
115 /* The expression representing this value for use in comments when the value is not needed */
116 const std::string& expression() const;
117
Yifan Hongf24fa852016-09-23 11:03:15 -0700118 /* Return a ConstantExpression that is 1 plus the original. */
Timur Iskhakov7296af12017-08-09 21:52:48 +0000119 std::unique_ptr<ConstantExpression> addOne(ScalarType::Kind baseKind);
Yifan Honge77ca132016-09-27 10:49:05 -0700120
121 size_t castSizeT() const;
Yifan Hong52165692016-08-12 18:06:40 -0700122
Timur Iskhakov35930c42017-08-28 18:49:54 -0700123 // Marks that package proceeding is completed
124 // Post parse passes must be proceeded during owner package parsin
125 void setPostParseCompleted();
126
Steven Morelandf21962d2018-08-09 12:44:40 -0700127 /*
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
Timur Iskhakov7296af12017-08-09 21:52:48 +0000135 private:
136 /* If the result value has been evaluated. */
137 bool mIsEvaluated = false;
Yifan Hong57886972016-08-17 10:42:15 -0700138 /* The formatted expression. */
Yifan Hongf24fa852016-09-23 11:03:15 -0700139 std::string mExpr;
Yifan Hongf24fa852016-09-23 11:03:15 -0700140 /* The kind of the result value. */
Yifan Hong57886972016-08-17 10:42:15 -0700141 ScalarType::Kind mValueKind;
Yifan Hongf24fa852016-09-23 11:03:15 -0700142 /* The stored result value. */
Yifan Hong57886972016-08-17 10:42:15 -0700143 uint64_t mValue;
Yifan Hong5706a432016-11-02 09:44:18 -0700144 /* true if description() does not offer more information than value(). */
145 bool mTrivialDescription = false;
Yifan Hong52165692016-08-12 18:06:40 -0700146
Timur Iskhakov35930c42017-08-28 18:49:54 -0700147 bool mIsPostParseCompleted = false;
148
Yifan Hongf24fa852016-09-23 11:03:15 -0700149 /*
Steven Morelandf21962d2018-08-09 12:44:40 -0700150 * Helper function, gives suffix comment to add to value/cppValue/javaValue
Yifan Hongf24fa852016-09-23 11:03:15 -0700151 */
Steven Morelandf21962d2018-08-09 12:44:40 -0700152 std::string descriptionSuffix() const;
Yifan Honge77ca132016-09-27 10:49:05 -0700153
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 */
Timur Iskhakov7296af12017-08-09 21:52:48 +0000159 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;
Steven Moreland12f0ab12018-11-02 17:27:37 -0700167 friend struct AttributeConstantExpression;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000168};
169
170struct LiteralConstantExpression : public ConstantExpression {
171 LiteralConstantExpression(ScalarType::Kind kind, uint64_t value);
Steven Moreland77943692018-08-09 12:53:42 -0700172 LiteralConstantExpression(ScalarType::Kind kind, uint64_t value, const std::string& expr);
Timur Iskhakov7296af12017-08-09 21:52:48 +0000173 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700174 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Steven Morelandd9d6dcb2017-09-20 15:55:39 -0700175
176 static LiteralConstantExpression* tryParse(const std::string& value);
Timur Iskhakov7296af12017-08-09 21:52:48 +0000177};
178
179struct UnaryConstantExpression : public ConstantExpression {
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700180 UnaryConstantExpression(const std::string& mOp, ConstantExpression* value);
Timur Iskhakov7296af12017-08-09 21:52:48 +0000181 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700182 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000183
184 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700185 ConstantExpression* const mUnary;
186 std::string mOp;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000187};
188
189struct BinaryConstantExpression : public ConstantExpression {
190 BinaryConstantExpression(ConstantExpression* lval, const std::string& op,
191 ConstantExpression* rval);
192 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700193 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000194
195 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700196 ConstantExpression* const mLval;
197 ConstantExpression* const mRval;
198 const std::string mOp;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000199};
200
201struct TernaryConstantExpression : public ConstantExpression {
202 TernaryConstantExpression(ConstantExpression* cond, ConstantExpression* trueVal,
203 ConstantExpression* falseVal);
204 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700205 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000206
207 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700208 ConstantExpression* const mCond;
209 ConstantExpression* const mTrueVal;
210 ConstantExpression* const mFalseVal;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000211};
212
213struct ReferenceConstantExpression : public ConstantExpression {
214 ReferenceConstantExpression(const Reference<LocalIdentifier>& value, const std::string& expr);
Timur Iskhakova6d33882017-09-01 13:02:09 -0700215
216 bool isReferenceConstantExpression() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000217 void evaluate() override;
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700218 std::vector<const ConstantExpression*> getConstantExpressions() const override;
Timur Iskhakov77dd65c2017-08-31 22:46:56 -0700219 std::vector<const Reference<LocalIdentifier>*> getReferences() const override;
Timur Iskhakov7296af12017-08-09 21:52:48 +0000220
221 private:
Timur Iskhakovd27580c2017-08-09 20:14:52 -0700222 Reference<LocalIdentifier> mReference;
Yifan Hong52165692016-08-12 18:06:40 -0700223};
224
Steven Moreland12f0ab12018-11-02 17:27:37 -0700225// This constant expression is a compile-time calculatable expression based on another type
226struct 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
Yifan Hong52165692016-08-12 18:06:40 -0700241} // namespace android
242
243#endif // CONSTANT_EXPRESSION_H_