using references in constant expressions
References to enumerators or other constants can be used in constant
expressions. This enables setting defaults to enum type variables.
References are resolved at compilation time.
Note that recursive references are not supported yet.
Bug: 142893595
Test: aidl_unittests
Test: aidl_integration_test
Change-Id: Ic7d7e74c1306462fa9148d474c764ebb9a5fae45
diff --git a/aidl_language.h b/aidl_language.h
index 0fccfaa..6638e0e 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -353,7 +353,7 @@
bool is_array_;
string comments_;
vector<string> split_name_;
- const AidlDefinedType* defined_type_; // set when Resolve() for defined types
+ const AidlDefinedType* defined_type_ = nullptr; // set when Resolve() for defined types
mutable shared_ptr<AidlTypeSpecifier> array_base_;
};
@@ -480,6 +480,7 @@
class AidlUnaryConstExpression;
class AidlBinaryConstExpression;
+class AidlConstantReference;
class AidlConstantValue : public AidlNode {
public:
@@ -493,12 +494,21 @@
ARRAY,
CHARACTER,
STRING,
+ REF,
FLOATING,
UNARY,
BINARY,
ERROR,
};
+ struct Visitor {
+ virtual ~Visitor() {}
+ virtual void Visit(AidlConstantValue&) = 0;
+ virtual void Visit(AidlConstantReference&) = 0;
+ virtual void Visit(AidlUnaryConstExpression&) = 0;
+ virtual void Visit(AidlBinaryConstExpression&) = 0;
+ };
+
/*
* Return the value casted to the given type.
*/
@@ -538,6 +548,7 @@
// Raw value of type (currently valid in C++ and Java). Empty string on error.
string ValueString(const AidlTypeSpecifier& type, const ConstantValueDecorator& decorator) const;
+ virtual void Accept(Visitor& visitor) { visitor.Visit(*this); }
private:
AidlConstantValue(const AidlLocation& location, Type parsed_type, int64_t parsed_value,
@@ -564,6 +575,32 @@
friend AidlUnaryConstExpression;
friend AidlBinaryConstExpression;
+ friend AidlConstantReference;
+};
+
+// Represents "<type>.<field>" which resolves to a constant which is one of
+// - constant declartion
+// - enumerator
+// When a <type> is missing, <field> is of the enclosing type.
+class AidlConstantReference : public AidlConstantValue {
+ public:
+ AidlConstantReference(const AidlLocation& location, const std::string& value,
+ const std::string& comments);
+
+ const std::unique_ptr<AidlTypeSpecifier>& GetRefType() const { return ref_type_; }
+ void SetRefType(std::unique_ptr<AidlTypeSpecifier> type) { ref_type_ = std::move(type); }
+ const std::string& GetFieldName() const { return field_name_; }
+ const std::string& GetComments() const { return comments_; }
+
+ bool CheckValid() const override;
+ void Accept(Visitor& visitor) override { visitor.Visit(*this); }
+
+ private:
+ bool evaluate(const AidlTypeSpecifier& type) const override;
+
+ std::unique_ptr<AidlTypeSpecifier> ref_type_;
+ std::string field_name_;
+ const std::string comments_;
};
class AidlUnaryConstExpression : public AidlConstantValue {
@@ -573,6 +610,11 @@
static bool IsCompatibleType(Type type, const string& op);
bool CheckValid() const override;
+ void Accept(Visitor& visitor) override {
+ visitor.Visit(*this);
+ unary_->Accept(visitor);
+ }
+
private:
bool evaluate(const AidlTypeSpecifier& type) const override;
@@ -592,6 +634,11 @@
static Type UsualArithmeticConversion(Type left, Type right);
// Returns the promoted integral type where INT32 is the smallest type
static Type IntegralPromotion(Type in);
+ void Accept(Visitor& visitor) override {
+ visitor.Visit(*this);
+ left_val_->Accept(visitor);
+ right_val_->Accept(visitor);
+ }
private:
bool evaluate(const AidlTypeSpecifier& type) const override;