Support for inline arrays in structs (#206)

* Generates `Array` instead of workaround.
* Removes `array-workaround` config.
* Removes depreacted `llvm-lib` config.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 82b5807..5139d6f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 3.0.0-beta.0
+- Added support for inline arrays in `Struct`s.
+- Remove config key `array-workaround`.
+- Remove deprecated key `llvm-lib` from config, Use `llvm-path` instead.
+
 # 2.5.0-beta.1
 - Added support for `Packed` structs. Packed annotations are generated
 automatically but can be overriden using `structs -> pack` config.
diff --git a/README.md b/README.md
index d8cac98..a008d37 100644
--- a/README.md
+++ b/README.md
@@ -253,18 +253,6 @@
   </td>
   </tr>
   <tr>
-    <td>array-workaround</td>
-    <td>Should generate workaround for fixed arrays in Structs. See <a href="#array-workaround">Array Workaround</a><br>
-      <b>Default: false</b>
-    </td>
-    <td>
-
-```yaml
-array-workaround: true
-```
-  </td>
-  </tr>
-  <tr>
     <td>comments</td>
     <td>Extract documentation comments for declarations.<br>
     The style and length of the comments recognized can be specified with the following options- <br>
@@ -402,80 +390,6 @@
 </tbody>
 </table>
 
-## Array-Workaround
-Fixed size array's in structs aren't currently supported by Dart. However we provide
-a workaround, using which array items can now be accessed using `[]` operator.
-
-Here's a C structure from libclang-
-```c
-typedef struct {
-  unsigned long long data[3];
-} CXFileUniqueID;
-```
-The generated code is -
-```dart
-class CXFileUniqueID extends ffi.Struct {
-  @ffi.Uint64()
-  external int _unique_data_item_0;
-  @ffi.Uint64()
-  external int _unique_data_item_1;
-  @ffi.Uint64()
-  external int _unique_data_item_2;
-
-  /// Helper for array `data`.
-  ArrayHelper_CXFileUniqueID_data_level0 get data =>
-      ArrayHelper_CXFileUniqueID_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXFileUniqueID`.
-class ArrayHelper_CXFileUniqueID_data_level0 {
-  final CXFileUniqueID _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXFileUniqueID_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..${length} exclusive.');
-    }
-  }
-
-  int operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_data_item_0;
-      case 1:
-        return _struct._unique_data_item_1;
-      case 2:
-        return _struct._unique_data_item_2;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, int value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_data_item_1 = value;
-        break;
-      case 2:
-        _struct._unique_data_item_2 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-}
-```
-
 ## Limitations
 1. Multi OS support for types such as long. [Issue #7](https://github.com/dart-lang/ffigen/issues/7)
 
diff --git a/example/libclang-example/generated_bindings.dart b/example/libclang-example/generated_bindings.dart
index cd366f3..71fa196 100644
--- a/example/libclang-example/generated_bindings.dart
+++ b/example/libclang-example/generated_bindings.dart
@@ -7928,64 +7928,8 @@
 /// Uniquely identifies a CXFile, that refers to the same underlying file,
 /// across an indexing session.
 class CXFileUniqueID extends ffi.Struct {
-  @ffi.Uint64()
-  external int _unique_data_item_0;
-  @ffi.Uint64()
-  external int _unique_data_item_1;
-  @ffi.Uint64()
-  external int _unique_data_item_2;
-
-  /// Helper for array `data`.
-  ArrayHelper_CXFileUniqueID_data_level0 get data =>
-      ArrayHelper_CXFileUniqueID_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXFileUniqueID`.
-class ArrayHelper_CXFileUniqueID_data_level0 {
-  final CXFileUniqueID _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXFileUniqueID_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  int operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_data_item_0;
-      case 1:
-        return _struct._unique_data_item_1;
-      case 2:
-        return _struct._unique_data_item_2;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, int value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_data_item_1 = value;
-        break;
-      case 2:
-        _struct._unique_data_item_2 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
+  @ffi.Array.multi([3])
+  external ffi.Array<ffi.Uint64> data;
 }
 
 /// Identifies a specific source location within a translation
@@ -7994,70 +7938,21 @@
 /// Use clang_getExpansionLocation() or clang_getSpellingLocation()
 /// to map a source location to a particular file, line, and column.
 class CXSourceLocation extends ffi.Struct {
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
 
-  /// Helper for array `ptr_data`.
-  ArrayHelper_CXSourceLocation_ptr_data_level0 get ptr_data =>
-      ArrayHelper_CXSourceLocation_ptr_data_level0(this, [2], 0, 0);
   @ffi.Uint32()
   external int int_data;
 }
 
-/// Helper for array `ptr_data` in struct `CXSourceLocation`.
-class ArrayHelper_CXSourceLocation_ptr_data_level0 {
-  final CXSourceLocation _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXSourceLocation_ptr_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_ptr_data_item_0;
-      case 1:
-        return _struct._unique_ptr_data_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_ptr_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_ptr_data_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-}
-
 /// Identifies a half-open character range in the source code.
 ///
 /// Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
 /// starting and end locations from a source range, respectively.
 class CXSourceRange extends ffi.Struct {
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
 
-  /// Helper for array `ptr_data`.
-  ArrayHelper_CXSourceRange_ptr_data_level0 get ptr_data =>
-      ArrayHelper_CXSourceRange_ptr_data_level0(this, [2], 0, 0);
   @ffi.Uint32()
   external int begin_int_data;
 
@@ -8065,49 +7960,6 @@
   external int end_int_data;
 }
 
