You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
9.0 KiB
247 lines
9.0 KiB
/*
|
|
* 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_
|