ConstantExpression.h revision 35930c43ef3ccc79ae5ad07ca8dab5e94902d30e
1/*
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
17#ifndef CONSTANT_EXPRESSION_H_
18
19#define CONSTANT_EXPRESSION_H_
20
21#include <android-base/macros.h>
22#include <functional>
23#include <memory>
24#include <string>
25#include <unordered_set>
26#include <vector>
27
28#include "Reference.h"
29#include "ScalarType.h"
30
31namespace android {
32
33struct LocalIdentifier;
34
35struct LiteralConstantExpression;
36struct UnaryConstantExpression;
37struct BinaryConstantExpression;
38struct TernaryConstantExpression;
39struct ReferenceConstantExpression;
40
41/**
42 * A constant expression is represented by a tree.
43 */
44struct ConstantExpression {
45    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);
48
49    virtual ~ConstantExpression() {}
50
51    // Proceeds recursive pass
52    // Makes sure to visit each node only once
53    // Used to provide lookup and lazy evaluation
54    status_t recursivePass(const std::function<status_t(ConstantExpression*)>& func,
55                           std::unordered_set<const ConstantExpression*>* visited);
56
57    // Evaluates current constant expression
58    // Doesn't call recursive evaluation, so must be called after dependencies
59    virtual void evaluate() = 0;
60
61    virtual std::vector<ConstantExpression*> getConstantExpressions() const = 0;
62
63    /* Returns true iff the value has already been evaluated. */
64    bool isEvaluated() const;
65    /* Evaluated result in a string form. */
66    std::string value() const;
67    /* Evaluated result in a string form. */
68    std::string cppValue() const;
69    /* Evaluated result in a string form. */
70    std::string javaValue() const;
71    /* Evaluated result in a string form, with given contextual kind. */
72    std::string value(ScalarType::Kind castKind) const;
73    /* Evaluated result in a string form, with given contextual kind. */
74    std::string cppValue(ScalarType::Kind castKind) const;
75    /* Evaluated result in a string form, with given contextual kind. */
76    std::string javaValue(ScalarType::Kind castKind) const;
77    /* Formatted expression with type. */
78    const std::string& description() const;
79    /* See mTrivialDescription */
80    bool descriptionIsTrivial() const;
81    /* Return a ConstantExpression that is 1 plus the original. */
82    std::unique_ptr<ConstantExpression> addOne(ScalarType::Kind baseKind);
83
84    size_t castSizeT() const;
85
86    // Marks that package proceeding is completed
87    // Post parse passes must be proceeded during owner package parsin
88    void setPostParseCompleted();
89
90   private:
91    /* If the result value has been evaluated. */
92    bool mIsEvaluated = false;
93    /* The formatted expression. */
94    std::string mExpr;
95    /* The kind of the result value. */
96    ScalarType::Kind mValueKind;
97    /* The stored result value. */
98    uint64_t mValue;
99    /* true if description() does not offer more information than value(). */
100    bool mTrivialDescription = false;
101
102    bool mIsPostParseCompleted = false;
103
104    /*
105     * Helper function for all cpp/javaValue methods.
106     * Returns a plain string (without any prefixes or suffixes, just the
107     * digits) converted from mValue.
108     */
109    std::string rawValue(ScalarType::Kind castKind) const;
110
111    /*
112     * Return the value casted to the given type.
113     * First cast it according to mValueKind, then cast it to T.
114     * Assumes !containsIdentifiers()
115     */
116    template <typename T>
117    T cast() const;
118
119    friend struct LiteralConstantExpression;
120    friend struct UnaryConstantExpression;
121    friend struct BinaryConstantExpression;
122    friend struct TernaryConstantExpression;
123    friend struct ReferenceConstantExpression;
124};
125
126struct LiteralConstantExpression : public ConstantExpression {
127    LiteralConstantExpression(ScalarType::Kind kind, uint64_t value);
128    LiteralConstantExpression(const std::string& value);
129    void evaluate() override;
130    std::vector<ConstantExpression*> getConstantExpressions() const override;
131};
132
133struct UnaryConstantExpression : public ConstantExpression {
134    UnaryConstantExpression(const std::string& mOp, ConstantExpression* value);
135    void evaluate() override;
136    std::vector<ConstantExpression*> getConstantExpressions() const override;
137
138   private:
139    ConstantExpression* const mUnary;
140    std::string mOp;
141};
142
143struct BinaryConstantExpression : public ConstantExpression {
144    BinaryConstantExpression(ConstantExpression* lval, const std::string& op,
145                             ConstantExpression* rval);
146    void evaluate() override;
147    std::vector<ConstantExpression*> getConstantExpressions() const override;
148
149   private:
150    ConstantExpression* const mLval;
151    ConstantExpression* const mRval;
152    const std::string mOp;
153};
154
155struct TernaryConstantExpression : public ConstantExpression {
156    TernaryConstantExpression(ConstantExpression* cond, ConstantExpression* trueVal,
157                              ConstantExpression* falseVal);
158    void evaluate() override;
159    std::vector<ConstantExpression*> getConstantExpressions() const override;
160
161   private:
162    ConstantExpression* const mCond;
163    ConstantExpression* const mTrueVal;
164    ConstantExpression* const mFalseVal;
165};
166
167struct ReferenceConstantExpression : public ConstantExpression {
168    ReferenceConstantExpression(const Reference<LocalIdentifier>& value, const std::string& expr);
169    void evaluate() override;
170    std::vector<ConstantExpression*> getConstantExpressions() const override;
171
172   private:
173    Reference<LocalIdentifier> mReference;
174};
175
176}  // namespace android
177
178#endif  // CONSTANT_EXPRESSION_H_
179