-/// Helper for array `ptr_data` in struct `CXSourceRange`.
-class ArrayHelper_CXSourceRange_ptr_data_level0 {
-  final CXSourceRange _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXSourceRange_ptr_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_ptr_data_item_0;
-      case 1:
-        return _struct._unique_ptr_data_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_ptr_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_ptr_data_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-}
-
 /// Identifies an array of ranges.
 class CXSourceRangeList extends ffi.Struct {
   /// The number of ranges in the \c ranges array.
@@ -8159,61 +8011,8 @@
   @ffi.Int32()
   external int xdata;
 
-  external ffi.Pointer<ffi.Void> _unique_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_data_item_1;
-  external ffi.Pointer<ffi.Void> _unique_data_item_2;
-
-  /// Helper for array `data`.
-  ArrayHelper_CXCursor_data_level0 get data =>
-      ArrayHelper_CXCursor_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXCursor`.
-class ArrayHelper_CXCursor_data_level0 {
-  final CXCursor _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXCursor_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_data_item_0;
-      case 1:
-        return _struct._unique_data_item_1;
-      case 2:
-        return _struct._unique_data_item_2;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_data_item_1 = value;
-        break;
-      case 2:
-        _struct._unique_data_item_2 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
+  @ffi.Array.multi([3])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
 }
 
 /// Describes the availability of a given entity on a particular platform, e.g.,
@@ -8382,127 +8181,18 @@
   @ffi.Int32()
   external int kind;
 
-  external ffi.Pointer<ffi.Void> _unique_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_data_item_1;
-
-  /// Helper for array `data`.
-  ArrayHelper_CXType_data_level0 get data =>
-      ArrayHelper_CXType_data_level0(this, [2], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXType`.
-class ArrayHelper_CXType_data_level0 {
-  final CXType _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXType_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_data_item_0;
-      case 1:
-        return _struct._unique_data_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_data_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
 }
 
 /// Describes a single preprocessing token.
 class CXToken extends ffi.Struct {
-  @ffi.Uint32()
-  external int _unique_int_data_item_0;
-  @ffi.Uint32()
-  external int _unique_int_data_item_1;
-  @ffi.Uint32()
-  external int _unique_int_data_item_2;
-  @ffi.Uint32()
-  external int _unique_int_data_item_3;
+  @ffi.Array.multi([4])
+  external ffi.Array<ffi.Uint32> int_data;
 
-  /// Helper for array `int_data`.
-  ArrayHelper_CXToken_int_data_level0 get int_data =>
-      ArrayHelper_CXToken_int_data_level0(this, [4], 0, 0);
   external ffi.Pointer<ffi.Void> ptr_data;
 }
 
-/// Helper for array `int_data` in struct `CXToken`.
-class ArrayHelper_CXToken_int_data_level0 {
-  final CXToken _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXToken_int_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  int operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_int_data_item_0;
-      case 1:
-        return _struct._unique_int_data_item_1;
-      case 2:
-        return _struct._unique_int_data_item_2;
-      case 3:
-        return _struct._unique_int_data_item_3;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, int value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_int_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_int_data_item_1 = value;
-        break;
-      case 2:
-        _struct._unique_int_data_item_2 = value;
-        break;
-      case 3:
-        _struct._unique_int_data_item_3 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-}
-
 /// A single result of code completion.
 class CXCompletionResult extends ffi.Struct {
   /// The kind of entity that this completion refers to.
@@ -8544,59 +8234,13 @@
 
 /// Source location passed to index callbacks.
 class CXIdxLoc extends ffi.Struct {
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
 
-  /// Helper for array `ptr_data`.
-  ArrayHelper_CXIdxLoc_ptr_data_level0 get ptr_data =>
-      ArrayHelper_CXIdxLoc_ptr_data_level0(this, [2], 0, 0);
   @ffi.Uint32()
   external int int_data;
 }
 
-/// Helper for array `ptr_data` in struct `CXIdxLoc`.
-class ArrayHelper_CXIdxLoc_ptr_data_level0 {
-  final CXIdxLoc _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXIdxLoc_ptr_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_ptr_data_item_0;
-      case 1:
-        return _struct._unique_ptr_data_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_ptr_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_ptr_data_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-}
-
 /// Data for ppIncludedFile callback.
 class CXIdxIncludedFileInfo extends ffi.Struct {
   /// Location of '#' in the \#include/\#import directive.
diff --git a/example/libclang-example/pubspec.yaml b/example/libclang-example/pubspec.yaml
index e048fe5..bf0695e 100644
--- a/example/libclang-example/pubspec.yaml
+++ b/example/libclang-example/pubspec.yaml
@@ -18,7 +18,8 @@
   # sort: true
 
   # This is required if LLVM can't be found in default locations by ffigen.
-  # llvm-lib: '/usr/local/opt/llvm/lib'
+  # llvm-path:
+  #   - '/usr/local/opt/llvm'
 
   # Bash style Glob matching is also supported.
   # TODO(11): Globs dont work on windows if they begin with '.' or '..'.
@@ -66,9 +67,6 @@
 
   description: 'Holds bindings to LibClang.'
 
-  # False by default.
-  array-workaround: true
-
   # Doc Comments for generated binings.
   # Comments can be disabled by using comments: false
   comments:
diff --git a/lib/src/README.md b/lib/src/README.md
index 7564006..2b20f84 100644
--- a/lib/src/README.md
+++ b/lib/src/README.md
@@ -22,7 +22,7 @@
     - `--verbose`: Sets log level.
     - `--config`: Specifies a config file.
 - The internal modules are called by `ffigen.dart` in the following way:
-- `ffigen.dart` will try to find dynamic library in default locations. If that fails, the user must excplicitly specify location in ffigen's config under the key `llvm-lib`.
+- `ffigen.dart` will try to find dynamic library in default locations. If that fails, the user must excplicitly specify location in ffigen's config under the key `llvm-path`.
     - It first creates a `Config` object from an input Yaml file. This is used by other modules.
     - The `parse` method is then invoked to generate a `Library` object.
     - Finally, the code is generated from the `Library` object to the specified file.
diff --git a/lib/src/code_generator/struc.dart b/lib/src/code_generator/struc.dart
index 37edfa0..8b87891 100644
--- a/lib/src/code_generator/struc.dart
+++ b/lib/src/code_generator/struc.dart
@@ -76,6 +76,13 @@
     return array;
   }
 
+  String _getInlineArrayTypeString(Type type, Writer w) {
+    if (type.broadType == BroadType.ConstantArray) {
+      return '${w.ffiLibraryPrefix}.Array<${_getInlineArrayTypeString(type.child!, w)}>';
+    }
+    return type.getCType(w);
+  }
+
   List<Typedef>? _typedefDependencies;
   @override
   List<Typedef> getTypedefDependencies(Writer w) {
@@ -101,10 +108,6 @@
       s.write(makeDartDoc(dartDoc!));
     }
 
-    final helpers = <ArrayHelper>[];
-
-    final expandedArrayItemPrefix = getUniqueExpandedArrayItemPrefix();
-
     /// Adding [enclosingClassName] because dart doesn't allow class member
     /// to have the same name as the class.
     final localUniqueNamer = UniqueNamer({enclosingClassName});
@@ -116,23 +119,15 @@
     // Write class declaration.
     s.write(
         'class $enclosingClassName extends ${w.ffiLibraryPrefix}.${isOpaque ? 'Opaque' : 'Struct'}{\n');
+    const depth = '  ';
     for (final m in members) {
       final memberName = localUniqueNamer.makeUnique(m.name);
       if (m.type.broadType == BroadType.ConstantArray) {
-        // TODO(5): Remove array helpers when inline array support arives.
-        final arrayHelper = ArrayHelper(
-          helperClassGroupName:
-              '${w.arrayHelperClassPrefix}_${enclosingClassName}_$memberName',
-          elementType: m.type.getBaseArrayType(),
-          dimensions: _getArrayDimensionLengths(m.type),
-          name: memberName,
-          structName: enclosingClassName,
-          elementNamePrefix: '$expandedArrayItemPrefix${memberName}_item_',
-        );
-        s.write(arrayHelper.declarationString(w));
-        helpers.add(arrayHelper);
+        s.write(
+            '$depth@${w.ffiLibraryPrefix}.Array.multi(${_getArrayDimensionLengths(m.type)})\n');
+        s.write(
+            '${depth}external ${_getInlineArrayTypeString(m.type, w)} $memberName;\n\n');
       } else {
-        const depth = '  ';
         if (m.dartDoc != null) {
           s.write(depth + '/// ');
           s.writeAll(m.dartDoc!.split('\n'), '\n' + depth + '/// ');
@@ -146,28 +141,8 @@
     }
     s.write('}\n\n');
 
-    for (final helper in helpers) {
-      s.write(helper.helperClassString(w));
-    }
-
     return BindingString(type: BindingStringType.struc, string: s.toString());
   }
-
-  /// Gets a unique prefix in local namespace for expanded array items.
-  String getUniqueExpandedArrayItemPrefix() {
-    final base = '_unique';
-    var expandedArrayItemPrefix = base;
-    var suffixInt = 0;
-    for (var i = 0; i < members.length; i++) {
-      if (members[i].name.startsWith(expandedArrayItemPrefix)) {
-        // Not a unique prefix, start over with a new suffix.
-        i = -1;
-        suffixInt++;
-        expandedArrayItemPrefix = '$base$suffixInt';
-      }
-    }
-    return expandedArrayItemPrefix + '_';
-  }
 }
 
 class Member {
@@ -183,137 +158,3 @@
     this.dartDoc,
   }) : originalName = originalName ?? name;
 }
