|  | /* | 
|  | * 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); | 
|  |  | 
|  | ConstantExpression(const std::string& expr); | 
|  | virtual ~ConstantExpression() {} | 
|  |  | 
|  | virtual bool isReferenceConstantExpression() const; | 
|  |  | 
|  | void surroundWithParens(); | 
|  |  | 
|  | // 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; | 
|  |  | 
|  | // If this object is in an invalid state. | 
|  | virtual status_t validate() 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; | 
|  |  | 
|  | std::vector<Reference<Type>*> getTypeReferences(); | 
|  | virtual std::vector<const Reference<Type>*> getTypeReferences() 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 with comment if applicable. */ | 
|  | std::string value() const; | 
|  | /* Evaluated result in a string form with comment if applicable. */ | 
|  | std::string cppValue() const; | 
|  | /* Evaluated result in a string form with comment if applicable. */ | 
|  | 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; | 
|  |  | 
|  | /* The expression representing this value for use in comments when the value is not needed */ | 
|  | const std::string& expression() 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(); | 
|  |  | 
|  | /* | 
|  | * 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() const; | 
|  | std::string rawValue(ScalarType::Kind castKind) const; | 
|  |  | 
|  | 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, gives suffix comment to add to value/cppValue/javaValue | 
|  | */ | 
|  | std::string descriptionSuffix() 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; | 
|  | friend struct AttributeConstantExpression; | 
|  | }; | 
|  |  | 
|  | struct LiteralConstantExpression : public ConstantExpression { | 
|  | LiteralConstantExpression(ScalarType::Kind kind, uint64_t value); | 
|  | LiteralConstantExpression(ScalarType::Kind kind, uint64_t value, const std::string& expr); | 
|  | void evaluate() override; | 
|  | std::vector<const ConstantExpression*> getConstantExpressions() const override; | 
|  |  | 
|  | static LiteralConstantExpression* tryParse(const std::string& value); | 
|  | }; | 
|  |  | 
|  | 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; | 
|  | }; | 
|  |  | 
|  | // This constant expression is a compile-time calculatable expression based on another type | 
|  | struct AttributeConstantExpression : public ConstantExpression { | 
|  | AttributeConstantExpression(const Reference<Type>& value, const std::string& fqname, | 
|  | const std::string& tag); | 
|  |  | 
|  | status_t validate() const override; | 
|  | void evaluate() override; | 
|  |  | 
|  | std::vector<const ConstantExpression*> getConstantExpressions() const override; | 
|  | std::vector<const Reference<Type>*> getTypeReferences() const override; | 
|  |  | 
|  | private: | 
|  | Reference<Type> mReference; | 
|  | const std::string mTag; | 
|  | }; | 
|  |  | 
|  | }  // namespace android | 
|  |  | 
|  | #endif  // CONSTANT_EXPRESSION_H_ |