grammar for fixed-size array
The grammar is extended to accept `T[N]` fixed-size array types.
Multiple-dimensional fixed-size arrays are supported while, for
simplicity, T[][N](dynamic array of fixed-size arrays) and
T[N][](fixed-size array of dynamic arrays) are not supported yet.
AIDL AST is changed as well, but fixed-size arrays are treated like a
dynamic array when compiling. Each backend support will follow.
Bug: 207087196
Test: aidl_unittests
Change-Id: Ife72ac04a9af516477df6bf8926a40a29de40e91
diff --git a/aidl_language.h b/aidl_language.h
index 019330c..266f473 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -381,12 +381,23 @@
vector<std::unique_ptr<AidlAnnotation>> annotations_;
};
+// Represents `[]`
+struct DynamicArray {};
+// Represents `[N][M]..`
+struct FixedSizeArray {
+ FixedSizeArray(std::unique_ptr<AidlConstantValue> dim) { dimensions.push_back(std::move(dim)); }
+ std::vector<std::unique_ptr<AidlConstantValue>> dimensions;
+};
+// Represents `[]` or `[N]` part of type specifier
+using ArrayType = std::variant<DynamicArray, FixedSizeArray>;
+
// AidlTypeSpecifier represents a reference to either a built-in type,
// a defined type, or a variant (e.g., array of generic) of a type.
class AidlTypeSpecifier final : public AidlAnnotatable,
public AidlParameterizable<unique_ptr<AidlTypeSpecifier>> {
public:
- AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name, bool is_array,
+ AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
+ std::optional<ArrayType> array,
vector<unique_ptr<AidlTypeSpecifier>>* type_params, const Comments& comments);
virtual ~AidlTypeSpecifier() = default;
@@ -424,14 +435,23 @@
bool IsResolved() const { return fully_qualified_name_ != ""; }
- bool IsArray() const { return is_array_; }
+ bool IsArray() const { return array_.has_value(); }
- __attribute__((warn_unused_result)) bool SetArray() {
- if (is_array_) return false;
- is_array_ = true;
- return true;
+ bool IsFixedSizeArray() const {
+ return array_.has_value() && std::get_if<FixedSizeArray>(&*array_) != nullptr;
}
+ const ArrayType& GetArray() const {
+ AIDL_FATAL_IF(!array_.has_value(), this) << "GetArray() for non-array type";
+ return array_.value();
+ }
+
+ // Accept transitions from
+ // T to T[]
+ // or T to T[N]
+ // or T[N] to T[N][M]
+ __attribute__((warn_unused_result)) bool MakeArray(ArrayType array_type);
+
// Resolve the base type name to a fully-qualified name. Return false if the
// resolution fails.
bool Resolve(const AidlTypenames& typenames, const AidlScope* scope);
@@ -441,20 +461,13 @@
const AidlNode& AsAidlNode() const override { return *this; }
const AidlDefinedType* GetDefinedType() const;
- void TraverseChildren(std::function<void(const AidlNode&)> traverse) const override {
- AidlAnnotatable::TraverseChildren(traverse);
- if (IsGeneric()) {
- for (const auto& tp : GetTypeParameters()) {
- traverse(*tp);
- }
- }
- }
+ void TraverseChildren(std::function<void(const AidlNode&)> traverse) const override;
void DispatchVisit(AidlVisitor& v) const override { v.Visit(*this); }
private:
const string unresolved_name_;
string fully_qualified_name_;
- mutable bool is_array_;
+ mutable std::optional<ArrayType> array_;
vector<string> split_name_;
const AidlDefinedType* defined_type_ = nullptr; // set when Resolve() for defined types
};