-
-// Helper bindings for struct array.
-class ArrayHelper {
-  final Type elementType;
-  final List<int> dimensions;
-  final String? structName;
-
-  final String? name;
-  final String helperClassGroupName;
-  final String elementNamePrefix;
-
-  int? _expandedArrayLength;
-  int get expandedArrayLength {
-    if (_expandedArrayLength != null) return _expandedArrayLength!;
-
-    var arrayLength = 1;
-    for (final i in dimensions) {
-      arrayLength = arrayLength * i;
-    }
-    return arrayLength;
-  }
-
-  ArrayHelper({
-    required this.elementType,
-    required this.dimensions,
-    required this.structName,
-    required this.name,
-    required this.helperClassGroupName,
-    required this.elementNamePrefix,
-  });
-
-  /// Create declaration binding, added inside the struct binding.
-  String declarationString(Writer w) {
-    final s = StringBuffer();
-    final arrayDartType = elementType.getDartType(w);
-    final arrayCType = elementType.getCType(w);
-
-    for (var i = 0; i < expandedArrayLength; i++) {
-      if (elementType.isPrimitive) {
-        s.write('  @$arrayCType()\n');
-      }
-      s.write('  external $arrayDartType $elementNamePrefix$i;\n');
-    }
-
-    s.write('/// Helper for array `$name`.\n');
-    s.write(
-        '${helperClassGroupName}_level0 get $name => ${helperClassGroupName}_level0(this, $dimensions, 0, 0);\n');
-
-    return s.toString();
-  }
-
-  String helperClassString(Writer w) {
-    final s = StringBuffer();
-    final arrayType = elementType.getDartType(w);
-    for (var dim = 0; dim < dimensions.length; dim++) {
-      final helperClassName = '${helperClassGroupName}_level$dim';
-      final structIdentifier = '_struct';
-      final dimensionsIdentifier = 'dimensions';
-      final levelIdentifier = 'level';
-      final absoluteIndexIdentifier = '_absoluteIndex';
-      final checkBoundsFunctionIdentifier = '_checkBounds';
-      final legthIdentifier = 'length';
-
-      s.write('/// Helper for array `$name` in struct `$structName`.\n');
-
-      // Write class declaration.
-      s.write('class $helperClassName{\n');
-      s.write('final $structName $structIdentifier;\n');
-      s.write('final List<int> $dimensionsIdentifier;\n');
-      s.write('final int $levelIdentifier;\n');
-      s.write('final int $absoluteIndexIdentifier;\n');
-      s.write(
-          'int get $legthIdentifier => $dimensionsIdentifier[$levelIdentifier];\n');
-
-      // Write class constructor.
-      s.write(
-          '$helperClassName(this.$structIdentifier, this.$dimensionsIdentifier, this.$levelIdentifier, this.$absoluteIndexIdentifier);\n');
-
-      // Write checkBoundsFunction.
-      s.write('''
-  void $checkBoundsFunctionIdentifier(int index) {
-    if (index >= $legthIdentifier || index < 0) {
-      throw RangeError('Dimension \$$levelIdentifier: index not in range 0..\$$legthIdentifier exclusive.');
-    }
-  }
-  ''');
-      // If this isn't the last level.
-      if (dim + 1 != dimensions.length) {
-        // Override [] operator.
-        s.write('''
-  ${helperClassGroupName}_level${dim + 1} operator [](int index) {
-    $checkBoundsFunctionIdentifier(index);
-    var offset = index;
-    for (var i = level + 1; i < $dimensionsIdentifier.length; i++) {
-      offset *= $dimensionsIdentifier[i];
-    }
-    return ${helperClassGroupName}_level${dim + 1}(
-        $structIdentifier, $dimensionsIdentifier, $levelIdentifier + 1, $absoluteIndexIdentifier + offset);
-  }
-''');
-      } else {
-        // This is the last level, add switching logic here.
-        // Override [] operator.
-        s.write('$arrayType operator[](int index){\n');
-        s.write('$checkBoundsFunctionIdentifier(index);\n');
-        s.write('switch($absoluteIndexIdentifier+index){\n');
-        for (var i = 0; i < expandedArrayLength; i++) {
-          s.write('case $i:\n');
-          s.write('  return $structIdentifier.$elementNamePrefix$i;\n');
-        }
-        s.write('default:\n');
-        s.write("  throw Exception('Invalid Array Helper generated.');");
-        s.write('}\n');
-        s.write('}\n');
-
-        // Override []= operator.
-        s.write('void operator[]=(int index, $arrayType value){\n');
-        s.write('$checkBoundsFunctionIdentifier(index);\n');
-        s.write('switch($absoluteIndexIdentifier+index){\n');
-        for (var i = 0; i < expandedArrayLength; i++) {
-          s.write('case $i:\n');
-          s.write('  $structIdentifier.$elementNamePrefix$i = value;\n');
-          s.write('  break;\n');
-        }
-        s.write('default:\n');
-        s.write("  throw Exception('Invalid Array Helper generated.');\n");
-        s.write('}\n');
-        s.write('}\n');
-      }
-      s.write('}\n');
-    }
-    return s.toString();
-  }
-}
diff --git a/lib/src/config_provider/config.dart b/lib/src/config_provider/config.dart
index cacc7fa..e42ed46 100644
--- a/lib/src/config_provider/config.dart
+++ b/lib/src/config_provider/config.dart
@@ -84,13 +84,6 @@
   StructPackingOverride get structPackingOverride => _structPackingOverride;
   late StructPackingOverride _structPackingOverride;
 
-  /// If tool should generate array workarounds.
-  ///
-  /// If false(default), structs with inline array members will have all its
-  /// members removed.
-  bool get arrayWorkaround => _arrayWorkaround;
-  late bool _arrayWorkaround;
-
   /// If dart bool should be generated for C booleans.
   bool get dartBool => _dartBool;
   late bool _dartBool;
