| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef CONSTANT_EXPRESSION_H_ |
| |
| #define CONSTANT_EXPRESSION_H_ |
| |
| #include <android-base/macros.h> |
| #include <functional> |
| #include <memory> |
| #include <string> |
| #include <unordered_set> |
| #include <vector> |
| |
| #include "Reference.h" |
| #include "ScalarType.h" |
| |
| namespace android { |
| |
| struct LocalIdentifier; |
| |
| struct LiteralConstantExpression; |
| struct UnaryConstantExpression; |
| struct BinaryConstantExpression; |
| struct TernaryConstantExpression; |
| struct ReferenceConstantExpression; |
| |
| /** |
| * A constant expression is represented by a tree. |
| */ |
| struct ConstantExpression { |
| static std::unique_ptr<ConstantExpression> Zero(ScalarType::Kind kind); |
| static std::unique_ptr<ConstantExpression> One(ScalarType::Kind kind); |
| static std::unique_ptr<ConstantExpression> ValueOf(ScalarType::Kind kind, uint64_t value); |
| |
| virtual ~ConstantExpression() {} |
| |
| virtual bool isReferenceConstantExpression() const; |
| |
| // Proceeds recursive pass |
| // Makes sure to visit each node only once |
| // Used to provide lookup and lazy evaluation |
| status_t recursivePass(const std::function<status_t(ConstantExpression*)>& func, |
| std::unordered_set<const ConstantExpression*>* visited, |
| bool processBeforeDependencies); |
| status_t recursivePass(const std::function<status_t(const ConstantExpression*)>& func, |
| std::unordered_set<const ConstantExpression*>* visited, |
| bool processBeforeDependencies) const; |
| |
| // Evaluates current constant expression |
| // Doesn't call recursive evaluation, so must be called after dependencies |
| virtual void evaluate() = 0; |
| |
| std::vector<ConstantExpression*> getConstantExpressions(); |
| virtual std::vector<const ConstantExpression*> getConstantExpressions() const = 0; |
| |
| std::vector<Reference<LocalIdentifier>*> getReferences(); |
| virtual std::vector<const Reference<LocalIdentifier>*> getReferences() const; |
| |
| // Recursive tree pass checkAcyclic return type. |
| // Stores cycle end for nice error messages. |
| struct CheckAcyclicStatus { |
| CheckAcyclicStatus(status_t status, const ConstantExpression* cycleEnd = nullptr, |
| const ReferenceConstantExpression* lastReferenceExpression = nullptr); |
| |
| status_t status; |
| |
| // If a cycle is found, stores the end of cycle. |
| // While going back in recursion, this is used to stop printing the cycle. |
| const ConstantExpression* cycleEnd; |
| |
| // The last ReferenceConstantExpression visited on the cycle. |
| const ReferenceConstantExpression* lastReference; |
| }; |
| |
| // Recursive tree pass that ensures that constant expressions definitions |
| // are acyclic. |
| CheckAcyclicStatus checkAcyclic(std::unordered_set<const ConstantExpression*>* visited, |
| std::unordered_set<const ConstantExpression*>* stack) const; |
| |
| /* Returns true iff the value has already been evaluated. */ |
| bool isEvaluated() const; |
| /* Evaluated result in a string form. */ |
| std::string value() const; |
| /* Evaluated result in a string form. */ |
| std::string cppValue() const; |
| /* Evaluated result in a string form. */ |
| std::string javaValue() const; |
| /* Evaluated result in a string form, with given contextual kind. */ |
| std::string value(ScalarType::Kind castKind) const; |
| /* Evaluated result in a string form, with given contextual kind. */ |
| std::string cppValue(ScalarType::Kind castKind) const; |
| /* Evaluated result in a string form, with given contextual kind. */ |
| std::string javaValue(ScalarType::Kind castKind) const; |
| /* Formatted expression with type. */ |
| const std::string& description() const; |
| /* See mTrivialDescription */ |
| bool descriptionIsTrivial() const; |
| /* Return a ConstantExpression that is 1 plus the original. */ |
| std::unique_ptr<ConstantExpression> addOne(ScalarType::Kind baseKind); |
| |
| size_t castSizeT() const; |
| |
| // Marks that package proceeding is completed |
| // Post parse passes must be proceeded during owner package parsin |
| void setPostParseCompleted(); |
| |
| private: |
| /* If the result value has been evaluated. */ |
| bool mIsEvaluated = false; |
| /* The formatted expression. */ |
| std::string mExpr; |
| /* The kind of the result value. */ |
| ScalarType::Kind mValueKind; |
| /* The stored result value. */ |
| uint64_t mValue; |
| /* true if description() does not offer more information than value(). */ |
| bool mTrivialDescription = false; |
| |
| bool mIsPostParseCompleted = false; |
| |
| /* |
| * Helper function for all cpp/javaValue methods. |
| * Returns a plain string (without any prefixes or suffixes, just the |
| * digits) converted from mValue. |
| */ |
| std::string rawValue(ScalarType::Kind castKind) const; |
| |
| /* |
| * Return the value casted to the given type. |
| * First cast it according to mValueKind, then cast it to T. |
| * Assumes !containsIdentifiers() |
| */ |
| template <typename T> |
| T cast() const; |
| |
| friend struct LiteralConstantExpression; |
| friend struct UnaryConstantExpression; |
| friend struct BinaryConstantExpression; |
| friend struct TernaryConstantExpression; |
| friend struct ReferenceConstantExpression; |
| }; |
| |
| struct LiteralConstantExpression : public ConstantExpression { |
| LiteralConstantExpression(ScalarType::Kind kind, uint64_t value); |
| void evaluate() override; |
| std::vector<const ConstantExpression*> getConstantExpressions() const override; |
| |
| static LiteralConstantExpression* tryParse(const std::string& value); |
| |
| private: |
| LiteralConstantExpression(ScalarType::Kind kind, uint64_t value, const std::string& expr); |
| }; |
| |
| struct UnaryConstantExpression : public ConstantExpression { |
| UnaryConstantExpression(const std::string& mOp, ConstantExpression* value); |
| void evaluate() override; |
| std::vector<const ConstantExpression*> getConstantExpressions() const override; |
| |
| private: |
| ConstantExpression* const mUnary; |
| std::string mOp; |
| }; |
| |
| struct BinaryConstantExpression : public ConstantExpression { |
| BinaryConstantExpression(ConstantExpression* lval, const std::string& op, |
| ConstantExpression* rval); |
| void evaluate() override; |
| std::vector<const ConstantExpression*> getConstantExpressions() const override; |
| |
| private: |
| ConstantExpression* const mLval; |
| ConstantExpression* const mRval; |
| const std::string mOp; |
| }; |
| |
| struct TernaryConstantExpression : public ConstantExpression { |
| TernaryConstantExpression(ConstantExpression* cond, ConstantExpression* trueVal, |
| ConstantExpression* falseVal); |
| void evaluate() override; |
| std::vector<const ConstantExpression*> getConstantExpressions() const override; |
| |
| private: |
| ConstantExpression* const mCond; |
| ConstantExpression* const mTrueVal; |
| ConstantExpression* const mFalseVal; |
| }; |
| |
| struct ReferenceConstantExpression : public ConstantExpression { |
| ReferenceConstantExpression(const Reference<LocalIdentifier>& value, const std::string& expr); |
| |
| bool isReferenceConstantExpression() const override; |
| void evaluate() override; |
| std::vector<const ConstantExpression*> getConstantExpressions() const override; |
| std::vector<const Reference<LocalIdentifier>*> getReferences() const override; |
| |
| private: |
| Reference<LocalIdentifier> mReference; |
| }; |
| |
| } // namespace android |
| |
| #endif // CONSTANT_EXPRESSION_H_ |