@@ -185,24 +178,13 @@
   /// Key: Name, Value: [Specification]
   Map<List<String>, Specification> _getSpecs() {
     return <List<String>, Specification>{
-      //TODO: Deprecated, remove in next major update.
-      [strings.llvmLib]: Specification<String>(
-        requirement: Requirement.no,
-        validator: llvmLibValidator,
-        extractor: llvmLibExtractor,
-        defaultValue: () => '',
-        extractedResult: (dynamic result) {
-          _libclangDylib = result as String;
-        },
-      ),
       [strings.llvmPath]: Specification<String>(
         requirement: Requirement.no,
         validator: llvmPathValidator,
         extractor: llvmPathExtractor,
         defaultValue: () => findDylibAtDefaultLocations(),
         extractedResult: (dynamic result) {
-          // If this key wasn't already set by `llvm-lib` use this result.
-          if (_libclangDylib.isEmpty) _libclangDylib = result as String;
+          _libclangDylib = result as String;
         },
       ),
       [strings.output]: Specification<String>(
@@ -348,13 +330,6 @@
         extractedResult: (dynamic result) =>
             _structPackingOverride = result as StructPackingOverride,
       ),
-      [strings.arrayWorkaround]: Specification<bool>(
-        requirement: Requirement.no,
-        validator: booleanValidator,
-        extractor: booleanExtractor,
-        defaultValue: () => false,
-        extractedResult: (dynamic result) => _arrayWorkaround = result as bool,
-      ),
       [strings.dartBool]: Specification<bool>(
         requirement: Requirement.no,
         validator: booleanValidator,
diff --git a/lib/src/config_provider/spec_utils.dart b/lib/src/config_provider/spec_utils.dart
index ff4a44a..a08d8c8 100644
--- a/lib/src/config_provider/spec_utils.dart
+++ b/lib/src/config_provider/spec_utils.dart
@@ -339,28 +339,6 @@
   }
 }
 
-String llvmLibExtractor(dynamic value) {
-  // Extract libclang's dylib from this.
-  final p = findLibclangDylib(value as String);
-  if (p == null) {
-    _logger.severe("Couldn't find ${strings.dylibFileName} at $value.");
-    exit(1);
-  } else {
-    return p;
-  }
-}
-
-bool llvmLibValidator(List<String> name, dynamic value) {
-  _logger.warning(
-      'Deprecated ${strings.llvmLib}: please use ${strings.llvmPath} instead.');
-  if (!checkType<String>(name, value) ||
-      !Directory(value as String).existsSync()) {
-    _logger.severe('Expected $name to be a valid folder Path.');
-    return false;
-  }
-  return true;
-}
-
 String llvmPathExtractor(dynamic value) {
   // Extract libclang's dylib from user specified paths.
   for (final path in (value as YamlList)) {
diff --git a/lib/src/header_parser/clang_bindings/clang_bindings.dart b/lib/src/header_parser/clang_bindings/clang_bindings.dart
index 2c69fa7..0525565 100644
--- a/lib/src/header_parser/clang_bindings/clang_bindings.dart
+++ b/lib/src/header_parser/clang_bindings/clang_bindings.dart
@@ -1195,70 +1195,21 @@
 /// Use clang_getExpansionLocation() or clang_getSpellingLocation()
 /// to map a source location to a particular file, line, and column.
 class CXSourceLocation extends ffi.Struct {
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
 
-  /// Helper for array `ptr_data`.
-  ArrayHelper_CXSourceLocation_ptr_data_level0 get ptr_data =>
-      ArrayHelper_CXSourceLocation_ptr_data_level0(this, [2], 0, 0);
   @ffi.Uint32()
   external int int_data;
 }
 
-/// Helper for array `ptr_data` in struct `CXSourceLocation`.
-class ArrayHelper_CXSourceLocation_ptr_data_level0 {
-  final CXSourceLocation _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXSourceLocation_ptr_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_ptr_data_item_0;
-      case 1:
-        return _struct._unique_ptr_data_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_ptr_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_ptr_data_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-}
-
 /// Identifies a half-open character range in the source code.
 ///
 /// Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
 /// starting and end locations from a source range, respectively.
 class CXSourceRange extends ffi.Struct {
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
 
-  /// Helper for array `ptr_data`.
-  ArrayHelper_CXSourceRange_ptr_data_level0 get ptr_data =>
-      ArrayHelper_CXSourceRange_ptr_data_level0(this, [2], 0, 0);
   @ffi.Uint32()
   external int begin_int_data;
 
@@ -1266,49 +1217,6 @@
   external int end_int_data;
 }
 
-/// Helper for array `ptr_data` in struct `CXSourceRange`.
-class ArrayHelper_CXSourceRange_ptr_data_level0 {
-  final CXSourceRange _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXSourceRange_ptr_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_ptr_data_item_0;
-      case 1:
-        return _struct._unique_ptr_data_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_ptr_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_ptr_data_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-}
-
 /// Options to control the display of diagnostics.
 ///
 /// The values in this enum are meant to be combined to customize the
@@ -2292,61 +2200,8 @@
   @ffi.Int32()
   external int xdata;
 
-  external ffi.Pointer<ffi.Void> _unique_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_data_item_1;
-  external ffi.Pointer<ffi.Void> _unique_data_item_2;
-
-  /// Helper for array `data`.
-  ArrayHelper_CXCursor_data_level0 get data =>
-      ArrayHelper_CXCursor_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXCursor`.
-class ArrayHelper_CXCursor_data_level0 {
-  final CXCursor _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXCursor_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_data_item_0;
-      case 1:
-        return _struct._unique_data_item_1;
-      case 2:
-        return _struct._unique_data_item_2;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_data_item_1 = value;
-        break;
-      case 2:
-        _struct._unique_data_item_2 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
+  @ffi.Array.multi([3])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
 }
 
 /// Describes the kind of type
@@ -2484,55 +2339,8 @@
   @ffi.Int32()
   external int kind;
 
-  external ffi.Pointer<ffi.Void> _unique_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_data_item_1;
-
-  /// Helper for array `data`.
-  ArrayHelper_CXType_data_level0 get data =>
-      ArrayHelper_CXType_data_level0(this, [2], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXType`.
-class ArrayHelper_CXType_data_level0 {
-  final CXType _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXType_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_data_item_0;
-      case 1:
-        return _struct._unique_data_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_data_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
 }
 
 /// Describes how the traversal of the children of a particular
diff --git a/lib/src/header_parser/sub_parsers/structdecl_parser.dart b/lib/src/header_parser/sub_parsers/structdecl_parser.dart
index c27d841..e5970f4 100644
--- a/lib/src/header_parser/sub_parsers/structdecl_parser.dart
+++ b/lib/src/header_parser/sub_parsers/structdecl_parser.dart
@@ -21,7 +21,6 @@
   Struc? struc;
   bool unimplementedMemberType = false;
   bool flexibleArrayMember = false;
-  bool arrayMember = false;
   bool bitFieldMember = false;
   bool dartHandleMember = false;
   bool incompleteStructMember = false;
@@ -29,7 +28,6 @@
   bool get isInComplete =>
       unimplementedMemberType ||
       flexibleArrayMember ||
-      (arrayMember && !config.arrayWorkaround) ||
       bitFieldMember ||
       (dartHandleMember && config.useDartHandle) ||
       incompleteStructMember;
@@ -168,12 +166,7 @@
 
   visitChildrenResultChecker(resultCode);
 
-  if (_stack.top.arrayMember && !config.arrayWorkaround) {
-    _logger.fine(
-        '---- Removed Struct members, reason: struct has array members ${cursor.completeStringRepr()}');
-    _logger.warning(
-        'Removed All Struct Members from: ${_stack.top.struc!.name}(${_stack.top.struc!.originalName}), Array members not supported');
-  } else if (_stack.top.unimplementedMemberType) {
+  if (_stack.top.unimplementedMemberType) {
     _logger.fine(
         '---- Removed Struct members, reason: member with unimplementedtype ${cursor.completeStringRepr()}');
     _logger.warning(
@@ -227,9 +220,6 @@
       }
 
       final mt = cursor.type().toCodeGenType();
-      if (mt.broadType == BroadType.ConstantArray) {
-        _stack.top.arrayMember = true;
-      }
       if (mt.broadType == BroadType.IncompleteArray) {
         // TODO(68): Structs with flexible Array Members are not supported.
         _stack.top.flexibleArrayMember = true;
diff --git a/lib/src/strings.dart b/lib/src/strings.dart
index 76ed940..0b5d2f1 100644
--- a/lib/src/strings.dart
+++ b/lib/src/strings.dart
@@ -22,7 +22,6 @@
   return name;
 }
 
-const llvmLib = 'llvm-lib';
 const llvmPath = 'llvm-path';
 
 /// Name of the parent folder of dynamic library `lib` or `bin` (on windows).
@@ -123,8 +122,6 @@
 // Boolean flags.
 const sort = 'sort';
 const useSupportedTypedefs = 'use-supported-typedefs';
-const warnWhenRemoving = 'warn-when-removing';
-const arrayWorkaround = 'array-workaround';
 const dartBool = 'dart-bool';
 const useDartHandle = 'use-dart-handle';
 
diff --git a/pubspec.yaml b/pubspec.yaml
index e761291..15555a2 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 name: ffigen
-version: 2.5.0-beta.1
+version: 3.0.0-beta.0
 homepage: https://github.com/dart-lang/ffigen
 description: Generator for FFI bindings, using LibClang to parse C header files.
 
diff --git a/test/code_generator_tests/expected_bindings/_expected_internal_conflict_resolution_bindings.dart b/test/code_generator_tests/expected_bindings/_expected_internal_conflict_resolution_bindings.dart
index 5e599fc..4556dfa 100644
--- a/test/code_generator_tests/expected_bindings/_expected_internal_conflict_resolution_bindings.dart
+++ b/test/code_generator_tests/expected_bindings/_expected_internal_conflict_resolution_bindings.dart
@@ -59,57 +59,8 @@
 }
 
 class _Test extends ffi.Struct {
-  @ffi.Int8()
-  external int _unique_array_item_0;
-  @ffi.Int8()
-  external int _unique_array_item_1;
-
-  /// Helper for array `array`.
-  ArrayHelper1__Test_array_level0 get array =>
-      ArrayHelper1__Test_array_level0(this, [2], 0, 0);
-}
-
-/// Helper for array `array` in struct `_Test`.
-class ArrayHelper1__Test_array_level0 {
-  final _Test _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper1__Test_array_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  int operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_array_item_0;
-      case 1:
-        return _struct._unique_array_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, int value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_array_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_array_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Int8> array;
 }
 
 class ArrayHelperPrefixCollisionTest extends ffi.Opaque {}
diff --git a/test/example_tests/libclang_example_test.dart b/test/example_tests/libclang_example_test.dart
index f385b00..deed803 100644
--- a/test/example_tests/libclang_example_test.dart
+++ b/test/example_tests/libclang_example_test.dart
@@ -43,7 +43,6 @@
 
 ${strings.name}: 'LibClang'
 ${strings.description}: 'Holds bindings to LibClang.'
-${strings.arrayWorkaround}: true
 ${strings.comments}:
   ${strings.style}: ${strings.doxygen}
   ${strings.length}: ${strings.full}
diff --git a/test/header_parser_tests/nested_parsing_test.dart b/test/header_parser_tests/nested_parsing_test.dart
index 978b365..4dc9427 100644
--- a/test/header_parser_tests/nested_parsing_test.dart
+++ b/test/header_parser_tests/nested_parsing_test.dart
@@ -23,7 +23,6 @@
 ${strings.name}: 'NativeLibrary'
 ${strings.description}: 'Nested Parsing Test'
 ${strings.output}: 'unused'
-${strings.arrayWorkaround}: true
 ${strings.headers}:
   ${strings.entryPoints}:
     - 'test/header_parser_tests/nested_parsing.h'
diff --git a/test/large_integration_tests/_expected_libclang_bindings.dart b/test/large_integration_tests/_expected_libclang_bindings.dart
index 34c6633..be68fb5 100644
--- a/test/large_integration_tests/_expected_libclang_bindings.dart
+++ b/test/large_integration_tests/_expected_libclang_bindings.dart
@@ -5937,129 +5937,24 @@
 /// Uniquely identifies a CXFile, that refers to the same underlying file,
 /// across an indexing session.
 class CXFileUniqueID extends ffi.Struct {
-  @ffi.Uint64()
-  external int _unique_data_item_0;
-  @ffi.Uint64()
-  external int _unique_data_item_1;
-  @ffi.Uint64()
-  external int _unique_data_item_2;
-
-  /// Helper for array `data`.
-  ArrayHelper_CXFileUniqueID_data_level0 get data =>
-      ArrayHelper_CXFileUniqueID_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXFileUniqueID`.
-class ArrayHelper_CXFileUniqueID_data_level0 {
-  final CXFileUniqueID _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXFileUniqueID_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  int operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_data_item_0;
-      case 1:
-        return _struct._unique_data_item_1;
-      case 2:
-        return _struct._unique_data_item_2;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, int value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_data_item_1 = value;
-        break;
-      case 2:
-        _struct._unique_data_item_2 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
+  @ffi.Array.multi([3])
+  external ffi.Array<ffi.Uint64> data;
 }
 
 /// Identifies a specific source location within a translation unit.
 class CXSourceLocation extends ffi.Struct {
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
 
-  /// Helper for array `ptr_data`.
-  ArrayHelper_CXSourceLocation_ptr_data_level0 get ptr_data =>
-      ArrayHelper_CXSourceLocation_ptr_data_level0(this, [2], 0, 0);
   @ffi.Uint32()
   external int int_data;
 }
 
-/// Helper for array `ptr_data` in struct `CXSourceLocation`.
-class ArrayHelper_CXSourceLocation_ptr_data_level0 {
-  final CXSourceLocation _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXSourceLocation_ptr_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_ptr_data_item_0;
-      case 1:
-        return _struct._unique_ptr_data_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_ptr_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_ptr_data_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-}
-
 /// Identifies a half-open character range in the source code.
 class CXSourceRange extends ffi.Struct {
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
 
-  /// Helper for array `ptr_data`.
-  ArrayHelper_CXSourceRange_ptr_data_level0 get ptr_data =>
-      ArrayHelper_CXSourceRange_ptr_data_level0(this, [2], 0, 0);
   @ffi.Uint32()
   external int begin_int_data;
 
@@ -6067,49 +5962,6 @@
   external int end_int_data;
 }
 
-/// Helper for array `ptr_data` in struct `CXSourceRange`.
-class ArrayHelper_CXSourceRange_ptr_data_level0 {
-  final CXSourceRange _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXSourceRange_ptr_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_ptr_data_item_0;
-      case 1:
-        return _struct._unique_ptr_data_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_ptr_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_ptr_data_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-}
-
 /// Identifies an array of ranges.
 class CXSourceRangeList extends ffi.Struct {
   /// The number of ranges in the ranges array.
@@ -6977,61 +6829,8 @@
   @ffi.Int32()
   external int xdata;
 
-  external ffi.Pointer<ffi.Void> _unique_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_data_item_1;
-  external ffi.Pointer<ffi.Void> _unique_data_item_2;
-
-  /// Helper for array `data`.
-  ArrayHelper_CXCursor_data_level0 get data =>
-      ArrayHelper_CXCursor_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXCursor`.
-class ArrayHelper_CXCursor_data_level0 {
-  final CXCursor _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXCursor_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_data_item_0;
-      case 1:
-        return _struct._unique_data_item_1;
-      case 2:
-        return _struct._unique_data_item_2;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_data_item_1 = value;
-        break;
-      case 2:
-        _struct._unique_data_item_2 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
+  @ffi.Array.multi([3])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
 }
 
 /// Describe the linkage of the entity referred to by a cursor.
@@ -7271,55 +7070,8 @@
   @ffi.Int32()
   external int kind;
 
-  external ffi.Pointer<ffi.Void> _unique_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_data_item_1;
-
-  /// Helper for array `data`.
-  ArrayHelper_CXType_data_level0 get data =>
-      ArrayHelper_CXType_data_level0(this, [2], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXType`.
-class ArrayHelper_CXType_data_level0 {
-  final CXType _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXType_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_data_item_0;
-      case 1:
-        return _struct._unique_data_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_data_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
 }
 
 /// Describes the kind of a template argument.
@@ -7515,74 +7267,12 @@
 
 /// Describes a single preprocessing token.
 class CXToken extends ffi.Struct {
-  @ffi.Uint32()
-  external int _unique_int_data_item_0;
-  @ffi.Uint32()
-  external int _unique_int_data_item_1;
-  @ffi.Uint32()
-  external int _unique_int_data_item_2;
-  @ffi.Uint32()
-  external int _unique_int_data_item_3;
+  @ffi.Array.multi([4])
+  external ffi.Array<ffi.Uint32> int_data;
 
-  /// Helper for array `int_data`.
-  ArrayHelper_CXToken_int_data_level0 get int_data =>
-      ArrayHelper_CXToken_int_data_level0(this, [4], 0, 0);
   external ffi.Pointer<ffi.Void> ptr_data;
 }
 
-/// Helper for array `int_data` in struct `CXToken`.
-class ArrayHelper_CXToken_int_data_level0 {
-  final CXToken _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXToken_int_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  int operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_int_data_item_0;
-      case 1:
-        return _struct._unique_int_data_item_1;
-      case 2:
-        return _struct._unique_int_data_item_2;
-      case 3:
-        return _struct._unique_int_data_item_3;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, int value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_int_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_int_data_item_1 = value;
-        break;
-      case 2:
-        _struct._unique_int_data_item_2 = value;
-        break;
-      case 3:
-        _struct._unique_int_data_item_3 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-}
-
 /// A single result of code completion.
 class CXCompletionResult extends ffi.Struct {
   /// The kind of entity that this completion refers to.
@@ -7829,59 +7519,13 @@
 
 /// Source location passed to index callbacks.
 class CXIdxLoc extends ffi.Struct {
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
-  external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
 
-  /// Helper for array `ptr_data`.
-  ArrayHelper_CXIdxLoc_ptr_data_level0 get ptr_data =>
-      ArrayHelper_CXIdxLoc_ptr_data_level0(this, [2], 0, 0);
   @ffi.Uint32()
   external int int_data;
 }
 
-/// Helper for array `ptr_data` in struct `CXIdxLoc`.
-class ArrayHelper_CXIdxLoc_ptr_data_level0 {
-  final CXIdxLoc _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_CXIdxLoc_ptr_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ffi.Pointer<ffi.Void> operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_ptr_data_item_0;
-      case 1:
-        return _struct._unique_ptr_data_item_1;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, ffi.Pointer<ffi.Void> value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_ptr_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_ptr_data_item_1 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-}
-
 /// Data for ppIncludedFile callback.
 class CXIdxIncludedFileInfo extends ffi.Struct {
   /// Location of '#' in the #include/#import directive.
diff --git a/test/large_integration_tests/_expected_sqlite_bindings.dart b/test/large_integration_tests/_expected_sqlite_bindings.dart
index 3a7e50e..9580bd1 100644
--- a/test/large_integration_tests/_expected_sqlite_bindings.dart
+++ b/test/large_integration_tests/_expected_sqlite_bindings.dart
@@ -10061,379 +10061,8 @@
 /// transaction that sees that historical version of the database rather than
 /// the most recent version.
 class sqlite3_snapshot extends ffi.Struct {
-  @ffi.Uint8()
-  external int _unique_hidden_item_0;
-  @ffi.Uint8()
-  external int _unique_hidden_item_1;
-  @ffi.Uint8()
-  external int _unique_hidden_item_2;
-  @ffi.Uint8()
-  external int _unique_hidden_item_3;
-  @ffi.Uint8()
-  external int _unique_hidden_item_4;
-  @ffi.Uint8()
-  external int _unique_hidden_item_5;
-  @ffi.Uint8()
-  external int _unique_hidden_item_6;
-  @ffi.Uint8()
-  external int _unique_hidden_item_7;
-  @ffi.Uint8()
-  external int _unique_hidden_item_8;
-  @ffi.Uint8()
-  external int _unique_hidden_item_9;
-  @ffi.Uint8()
-  external int _unique_hidden_item_10;
-  @ffi.Uint8()
-  external int _unique_hidden_item_11;
-  @ffi.Uint8()
-  external int _unique_hidden_item_12;
-  @ffi.Uint8()
-  external int _unique_hidden_item_13;
-  @ffi.Uint8()
-  external int _unique_hidden_item_14;
-  @ffi.Uint8()
-  external int _unique_hidden_item_15;
-  @ffi.Uint8()
-  external int _unique_hidden_item_16;
-  @ffi.Uint8()
-  external int _unique_hidden_item_17;
-  @ffi.Uint8()
-  external int _unique_hidden_item_18;
-  @ffi.Uint8()
-  external int _unique_hidden_item_19;
-  @ffi.Uint8()
-  external int _unique_hidden_item_20;
-  @ffi.Uint8()
-  external int _unique_hidden_item_21;
-  @ffi.Uint8()
-  external int _unique_hidden_item_22;
-  @ffi.Uint8()
-  external int _unique_hidden_item_23;
-  @ffi.Uint8()
-  external int _unique_hidden_item_24;
-  @ffi.Uint8()
-  external int _unique_hidden_item_25;
-  @ffi.Uint8()
-  external int _unique_hidden_item_26;
-  @ffi.Uint8()
-  external int _unique_hidden_item_27;
-  @ffi.Uint8()
-  external int _unique_hidden_item_28;
-  @ffi.Uint8()
-  external int _unique_hidden_item_29;
-  @ffi.Uint8()
-  external int _unique_hidden_item_30;
-  @ffi.Uint8()
-  external int _unique_hidden_item_31;
-  @ffi.Uint8()
-  external int _unique_hidden_item_32;
-  @ffi.Uint8()
-  external int _unique_hidden_item_33;
-  @ffi.Uint8()
-  external int _unique_hidden_item_34;
-  @ffi.Uint8()
-  external int _unique_hidden_item_35;
-  @ffi.Uint8()
-  external int _unique_hidden_item_36;
-  @ffi.Uint8()
-  external int _unique_hidden_item_37;
-  @ffi.Uint8()
-  external int _unique_hidden_item_38;
-  @ffi.Uint8()
-  external int _unique_hidden_item_39;
-  @ffi.Uint8()
-  external int _unique_hidden_item_40;
-  @ffi.Uint8()
-  external int _unique_hidden_item_41;
-  @ffi.Uint8()
-  external int _unique_hidden_item_42;
-  @ffi.Uint8()
-  external int _unique_hidden_item_43;
-  @ffi.Uint8()
-  external int _unique_hidden_item_44;
-  @ffi.Uint8()
-  external int _unique_hidden_item_45;
-  @ffi.Uint8()
-  external int _unique_hidden_item_46;
-  @ffi.Uint8()
-  external int _unique_hidden_item_47;
-
-  /// Helper for array `hidden`.
-  ArrayHelper_sqlite3_snapshot_hidden_level0 get hidden =>
-      ArrayHelper_sqlite3_snapshot_hidden_level0(this, [48], 0, 0);
-}
-
-/// Helper for array `hidden` in struct `sqlite3_snapshot`.
-class ArrayHelper_sqlite3_snapshot_hidden_level0 {
-  final sqlite3_snapshot _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_sqlite3_snapshot_hidden_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  int operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_hidden_item_0;
-      case 1:
-        return _struct._unique_hidden_item_1;
-      case 2:
-        return _struct._unique_hidden_item_2;
-      case 3:
-        return _struct._unique_hidden_item_3;
-      case 4:
-        return _struct._unique_hidden_item_4;
-      case 5:
-        return _struct._unique_hidden_item_5;
-      case 6:
-        return _struct._unique_hidden_item_6;
-      case 7:
-        return _struct._unique_hidden_item_7;
-      case 8:
-        return _struct._unique_hidden_item_8;
-      case 9:
-        return _struct._unique_hidden_item_9;
-      case 10:
-        return _struct._unique_hidden_item_10;
-      case 11:
-        return _struct._unique_hidden_item_11;
-      case 12:
-        return _struct._unique_hidden_item_12;
-      case 13:
-        return _struct._unique_hidden_item_13;
-      case 14:
-        return _struct._unique_hidden_item_14;
-      case 15:
-        return _struct._unique_hidden_item_15;
-      case 16:
-        return _struct._unique_hidden_item_16;
-      case 17:
-        return _struct._unique_hidden_item_17;
-      case 18:
-        return _struct._unique_hidden_item_18;
-      case 19:
-        return _struct._unique_hidden_item_19;
-      case 20:
-        return _struct._unique_hidden_item_20;
-      case 21:
-        return _struct._unique_hidden_item_21;
-      case 22:
-        return _struct._unique_hidden_item_22;
-      case 23:
-        return _struct._unique_hidden_item_23;
-      case 24:
-        return _struct._unique_hidden_item_24;
-      case 25:
-        return _struct._unique_hidden_item_25;
-      case 26:
-        return _struct._unique_hidden_item_26;
-      case 27:
-        return _struct._unique_hidden_item_27;
-      case 28:
-        return _struct._unique_hidden_item_28;
-      case 29:
-        return _struct._unique_hidden_item_29;
-      case 30:
-        return _struct._unique_hidden_item_30;
-      case 31:
-        return _struct._unique_hidden_item_31;
-      case 32:
-        return _struct._unique_hidden_item_32;
-      case 33:
-        return _struct._unique_hidden_item_33;
-      case 34:
-        return _struct._unique_hidden_item_34;
-      case 35:
-        return _struct._unique_hidden_item_35;
-      case 36:
-        return _struct._unique_hidden_item_36;
-      case 37:
-        return _struct._unique_hidden_item_37;
-      case 38:
-        return _struct._unique_hidden_item_38;
-      case 39:
-        return _struct._unique_hidden_item_39;
-      case 40:
-        return _struct._unique_hidden_item_40;
-      case 41:
-        return _struct._unique_hidden_item_41;
-      case 42:
-        return _struct._unique_hidden_item_42;
-      case 43:
-        return _struct._unique_hidden_item_43;
-      case 44:
-        return _struct._unique_hidden_item_44;
-      case 45:
-        return _struct._unique_hidden_item_45;
-      case 46:
-        return _struct._unique_hidden_item_46;
-      case 47:
-        return _struct._unique_hidden_item_47;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, int value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_hidden_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_hidden_item_1 = value;
-        break;
-      case 2:
-        _struct._unique_hidden_item_2 = value;
-        break;
-      case 3:
-        _struct._unique_hidden_item_3 = value;
-        break;
-      case 4:
-        _struct._unique_hidden_item_4 = value;
-        break;
-      case 5:
-        _struct._unique_hidden_item_5 = value;
-        break;
-      case 6:
-        _struct._unique_hidden_item_6 = value;
-        break;
-      case 7:
-        _struct._unique_hidden_item_7 = value;
-        break;
-      case 8:
-        _struct._unique_hidden_item_8 = value;
-        break;
-      case 9:
-        _struct._unique_hidden_item_9 = value;
-        break;
-      case 10:
-        _struct._unique_hidden_item_10 = value;
-        break;
-      case 11:
-        _struct._unique_hidden_item_11 = value;
-        break;
-      case 12:
-        _struct._unique_hidden_item_12 = value;
-        break;
-      case 13:
-        _struct._unique_hidden_item_13 = value;
-        break;
-      case 14:
-        _struct._unique_hidden_item_14 = value;
-        break;
-      case 15:
-        _struct._unique_hidden_item_15 = value;
-        break;
-      case 16:
-        _struct._unique_hidden_item_16 = value;
-        break;
-      case 17:
-        _struct._unique_hidden_item_17 = value;
-        break;
-      case 18:
-        _struct._unique_hidden_item_18 = value;
-        break;
-      case 19:
-        _struct._unique_hidden_item_19 = value;
-        break;
-      case 20:
-        _struct._unique_hidden_item_20 = value;
-        break;
-      case 21:
-        _struct._unique_hidden_item_21 = value;
-        break;
-      case 22:
-        _struct._unique_hidden_item_22 = value;
-        break;
-      case 23:
-        _struct._unique_hidden_item_23 = value;
-        break;
-      case 24:
-        _struct._unique_hidden_item_24 = value;
-        break;
-      case 25:
-        _struct._unique_hidden_item_25 = value;
-        break;
-      case 26:
-        _struct._unique_hidden_item_26 = value;
-        break;
-      case 27:
-        _struct._unique_hidden_item_27 = value;
-        break;
-      case 28:
-        _struct._unique_hidden_item_28 = value;
-        break;
-      case 29:
-        _struct._unique_hidden_item_29 = value;
-        break;
-      case 30:
-        _struct._unique_hidden_item_30 = value;
-        break;
-      case 31:
-        _struct._unique_hidden_item_31 = value;
-        break;
-      case 32:
-        _struct._unique_hidden_item_32 = value;
-        break;
-      case 33:
-        _struct._unique_hidden_item_33 = value;
-        break;
-      case 34:
-        _struct._unique_hidden_item_34 = value;
-        break;
-      case 35:
-        _struct._unique_hidden_item_35 = value;
-        break;
-      case 36:
-        _struct._unique_hidden_item_36 = value;
-        break;
-      case 37:
-        _struct._unique_hidden_item_37 = value;
-        break;
-      case 38:
-        _struct._unique_hidden_item_38 = value;
-        break;
-      case 39:
-        _struct._unique_hidden_item_39 = value;
-        break;
-      case 40:
-        _struct._unique_hidden_item_40 = value;
-        break;
-      case 41:
-        _struct._unique_hidden_item_41 = value;
-        break;
-      case 42:
-        _struct._unique_hidden_item_42 = value;
-        break;
-      case 43:
-        _struct._unique_hidden_item_43 = value;
-        break;
-      case 44:
-        _struct._unique_hidden_item_44 = value;
-        break;
-      case 45:
-        _struct._unique_hidden_item_45 = value;
-        break;
-      case 46:
-        _struct._unique_hidden_item_46 = value;
-        break;
-      case 47:
-        _struct._unique_hidden_item_47 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
+  @ffi.Array.multi([48])
+  external ffi.Array<ffi.Uint8> hidden;
 }
 
 /// A pointer to a structure of the following type is passed as the first
diff --git a/test/large_integration_tests/large_test.dart b/test/large_integration_tests/large_test.dart
index 2815a1f..fc38fb3 100644
--- a/test/large_integration_tests/large_test.dart
+++ b/test/large_integration_tests/large_test.dart
@@ -23,7 +23,6 @@
 ${strings.description}: Bindings to LibClang.
 ${strings.output}: unused
 ${strings.compilerOpts}: -I${path.join('third_party', 'libclang', 'include')}
-${strings.arrayWorkaround}: true
 ${strings.comments}:
   ${strings.style}: ${strings.doxygen}
   ${strings.length}: ${strings.brief}
@@ -55,7 +54,6 @@
 ${strings.output}: unused
 ${strings.comments}:
   ${strings.length}: ${strings.full}
-${strings.arrayWorkaround}: true
 ${strings.headers}:
   ${strings.entryPoints}:
     - third_party/cjson_library/cJSON.h
@@ -78,7 +76,6 @@
 ${strings.name}: SQLite
 ${strings.description}: Bindings to SQLite.
 ${strings.output}: unused
-${strings.arrayWorkaround}: true
 ${strings.comments}:
   ${strings.style}: ${strings.any}
   ${strings.length}: ${strings.full}
diff --git a/test/native_test/config.yaml b/test/native_test/config.yaml
index 6c7b239..d68a62f 100644
--- a/test/native_test/config.yaml
+++ b/test/native_test/config.yaml
@@ -14,6 +14,5 @@
     - 'test/native_test/native_test.c'
   include-directives:
     - '**native_test.c'
-array-workaround: true
 
 compiler-opts: '-Wno-nullability-completeness'
diff --git a/test/native_test/native_test.dart b/test/native_test/native_test.dart
index 5e90a0b..08e1475 100644
--- a/test/native_test/native_test.dart
+++ b/test/native_test/native_test.dart
@@ -91,19 +91,20 @@
     test('double', () {
       expect(bindings.Function1Double(0), 42.0);
     });
-    test('array-workaround: Order of access', () {
+    test('Array Test: Order of access', () {
       final struct1 = bindings.getStruct1();
       var expectedValue = 1;
-      for (var i = 0; i < struct1.ref.data.dimensions[0]; i++) {
-        for (var j = 0; j < struct1.ref.data.dimensions[1]; j++) {
-          for (var k = 0; k < struct1.ref.data.dimensions[2]; k++) {
+      final dimensions = [3, 1, 2];
+      for (var i = 0; i < dimensions[0]; i++) {
+        for (var j = 0; j < dimensions[1]; j++) {
+          for (var k = 0; k < dimensions[2]; k++) {
             expect(struct1.ref.data[i][j][k], expectedValue);
             expectedValue++;
           }
         }
       }
     });
-    test('array-workaround: Range Errors', () {
+    test('Array Workaround: Range Errors', () {
       final struct1 = bindings.getStruct1();
       // Index (get) above range.
       expect(
diff --git a/test/native_test/native_test_bindings.dart b/test/native_test/native_test_bindings.dart
index f409db8..620771c 100644
--- a/test/native_test/native_test_bindings.dart
+++ b/test/native_test/native_test_bindings.dart
@@ -224,139 +224,8 @@
   @ffi.Int8()
   external int a;
 
-  @ffi.Int32()
-  external int _unique_data_item_0;
-  @ffi.Int32()
-  external int _unique_data_item_1;
-  @ffi.Int32()
-  external int _unique_data_item_2;
-  @ffi.Int32()
-  external int _unique_data_item_3;
-  @ffi.Int32()
-  external int _unique_data_item_4;
-  @ffi.Int32()
-  external int _unique_data_item_5;
-
-  /// Helper for array `data`.
-  ArrayHelper_Struct1_data_level0 get data =>
-      ArrayHelper_Struct1_data_level0(this, [3, 1, 2], 0, 0);
-}
-
-/// Helper for array `data` in struct `Struct1`.
-class ArrayHelper_Struct1_data_level0 {
-  final Struct1 _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_Struct1_data_level0(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ArrayHelper_Struct1_data_level1 operator [](int index) {
-    _checkBounds(index);
-    var offset = index;
-    for (var i = level + 1; i < dimensions.length; i++) {
-      offset *= dimensions[i];
-    }
-    return ArrayHelper_Struct1_data_level1(
-        _struct, dimensions, level + 1, _absoluteIndex + offset);
-  }
-}
-
-/// Helper for array `data` in struct `Struct1`.
-class ArrayHelper_Struct1_data_level1 {
-  final Struct1 _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_Struct1_data_level1(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  ArrayHelper_Struct1_data_level2 operator [](int index) {
-    _checkBounds(index);
-    var offset = index;
-    for (var i = level + 1; i < dimensions.length; i++) {
-      offset *= dimensions[i];
-    }
-    return ArrayHelper_Struct1_data_level2(
-        _struct, dimensions, level + 1, _absoluteIndex + offset);
-  }
-}
-
-/// Helper for array `data` in struct `Struct1`.
-class ArrayHelper_Struct1_data_level2 {
-  final Struct1 _struct;
-  final List<int> dimensions;
-  final int level;
-  final int _absoluteIndex;
-  int get length => dimensions[level];
-  ArrayHelper_Struct1_data_level2(
-      this._struct, this.dimensions, this.level, this._absoluteIndex);
-  void _checkBounds(int index) {
-    if (index >= length || index < 0) {
-      throw RangeError(
-          'Dimension $level: index not in range 0..$length exclusive.');
-    }
-  }
-
-  int operator [](int index) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        return _struct._unique_data_item_0;
-      case 1:
-        return _struct._unique_data_item_1;
-      case 2:
-        return _struct._unique_data_item_2;
-      case 3:
-        return _struct._unique_data_item_3;
-      case 4:
-        return _struct._unique_data_item_4;
-      case 5:
-        return _struct._unique_data_item_5;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
-
-  void operator []=(int index, int value) {
-    _checkBounds(index);
-    switch (_absoluteIndex + index) {
-      case 0:
-        _struct._unique_data_item_0 = value;
-        break;
-      case 1:
-        _struct._unique_data_item_1 = value;
-        break;
-      case 2:
-        _struct._unique_data_item_2 = value;
-        break;
-      case 3:
-        _struct._unique_data_item_3 = value;
-        break;
-      case 4:
-        _struct._unique_data_item_4 = value;
-        break;
-      case 5:
-        _struct._unique_data_item_5 = value;
-        break;
-      default:
-        throw Exception('Invalid Array Helper generated.');
-    }
-  }
+  @ffi.Array.multi([3, 1, 2])
+  external ffi.Array<ffi.Array<ffi.Array<ffi.Int32>>> data;
 }
 
 class Struct3 extends ffi.Struct {
diff --git a/tool/libclang_config.yaml b/tool/libclang_config.yaml
index 87f6bb0..b6af5e1 100644
--- a/tool/libclang_config.yaml
+++ b/tool/libclang_config.yaml
@@ -23,7 +23,6 @@
     - '**Index.h'
     - '**CXString.h'
 
-array-workaround: true
 preamble: |
   // Part of the LLVM Project, under the Apache License v2.0 with LLVM
   // Exceptions.