Added support for parsing macros and anonymous unnamed enums (#35)

closes #12, closes #50 

- Support for parsing macros and anonymous unnamed enums.
- These are generated as top-level constants.
- unnamed enums can be disabled by using `unnamed-enums: false`, default is `true`.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf34d90..9a32792 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 0.1.5
+- Added support for parsing macros and anonymous unnamed enums. These are generated as top level constants.
+
 # 0.1.4
 - Comments config now has a style and length sub keys - `style: doxygen(default) | any`, `length: brief | full(default)`, and can be disabled by passing `comments: false`.
 
diff --git a/README.md b/README.md
index 4bf4abd..604a1bc 100644
--- a/README.md
+++ b/README.md
@@ -63,21 +63,18 @@
 <thead>
   <tr>
     <th>Key</th>
-    <th>Required</th>
     <th>Explaination</th>
     <th>Example</th>
   </tr>
 </thead>
 <tbody>
   <tr>
-    <td>output</td>
-    <td>yes</td>
+    <td>output<br><i>(Required)</i></td>
     <td>Output path of the generated bindings.</td>
     <td><pre lang="yaml"><code>output: 'generated_bindings.dart'</code></pre></td>
   </tr>
   <tr>
-    <td>headers</td>
-    <td>yes</td>
+    <td>headers<br><i>(Required)</i></td>
     <td>List of C headers to use. Glob syntax is allowed.</td>
     <td><pre lang="yaml"><code>
 headers:
@@ -86,7 +83,6 @@
   </tr>
   <tr>
     <td>header-filter</td>
-    <td>no</td>
     <td>Name of headers to include/exclude.</td>
     <td><pre lang="yaml"><code>
 header-filter:
@@ -95,26 +91,22 @@
     - 'platform.h'</code></pre></td>
   </tr>
   <tr>
-    <td>name</td>
-    <td>prefer</td>
+    <td>name<br><i>(Prefer)</i></td>
     <td>Name of generated class.</td>
     <td><pre lang="yaml"><code>name: 'SQLite'</code></pre></td>
   </tr>
   <tr>
-    <td>description</td>
-    <td>prefer</td>
+    <td>description<br><i>(Prefer)</i></td>
     <td>Dart Doc for generated class.</td>
     <td><pre lang="yaml"><code>description: 'Bindings to SQLite'</code></pre></td>
   </tr>
   <tr>
     <td>compiler-opts</td>
-    <td>no</td>
     <td>Pass compiler options to clang.</td>
     <td><pre lang="yaml"><code>compiler-opts: '-I/usr/lib/llvm-9/include/'</code></pre></td>
   </tr>
   <tr>
-    <td>functions<br>structs<br>enums</td>
-    <td>no</td>
+    <td>functions<br>structs<br>enums<br>macros</td>
     <td>Filters for declarations.<br><b>Default: all are included</b></td>
     <td><pre lang="yaml"><code>
 functions:
@@ -132,7 +124,6 @@
   </tr>
   <tr>
     <td>array-workaround</td>
-    <td>no</td>
     <td>Should generate workaround for fixed arrays in Structs. See <a href="#array-workaround">Array Workaround</a><br>
       <b>Default: false</b>
     </td>
@@ -140,7 +131,6 @@
   </tr>
   <tr>
     <td>comments</td>
-    <td>no</td>
     <td>Extract documentation comments for declarations.<br>
     The style and length of the comments can be specified with the following options.<br>
     <i>style: doxygen(default) | any </i><br>
@@ -156,7 +146,6 @@
   </tr>
   <tr>
     <td>sort</td>
-    <td>no</td>
     <td>Sort the bindings according to name.<br>
       <b>Default: false</b>, i.e keep the order as in the source files.
     </td>
@@ -164,15 +153,20 @@
   </tr>
   <tr>
     <td>use-supported-typedefs</td>
-    <td>no</td>
     <td>Should automatically map typedefs, E.g uint8_t => Uint8, int16_t => Int16 etc.<br>
     <b>Default: true</b>
     </td>
     <td><pre lang="yaml"><code>use-supported-typedefs: true</code></pre></td>
   </tr>
+  <tr>
+    <td>unnamed-enums</td>
+    <td>Should generate constants for anonymous unnamed enums.<br>
+    <b>Default: true</b>
+    </td>
+    <td><pre lang="yaml"><code>unnamed-enums: true</code></pre></td>
+  </tr>
    <tr>
     <td>preamble</td>
-    <td>no</td>
     <td>Raw header of the file, pasted as-it-is.</td>
     <td><pre lang="yaml"><code>
 preamble: |
@@ -182,7 +176,6 @@
   </tr>
   <tr>
     <td>size-map</td>
-    <td>no</td>
     <td>Size of integers to use (in bytes).<br>
     <b>The defaults (see example) <i>may</i> not be portable on all OS.
     Do not change these unless absolutely sure.</b>
diff --git a/example/c_json/cjson_generated_bindings.dart b/example/c_json/cjson_generated_bindings.dart
index 25900b1..7c41b0f 100644
--- a/example/c_json/cjson_generated_bindings.dart
+++ b/example/c_json/cjson_generated_bindings.dart
@@ -1063,6 +1063,38 @@
   ffi.Pointer<ffi.NativeFunction<_typedefC_2>> free_fn;
 }
 
+const int CJSON_VERSION_MAJOR = 1;
+
+const int CJSON_VERSION_MINOR = 7;
+
+const int CJSON_VERSION_PATCH = 12;
+
+const int cJSON_Invalid = 0;
+
+const int cJSON_False = 1;
+
+const int cJSON_True = 2;
+
+const int cJSON_NULL = 4;
+
+const int cJSON_Number = 8;
+
+const int cJSON_String = 16;
+
+const int cJSON_Array = 32;
+
+const int cJSON_Object = 64;
+
+const int cJSON_Raw = 128;
+
+const int cJSON_IsReference = 256;
+
+const int cJSON_StringIsConst = 512;
+
+const int CJSON_NESTING_LIMIT = 1000;
+
+const double CJSON_DOUBLE_PRECISION = 1e-16;
+
 typedef _c_cJSON_Version = ffi.Pointer<ffi.Int8> Function();
 
 typedef _dart_cJSON_Version = ffi.Pointer<ffi.Int8> Function();
diff --git a/example/libclang-example/generated_bindings.dart b/example/libclang-example/generated_bindings.dart
index bd5b8ce..6148331 100644
--- a/example/libclang-example/generated_bindings.dart
+++ b/example/libclang-example/generated_bindings.dart
@@ -3293,6 +3293,14 @@
   ffi.Pointer<ffi.NativeFunction<_typedefC_10>> indexEntityReference;
 }
 
+const int CINDEX_VERSION_MAJOR = 0;
+
+const int CINDEX_VERSION_MINOR = 59;
+
+const int CINDEX_VERSION = 59;
+
+const String CINDEX_VERSION_STRING = '0.59';
+
 typedef _c_clang_disposeStringSet = ffi.Void Function(
   ffi.Pointer<CXStringSet> set_1,
 );
diff --git a/lib/src/clang_library/wrapper.c b/lib/src/clang_library/wrapper.c
index 978b7e7..c43c7f6 100644
--- a/lib/src/clang_library/wrapper.c
+++ b/lib/src/clang_library/wrapper.c
@@ -333,4 +333,29 @@
     return ptrToCXType(clang_getArrayElementType(*cxtype));
 }
 
+unsigned clang_Cursor_isMacroFunctionLike_wrap(CXCursor *cursor)
+{
+    return clang_Cursor_isMacroFunctionLike(*cursor);
+}
+
+unsigned clang_Cursor_isMacroBuiltin_wrap(CXCursor *cursor)
+{
+    return clang_Cursor_isMacroBuiltin(*cursor);
+}
+
+CXEvalResult clang_Cursor_Evaluate_wrap(CXCursor *cursor)
+{
+    return clang_Cursor_Evaluate(*cursor);
+}
+
+unsigned clang_Cursor_isAnonymous_wrap(CXCursor *cursor)
+{
+    return clang_Cursor_isAnonymous(*cursor);
+}
+
+unsigned clang_Cursor_isAnonymousRecordDecl_wrap(CXCursor *cursor)
+{
+    return clang_Cursor_isAnonymousRecordDecl(*cursor);
+}
+
 // END ===== WRAPPER FUNCTIONS =====================
diff --git a/lib/src/clang_library/wrapper.def b/lib/src/clang_library/wrapper.def
index 5a10727..c82231f 100644
--- a/lib/src/clang_library/wrapper.def
+++ b/lib/src/clang_library/wrapper.def
@@ -353,3 +353,8 @@
 clang_getFileName_wrap
 clang_getNumElements_wrap
 clang_getArrayElementType_wrap
+clang_Cursor_isMacroFunctionLike_wrap
+clang_Cursor_isMacroBuiltin_wrap
+clang_Cursor_Evaluate_wrap
+clang_Cursor_isAnonymous_wrap
+clang_Cursor_isAnonymousRecordDecl_wrap
diff --git a/lib/src/code_generator/constant.dart b/lib/src/code_generator/constant.dart
index 6af8a6d..b5521ad 100644
--- a/lib/src/code_generator/constant.dart
+++ b/lib/src/code_generator/constant.dart
@@ -7,7 +7,6 @@
 
 import 'binding.dart';
 import 'binding_string.dart';
-import 'type.dart';
 import 'utils.dart';
 import 'writer.dart';
 
@@ -23,7 +22,8 @@
 /// const int name = 10;
 /// ```
 class Constant extends NoLookUpBinding {
-  final Type type;
+  /// The rawType is pasted as it is. E.g 'int', 'String', 'double'
+  final String rawType;
 
   /// The rawValue is pasted as it is.
   ///
@@ -34,7 +34,7 @@
     String originalName,
     @required String name,
     String dartDoc,
-    @required this.type,
+    @required this.rawType,
     @required this.rawValue,
   }) : super(originalName: originalName ?? name, name: name, dartDoc: dartDoc);
 
@@ -47,7 +47,7 @@
       s.write(makeDartDoc(dartDoc));
     }
 
-    s.write('const ${type.getDartType(w)} $constantName = $rawValue;\n\n');
+    s.write('const ${rawType} $constantName = $rawValue;\n\n');
 
     return BindingString(
         type: BindingStringType.constant, string: s.toString());
diff --git a/lib/src/config_provider/config.dart b/lib/src/config_provider/config.dart
index 0f872f9..eb75b80 100644
--- a/lib/src/config_provider/config.dart
+++ b/lib/src/config_provider/config.dart
@@ -43,6 +43,9 @@
   /// Declaration config for Enums.
   Declaration enumClassDecl;
 
+  /// Declaration config for Enums.
+  Declaration macroDecl;
+
   /// If generated bindings should be sorted alphabetically.
   bool sort;
 
@@ -58,6 +61,9 @@
   /// members removed.
   bool arrayWorkaround;
 
+  /// If constants should be generated for unnamed enums.
+  bool unnamedEnums;
+
   /// Name of the wrapper class.
   String wrapperName;
 
@@ -189,6 +195,16 @@
           enumClassDecl = result as Declaration;
         },
       ),
+      strings.macros: Specification<Declaration>(
+        description: 'Filter for macros',
+        requirement: Requirement.no,
+        validator: declarationConfigValidator,
+        extractor: declarationConfigExtractor,
+        defaultValue: () => Declaration(),
+        extractedResult: (dynamic result) {
+          macroDecl = result as Declaration;
+        },
+      ),
       strings.sizemap: Specification<Map<int, SupportedNativeType>>(
         description: 'map of types: byte size in int',
         validator: sizemapValidator,
@@ -238,6 +254,14 @@
         defaultValue: () => false,
         extractedResult: (dynamic result) => arrayWorkaround = result as bool,
       ),
+      strings.unnamedEnums: Specification<bool>(
+        description: 'whether or not to generate constants for unnamed enums.',
+        requirement: Requirement.no,
+        validator: booleanValidator,
+        extractor: booleanExtractor,
+        defaultValue: () => true,
+        extractedResult: (dynamic result) => unnamedEnums = result as bool,
+      ),
       strings.name: Specification<String>(
         description: 'Name of the wrapper class',
         requirement: Requirement.prefer,
diff --git a/lib/src/header_parser/clang_bindings/clang_bindings.dart b/lib/src/header_parser/clang_bindings/clang_bindings.dart
index afdf041..61fe3d8 100644
--- a/lib/src/header_parser/clang_bindings/clang_bindings.dart
+++ b/lib/src/header_parser/clang_bindings/clang_bindings.dart
@@ -174,6 +174,97 @@
 
   _dart_clang_disposeTranslationUnit _clang_disposeTranslationUnit;
 
+  /// Returns the kind of the evaluated result.
+  int clang_EvalResult_getKind(
+    ffi.Pointer<ffi.Void> E,
+  ) {
+    _clang_EvalResult_getKind ??= _dylib.lookupFunction<
+        _c_clang_EvalResult_getKind,
+        _dart_clang_EvalResult_getKind>('clang_EvalResult_getKind');
+    return _clang_EvalResult_getKind(
+      E,
+    );
+  }
+
+  _dart_clang_EvalResult_getKind _clang_EvalResult_getKind;
+
+  /// Returns the evaluation result as integer if the
+  /// kind is Int.
+  int clang_EvalResult_getAsInt(
+    ffi.Pointer<ffi.Void> E,
+  ) {
+    _clang_EvalResult_getAsInt ??= _dylib.lookupFunction<
+        _c_clang_EvalResult_getAsInt,
+        _dart_clang_EvalResult_getAsInt>('clang_EvalResult_getAsInt');
+    return _clang_EvalResult_getAsInt(
+      E,
+    );
+  }
+
+  _dart_clang_EvalResult_getAsInt _clang_EvalResult_getAsInt;
+
+  /// Returns the evaluation result as a long long integer if the
+  /// kind is Int. This prevents overflows that may happen if the result is
+  /// returned with clang_EvalResult_getAsInt.
+  int clang_EvalResult_getAsLongLong(
+    ffi.Pointer<ffi.Void> E,
+  ) {
+    _clang_EvalResult_getAsLongLong ??= _dylib.lookupFunction<
+        _c_clang_EvalResult_getAsLongLong,
+        _dart_clang_EvalResult_getAsLongLong>('clang_EvalResult_getAsLongLong');
+    return _clang_EvalResult_getAsLongLong(
+      E,
+    );
+  }
+
+  _dart_clang_EvalResult_getAsLongLong _clang_EvalResult_getAsLongLong;
+
+  /// Returns the evaluation result as double if the
+  /// kind is double.
+  double clang_EvalResult_getAsDouble(
+    ffi.Pointer<ffi.Void> E,
+  ) {
+    _clang_EvalResult_getAsDouble ??= _dylib.lookupFunction<
+        _c_clang_EvalResult_getAsDouble,
+        _dart_clang_EvalResult_getAsDouble>('clang_EvalResult_getAsDouble');
+    return _clang_EvalResult_getAsDouble(
+      E,
+    );
+  }
+
+  _dart_clang_EvalResult_getAsDouble _clang_EvalResult_getAsDouble;
+
+  /// Returns the evaluation result as a constant string if the
+  /// kind is other than Int or float. User must not free this pointer,
+  /// instead call clang_EvalResult_dispose on the CXEvalResult returned
+  /// by clang_Cursor_Evaluate.
+  ffi.Pointer<ffi.Int8> clang_EvalResult_getAsStr(
+    ffi.Pointer<ffi.Void> E,
+  ) {
+    _clang_EvalResult_getAsStr ??= _dylib.lookupFunction<
+        _c_clang_EvalResult_getAsStr,
+        _dart_clang_EvalResult_getAsStr>('clang_EvalResult_getAsStr');
+    return _clang_EvalResult_getAsStr(
+      E,
+    );
+  }
+
+  _dart_clang_EvalResult_getAsStr _clang_EvalResult_getAsStr;
+
+  /// Disposes the created Eval memory.
+  void clang_EvalResult_dispose(
+    ffi.Pointer<ffi.Void> E,
+  ) {
+    _clang_EvalResult_dispose ??= _dylib.lookupFunction<
+        _c_clang_EvalResult_dispose,
+        _dart_clang_EvalResult_dispose>('clang_EvalResult_dispose');
+    return _clang_EvalResult_dispose(
+      E,
+    );
+  }
+
+  _dart_clang_EvalResult_dispose _clang_EvalResult_dispose;
+
   ffi.Pointer<ffi.Int8> clang_getCString_wrap(
     ffi.Pointer<CXString> string,
   ) {
@@ -612,6 +703,76 @@
   }
 
   _dart_clang_getArrayElementType_wrap _clang_getArrayElementType_wrap;
+
+  int clang_Cursor_isMacroFunctionLike_wrap(
+    ffi.Pointer<CXCursor> cursor,
+  ) {
+    _clang_Cursor_isMacroFunctionLike_wrap ??= _dylib.lookupFunction<
+            _c_clang_Cursor_isMacroFunctionLike_wrap,
+            _dart_clang_Cursor_isMacroFunctionLike_wrap>(
+        'clang_Cursor_isMacroFunctionLike_wrap');
+    return _clang_Cursor_isMacroFunctionLike_wrap(
+      cursor,
+    );
+  }
+
+  _dart_clang_Cursor_isMacroFunctionLike_wrap
+      _clang_Cursor_isMacroFunctionLike_wrap;
+
+  int clang_Cursor_isMacroBuiltin_wrap(
+    ffi.Pointer<CXCursor> cursor,
+  ) {
+    _clang_Cursor_isMacroBuiltin_wrap ??= _dylib.lookupFunction<
+            _c_clang_Cursor_isMacroBuiltin_wrap,
+            _dart_clang_Cursor_isMacroBuiltin_wrap>(
+        'clang_Cursor_isMacroBuiltin_wrap');
+    return _clang_Cursor_isMacroBuiltin_wrap(
+      cursor,
+    );
+  }
+
+  _dart_clang_Cursor_isMacroBuiltin_wrap _clang_Cursor_isMacroBuiltin_wrap;
+
+  ffi.Pointer<ffi.Void> clang_Cursor_Evaluate_wrap(
+    ffi.Pointer<CXCursor> cursor,
+  ) {
+    _clang_Cursor_Evaluate_wrap ??= _dylib.lookupFunction<
+        _c_clang_Cursor_Evaluate_wrap,
+        _dart_clang_Cursor_Evaluate_wrap>('clang_Cursor_Evaluate_wrap');
+    return _clang_Cursor_Evaluate_wrap(
+      cursor,
+    );
+  }
+
+  _dart_clang_Cursor_Evaluate_wrap _clang_Cursor_Evaluate_wrap;
+
+  int clang_Cursor_isAnonymous_wrap(
+    ffi.Pointer<CXCursor> cursor,
+  ) {
+    _clang_Cursor_isAnonymous_wrap ??= _dylib.lookupFunction<
+        _c_clang_Cursor_isAnonymous_wrap,
+        _dart_clang_Cursor_isAnonymous_wrap>('clang_Cursor_isAnonymous_wrap');
+    return _clang_Cursor_isAnonymous_wrap(
+      cursor,
+    );
+  }
+
+  _dart_clang_Cursor_isAnonymous_wrap _clang_Cursor_isAnonymous_wrap;
+
+  int clang_Cursor_isAnonymousRecordDecl_wrap(
+    ffi.Pointer<CXCursor> cursor,
+  ) {
+    _clang_Cursor_isAnonymousRecordDecl_wrap ??= _dylib.lookupFunction<
+            _c_clang_Cursor_isAnonymousRecordDecl_wrap,
+            _dart_clang_Cursor_isAnonymousRecordDecl_wrap>(
+        'clang_Cursor_isAnonymousRecordDecl_wrap');
+    return _clang_Cursor_isAnonymousRecordDecl_wrap(
+      cursor,
+    );
+  }
+
+  _dart_clang_Cursor_isAnonymousRecordDecl_wrap
+      _clang_Cursor_isAnonymousRecordDecl_wrap;
 }
 
 /// A character string.
@@ -2012,6 +2173,24 @@
   static const int CXChildVisit_Recurse = 2;
 }
 
+abstract class CXEvalResultKind {
+  static const int CXEval_Int = 1;
+  static const int CXEval_Float = 2;
+  static const int CXEval_ObjCStrLiteral = 3;
+  static const int CXEval_StrLiteral = 4;
+  static const int CXEval_CFStr = 5;
+  static const int CXEval_Other = 6;
+  static const int CXEval_UnExposed = 0;
+}
+
+const int CINDEX_VERSION_MAJOR = 0;
+
+const int CINDEX_VERSION_MINOR = 59;
+
+const int CINDEX_VERSION = 59;
+
+const String CINDEX_VERSION_STRING = '0.59';
+
 typedef _c_clang_createIndex = ffi.Pointer<ffi.Void> Function(
   ffi.Int32 excludeDeclarationsFromPCH,
   ffi.Int32 displayDiagnostics,
@@ -2086,6 +2265,54 @@
   ffi.Pointer<CXTranslationUnitImpl> arg0,
 );
 
+typedef _c_clang_EvalResult_getKind = ffi.Int32 Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
+typedef _dart_clang_EvalResult_getKind = int Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
+typedef _c_clang_EvalResult_getAsInt = ffi.Int32 Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
+typedef _dart_clang_EvalResult_getAsInt = int Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
+typedef _c_clang_EvalResult_getAsLongLong = ffi.Int64 Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
+typedef _dart_clang_EvalResult_getAsLongLong = int Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
+typedef _c_clang_EvalResult_getAsDouble = ffi.Double Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
+typedef _dart_clang_EvalResult_getAsDouble = double Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
+typedef _c_clang_EvalResult_getAsStr = ffi.Pointer<ffi.Int8> Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
+typedef _dart_clang_EvalResult_getAsStr = ffi.Pointer<ffi.Int8> Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
+typedef _c_clang_EvalResult_dispose = ffi.Void Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
+typedef _dart_clang_EvalResult_dispose = void Function(
+  ffi.Pointer<ffi.Void> E,
+);
+
 typedef _c_clang_getCString_wrap = ffi.Pointer<ffi.Int8> Function(
   ffi.Pointer<CXString> string,
 );
@@ -2369,3 +2596,43 @@
 typedef _dart_clang_getArrayElementType_wrap = ffi.Pointer<CXType> Function(
   ffi.Pointer<CXType> cxtype,
 );
+
+typedef _c_clang_Cursor_isMacroFunctionLike_wrap = ffi.Uint32 Function(
+  ffi.Pointer<CXCursor> cursor,
+);
+
+typedef _dart_clang_Cursor_isMacroFunctionLike_wrap = int Function(
+  ffi.Pointer<CXCursor> cursor,
+);
+
+typedef _c_clang_Cursor_isMacroBuiltin_wrap = ffi.Uint32 Function(
+  ffi.Pointer<CXCursor> cursor,
+);
+
+typedef _dart_clang_Cursor_isMacroBuiltin_wrap = int Function(
+  ffi.Pointer<CXCursor> cursor,
+);
+
+typedef _c_clang_Cursor_Evaluate_wrap = ffi.Pointer<ffi.Void> Function(
+  ffi.Pointer<CXCursor> cursor,
+);
+
+typedef _dart_clang_Cursor_Evaluate_wrap = ffi.Pointer<ffi.Void> Function(
+  ffi.Pointer<CXCursor> cursor,
+);
+
+typedef _c_clang_Cursor_isAnonymous_wrap = ffi.Uint32 Function(
+  ffi.Pointer<CXCursor> cursor,
+);
+
+typedef _dart_clang_Cursor_isAnonymous_wrap = int Function(
+  ffi.Pointer<CXCursor> cursor,
+);
+
+typedef _c_clang_Cursor_isAnonymousRecordDecl_wrap = ffi.Uint32 Function(
+  ffi.Pointer<CXCursor> cursor,
+);
+
+typedef _dart_clang_Cursor_isAnonymousRecordDecl_wrap = int Function(
+  ffi.Pointer<CXCursor> cursor,
+);
diff --git a/lib/src/header_parser/includer.dart b/lib/src/header_parser/includer.dart
index f0ab13c..b00fa4f 100644
--- a/lib/src/header_parser/includer.dart
+++ b/lib/src/header_parser/includer.dart
@@ -13,6 +13,7 @@
 Map<String, Struc> _structs = {};
 Map<String, Func> _functions = {};
 Map<String, EnumClass> _enumClass = {};
+Map<String, String> _macros = {};
 
 bool shouldIncludeStruct(String name) {
   if (_structs.containsKey(name) || name == '') {
@@ -47,9 +48,24 @@
   }
 }
 
+bool shouldIncludeMacro(String name) {
+  if (_macros.containsKey(name) || name == '') {
+    return false;
+  } else if (config.macroDecl == null || config.macroDecl.shouldInclude(name)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
 /// True if a cursor should be included based on header-filter, use for root
 /// declarations.
 bool shouldIncludeRootCursor(String sourceFile) {
+  // Handle null in case of system headers or macros.
+  if (sourceFile == null) {
+    return false;
+  }
+
   final name = p.basename(sourceFile);
 
   if (config.headerFilter.excludedInclusionHeaders.contains(name)) {
@@ -103,3 +119,15 @@
 EnumClass getSeenEnumClass(String originalName) {
   return _enumClass[originalName];
 }
+
+bool isSeenMacro(String originalName) {
+  return _macros.containsKey(originalName);
+}
+
+void addMacroToSeen(String originalName, String macro) {
+  _macros[originalName] = macro;
+}
+
+String getSeenMacro(String originalName) {
+  return _macros[originalName];
+}
diff --git a/lib/src/header_parser/parser.dart b/lib/src/header_parser/parser.dart
index bb171b3..6730d22 100644
--- a/lib/src/header_parser/parser.dart
+++ b/lib/src/header_parser/parser.dart
@@ -7,8 +7,10 @@
 import 'package:ffi/ffi.dart';
 import 'package:ffigen/src/code_generator.dart';
 import 'package:ffigen/src/config_provider.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/macro_parser.dart';
 import 'package:ffigen/src/config_provider/config_types.dart';
 import 'package:ffigen/src/find_resource.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart';
 import 'package:ffigen/src/header_parser/translation_unit_parser.dart';
 import 'package:ffigen/src/strings.dart' as strings;
 import 'package:logging/logging.dart';
@@ -96,7 +98,9 @@
       cmdLen,
       nullptr,
       0,
-      clang_types.CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies,
+      clang_types.CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies |
+          clang_types.CXTranslationUnit_Flags
+              .CXTranslationUnit_DetailedPreprocessingRecord,
     );
 
     if (tu == nullptr) {
@@ -116,6 +120,12 @@
     clang.clang_disposeTranslationUnit(tu);
   }
 
+  // Add all saved unnamed enums.
+  bindings.addAll(getSavedUnNamedEnums());
+
+  // Parse all saved macros.
+  bindings.addAll(parseSavedMacros());
+
   if (config.compilerOpts != null) {
     clangCmdArgs.dispose(config.compilerOpts.length);
   }
diff --git a/lib/src/header_parser/sub_parsers/enumdecl_parser.dart b/lib/src/header_parser/sub_parsers/enumdecl_parser.dart
index 8cba1c9..293fa22 100644
--- a/lib/src/header_parser/sub_parsers/enumdecl_parser.dart
+++ b/lib/src/header_parser/sub_parsers/enumdecl_parser.dart
@@ -6,6 +6,7 @@
 
 import 'package:ffigen/src/code_generator.dart';
 import 'package:ffigen/src/header_parser/data.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart';
 import 'package:logging/logging.dart';
 
 import '../clang_bindings/clang_bindings.dart' as clang_types;
@@ -31,10 +32,16 @@
   String name,
 }) {
   _stack.push(_ParsedEnum());
-
   final enumName = name ?? cursor.spelling();
   if (enumName == '') {
-    _logger.finest('unnamed enum declaration');
+    // Save this unnamed enum if it is anonymous (therefore not in a typedef).
+    if (config.unnamedEnums &&
+        clang.clang_Cursor_isAnonymous_wrap(cursor) != 0) {
+      _logger.fine('Saving anonymous enum.');
+      saveUnNamedEnum(cursor);
+    } else {
+      _logger.fine('Unnamed enum inside a typedef.');
+    }
   } else if (shouldIncludeEnumClass(enumName) && !isSeenEnumClass(enumName)) {
     _logger.fine('++++ Adding Enum: ${cursor.completeStringRepr()}');
     _stack.top.enumClass = EnumClass(
diff --git a/lib/src/header_parser/sub_parsers/macro_parser.dart b/lib/src/header_parser/sub_parsers/macro_parser.dart
new file mode 100644
index 0000000..4da1b04
--- /dev/null
+++ b/lib/src/header_parser/sub_parsers/macro_parser.dart
@@ -0,0 +1,238 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:path/path.dart' as p;
+import 'package:ffi/ffi.dart';
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/data.dart';
+import 'package:ffigen/src/header_parser/includer.dart';
+import 'package:logging/logging.dart';
+
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../data.dart';
+import '../utils.dart';
+
+var _logger = Logger('ffigen.header_parser.macro_parser');
+
+/// Saved macros, Key: prefixedName, Value originalName.
+final _savedMacros = <String, String>{};
+
+/// Adds a macro definition to be parsed later.
+void saveMacroDefinition(Pointer<clang_types.CXCursor> cursor) {
+  final originalMacroName = cursor.spelling();
+  if (shouldIncludeMacro(originalMacroName) &&
+      !isSeenMacro(originalMacroName) &&
+      clang.clang_Cursor_isMacroBuiltin_wrap(cursor) == 0 &&
+      clang.clang_Cursor_isMacroFunctionLike_wrap(cursor) == 0) {
+    // Parse macro only if it's not builtin or function-like.
+    _logger.fine(
+        "++++ Saved Macro '$originalMacroName' for later : ${cursor.completeStringRepr()}");
+    final prefixedName = config.macroDecl.getPrefixedName(originalMacroName);
+    addMacroToSeen(originalMacroName, prefixedName);
+    _saveMacro(prefixedName, originalMacroName);
+  }
+}
+
+/// Saves a macro to be parsed later.
+///
+/// Macros are parsed later in [parseSavedMacros()].
+void _saveMacro(String name, String originalName) {
+  _savedMacros[name] = originalName;
+}
+
+List<Constant> _bindings;
+
+/// Macros cannot be parsed directly, so we create a new `.hpp` file in which
+/// they are assigned to a variable after which their value can be determined
+/// by evaluating the value of the variable.
+List<Constant> parseSavedMacros() {
+  _bindings = [];
+
+  if (_savedMacros.keys.isEmpty) {
+    return _bindings;
+  }
+
+  // Create a file for parsing macros;
+  final file = createFileForMacros();
+
+  final index = clang.clang_createIndex(0, 0);
+  Pointer<Pointer<Utf8>> clangCmdArgs = nullptr;
+  var cmdLen = 0;
+  if (config.compilerOpts != null) {
+    clangCmdArgs = createDynamicStringArray(config.compilerOpts);
+    cmdLen = config.compilerOpts.length;
+  }
+  final tu = clang.clang_parseTranslationUnit(
+    index,
+    Utf8.toUtf8(file.path).cast(),
+    clangCmdArgs.cast(),
+    cmdLen,
+    nullptr,
+    0,
+    clang_types.CXTranslationUnit_Flags.CXTranslationUnit_KeepGoing,
+  );
+
+  if (tu == nullptr) {
+    _logger.severe('Unable to parse Macros.');
+  } else {
+    final rootCursor = clang.clang_getTranslationUnitCursor_wrap(tu);
+
+    final resultCode = clang.clang_visitChildren_wrap(
+      rootCursor,
+      Pointer.fromFunction(_macroVariablevisitor,
+          clang_types.CXChildVisitResult.CXChildVisit_Break),
+      uid,
+    );
+
+    visitChildrenResultChecker(resultCode);
+    rootCursor.dispose();
+  }
+
+  clang.clang_disposeTranslationUnit(tu);
+  clang.clang_disposeIndex(index);
+  // Delete the temp file created for macros.
+  file.deleteSync();
+
+  return _bindings;
+}
+
+/// Child visitor invoked on translationUnitCursor for parsing macroVariables.
+int _macroVariablevisitor(Pointer<clang_types.CXCursor> cursor,
+    Pointer<clang_types.CXCursor> parent, Pointer<Void> clientData) {
+  Constant constant;
+  try {
+    if (isFromGeneratedFile(cursor) &&
+        _macroVarNames.contains(cursor.spelling()) &&
+        cursor.kind() == clang_types.CXCursorKind.CXCursor_VarDecl) {
+      final e = clang.clang_Cursor_Evaluate_wrap(cursor);
+      final k = clang.clang_EvalResult_getKind(e);
+      _logger.fine('macroVariablevisitor: ${cursor.completeStringRepr()}');
+
+      /// Get macro name, the variable name starts with '<macro-name>_'.
+      final macroName = MacroVariableString.decode(cursor.spelling());
+      switch (k) {
+        case clang_types.CXEvalResultKind.CXEval_Int:
+          constant = Constant(
+            originalName: _savedMacros[macroName],
+            name: macroName,
+            rawType: 'int',
+            rawValue: clang.clang_EvalResult_getAsLongLong(e).toString(),
+          );
+          break;
+        case clang_types.CXEvalResultKind.CXEval_Float:
+          constant = Constant(
+            originalName: _savedMacros[macroName],
+            name: macroName,
+            rawType: 'double',
+            rawValue: clang.clang_EvalResult_getAsDouble(e).toString(),
+          );
+          break;
+        case clang_types.CXEvalResultKind.CXEval_StrLiteral:
+          constant = Constant(
+            originalName: _savedMacros[macroName],
+            name: macroName,
+            rawType: 'String',
+            rawValue:
+                "'${Utf8.fromUtf8(clang.clang_EvalResult_getAsStr(e).cast())}'",
+          );
+          break;
+      }
+      clang.clang_EvalResult_dispose(e);
+
+      if (constant != null) {
+        _bindings.add(constant);
+      }
+    }
+    cursor.dispose();
+    parent.dispose();
+  } catch (e, s) {
+    _logger.severe(e);
+    _logger.severe(s);
+    rethrow;
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
+
+/// Returns true if cursor is from generated file.
+bool isFromGeneratedFile(Pointer<clang_types.CXCursor> cursor) {
+  final s = cursor.sourceFileName();
+  if (s == null || s.isEmpty) {
+    return false;
+  } else {
+    return p.basename(s) == _generatedFileBaseName;
+  }
+}
+
+/// Base name of generated file.
+String _generatedFileBaseName;
+
+/// Generated macro variable names.
+///
+/// Used to determine if macro should be included in bindings or not.
+Set<String> _macroVarNames = {};
+
+/// Creates a temporary file for parsing macros in current directory.
+File createFileForMacros() {
+  final fileNameBase = 'temp_for_macros';
+  final fileExt = 'hpp';
+
+  // Find a filename which doesn't already exist.
+  var file = File('$fileNameBase.$fileExt');
+  var i = 0;
+  while (file.existsSync()) {
+    i++;
+    file = File('${fileNameBase.split('.')[0]}_$i.$fileExt');
+  }
+
+  // Create file.
+  file.createSync();
+  // Save generted name.
+  _generatedFileBaseName = p.basename(file.path);
+
+  // Write file contents.
+  final sb = StringBuffer();
+  for (final h in config.headers) {
+    sb.writeln('#include "$h"');
+  }
+
+  _macroVarNames = {};
+  for (final prefixedMacroName in _savedMacros.keys) {
+    // Write macro.
+    final macroVarName = MacroVariableString.encode(prefixedMacroName);
+    sb.writeln('auto ${macroVarName} = ${_savedMacros[prefixedMacroName]};');
+    // Add to _macroVarNames.
+    _macroVarNames.add(macroVarName);
+  }
+  final macroFileContent = sb.toString();
+  // Log this generated file for debugging purpose.
+  // We use the finest log because this file may be very big.
+  _logger.finest('=====FILE FOR MACROS====');
+  _logger.finest(macroFileContent);
+  _logger.finest('========================');
+
+  file.writeAsStringSync(macroFileContent);
+  return file;
+}
+
+/// Deals with encoding/decoding name of the variable generated for a Macro.
+class MacroVariableString {
+  static String encode(String s) {
+    return '_${s.length}_${s}_generated_macro_variable';
+  }
+
+  static String decode(String s) {
+    // Remove underscore.
+    s = s.substring(1);
+    final intReg = RegExp('[0-9]+');
+    final lengthEnd = intReg.matchAsPrefix(s).end;
+    final len = int.parse(s.substring(0, lengthEnd));
+
+    // Name starts after an unerscore.
+    final nameStart = lengthEnd + 1;
+    return s.substring(nameStart, nameStart + len);
+  }
+}
diff --git a/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart b/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart
new file mode 100644
index 0000000..8f8487b
--- /dev/null
+++ b/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/data.dart';
+import 'package:logging/logging.dart';
+
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../data.dart';
+import '../utils.dart';
+
+var _logger = Logger('ffigen.header_parser.unnamed_enumdecl_parser');
+
+List<Constant> _constants = [];
+
+List<Constant> getSavedUnNamedEnums() => _constants;
+
+/// Saves unnamed enums.
+void saveUnNamedEnum(Pointer<clang_types.CXCursor> cursor) {
+  final resultCode = clang.clang_visitChildren_wrap(
+    cursor,
+    Pointer.fromFunction(_unnamedenumCursorVisitor,
+        clang_types.CXChildVisitResult.CXChildVisit_Break),
+    uid,
+  );
+
+  visitChildrenResultChecker(resultCode);
+}
+
+/// Visitor for a enum cursor [clang.CXCursorKind.CXCursor_EnumDecl].
+///
+/// Invoked on every enum directly under rootCursor.
+/// Used for for extracting enum values.
+int _unnamedenumCursorVisitor(Pointer<clang_types.CXCursor> cursor,
+    Pointer<clang_types.CXCursor> parent, Pointer<Void> clientData) {
+  try {
+    _logger
+        .finest('  unnamedenumCursorVisitor: ${cursor.completeStringRepr()}');
+    switch (clang.clang_getCursorKind_wrap(cursor)) {
+      case clang_types.CXCursorKind.CXCursor_EnumConstantDecl:
+        _addUnNamedEnumConstant(cursor);
+        break;
+      default:
+        _logger.severe('Invalid enum constant.');
+    }
+    cursor.dispose();
+    parent.dispose();
+  } catch (e, s) {
+    _logger.severe(e);
+    _logger.severe(s);
+    rethrow;
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
+
+/// Adds the parameter to func in [functiondecl_parser.dart].
+void _addUnNamedEnumConstant(Pointer<clang_types.CXCursor> cursor) {
+  _constants.add(
+    Constant(
+      name: cursor.spelling(),
+      rawType: 'int',
+      rawValue: clang.clang_getEnumConstantDeclValue_wrap(cursor).toString(),
+    ),
+  );
+}
diff --git a/lib/src/header_parser/translation_unit_parser.dart b/lib/src/header_parser/translation_unit_parser.dart
index 987254e..4723fe4 100644
--- a/lib/src/header_parser/translation_unit_parser.dart
+++ b/lib/src/header_parser/translation_unit_parser.dart
@@ -5,6 +5,7 @@
 import 'dart:ffi';
 
 import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/macro_parser.dart';
 import 'package:logging/logging.dart';
 
 import 'clang_bindings/clang_bindings.dart' as clang_types;
@@ -55,6 +56,9 @@
         case clang_types.CXCursorKind.CXCursor_EnumDecl:
           addToBindings(parseEnumDeclaration(cursor));
           break;
+        case clang_types.CXCursorKind.CXCursor_MacroDefinition:
+          saveMacroDefinition(cursor);
+          break;
         default:
           _logger.finer('rootCursorVisitor: CursorKind not implemented');
       }
diff --git a/lib/src/strings.dart b/lib/src/strings.dart
index 963f84c..cfa1f5d 100644
--- a/lib/src/strings.dart
+++ b/lib/src/strings.dart
@@ -7,7 +7,7 @@
     as clang;
 
 // This version must be updated whenever we update the libclang wrapper.
-const dylibVersion = 'v1';
+const dylibVersion = 'v2';
 
 /// Name of the dynamic library file according to current platform.
 String get dylibFileName {
@@ -36,6 +36,7 @@
 const functions = 'functions';
 const structs = 'structs';
 const enums = 'enums';
+const macros = 'macros';
 
 // Sub-fields of Declarations.
 const include = 'include';
@@ -82,6 +83,7 @@
 const useSupportedTypedefs = 'use-supported-typedefs';
 const warnWhenRemoving = 'warn-when-removing';
 const arrayWorkaround = 'array-workaround';
+const unnamedEnums = 'unnamed-enums';
 
 const comments = 'comments';
 // Sub-fields of comments
diff --git a/pubspec.yaml b/pubspec.yaml
index e4f34cf..fb8ad12 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: 0.1.4
+version: 0.1.5
 homepage: https://github.com/dart-lang/ffigen
 description: Experimental generator for FFI bindings, using LibClang to parse C/C++ header files.
 
diff --git a/test/code_generator_test.dart b/test/code_generator_test.dart
index a67f41e..47c0ac7 100644
--- a/test/code_generator_test.dart
+++ b/test/code_generator_test.dart
@@ -471,16 +471,12 @@
         bindings: [
           Constant(
             name: 'test1',
-            type: Type.nativeType(
-              SupportedNativeType.Int32,
-            ),
+            rawType: 'int',
             rawValue: '20',
           ),
           Constant(
             name: 'test2',
-            type: Type.nativeType(
-              SupportedNativeType.Float,
-            ),
+            rawType: 'double',
             rawValue: '20.0',
           ),
         ],
diff --git a/test/collision_tests/decl_decl_collision_test.dart b/test/collision_tests/decl_decl_collision_test.dart
index e0ebb25..554795e 100644
--- a/test/collision_tests/decl_decl_collision_test.dart
+++ b/test/collision_tests/decl_decl_collision_test.dart
@@ -24,6 +24,18 @@
         Func(
             name: 'testFunc',
             returnType: Type.nativeType(SupportedNativeType.Void)),
+        Constant(
+          originalName: 'Test_Macro',
+          name: 'Test_Macro',
+          rawType: 'int',
+          rawValue: '0',
+        ),
+        Constant(
+          originalName: 'Test_Macro',
+          name: 'Test_Macro',
+          rawType: 'int',
+          rawValue: '0',
+        ),
       ]);
       final l2 = Library(name: 'Bindings', bindings: [
         Struc(name: 'TestStruc'),
@@ -38,6 +50,18 @@
             name: 'testFunc_1',
             originalName: 'testFunc',
             returnType: Type.nativeType(SupportedNativeType.Void)),
+        Constant(
+          originalName: 'Test_Macro',
+          name: 'Test_Macro',
+          rawType: 'int',
+          rawValue: '0',
+        ),
+        Constant(
+          originalName: 'Test_Macro',
+          name: 'Test_Macro_1',
+          rawType: 'int',
+          rawValue: '0',
+        ),
       ]);
 
       expect(l1.generate(), l2.generate());
diff --git a/test/collision_tests/reserved_keyword_collision_test.dart b/test/collision_tests/reserved_keyword_collision_test.dart
index 964d7ea..b5b6931 100644
--- a/test/collision_tests/reserved_keyword_collision_test.dart
+++ b/test/collision_tests/reserved_keyword_collision_test.dart
@@ -40,6 +40,11 @@
               ),
             ],
             returnType: Type.nativeType(SupportedNativeType.Void)),
+        Constant(
+          name: 'else',
+          rawType: 'int',
+          rawValue: '0',
+        ),
       ]);
       final l2 = Library(name: 'Bindings', bindings: [
         Struc(name: 'abstract_1'),
@@ -69,6 +74,11 @@
               ),
             ],
             returnType: Type.nativeType(SupportedNativeType.Void)),
+        Constant(
+          name: 'else_1',
+          rawType: 'int',
+          rawValue: '0',
+        ),
       ]);
       expect(l1.generate(), l2.generate());
     });
diff --git a/test/header_parser_tests/macros.h b/test/header_parser_tests/macros.h
new file mode 100644
index 0000000..b405db4
--- /dev/null
+++ b/test/header_parser_tests/macros.h
@@ -0,0 +1,16 @@
+#define TEST1 1.1
+#define TEST2 10
+#define TEST3 (TEST1 + TEST2)
+#define TEST4 "test"
+
+// The comma operator should actually return the last value (3),
+// when returned by a function. This value, however, when assigned to a variable
+// will not compile and so libclang tries to fix it and assigns the first
+// value (4) to the generated macro variable.
+#define TEST5 4, \
+              2, \
+              3
+#define TEST6 (1 == 1);
+#define TEST7(x, y) x *y
+
+#define TEST8 5,2,3
diff --git a/test/header_parser_tests/macros_test.dart b/test/header_parser_tests/macros_test.dart
new file mode 100644
index 0000000..b912f78
--- /dev/null
+++ b/test/header_parser_tests/macros_test.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/config_provider.dart';
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+import 'package:yaml/yaml.dart' as yaml;
+import 'package:ffigen/src/strings.dart' as strings;
+
+import '../test_utils.dart';
+
+Library actual, expected;
+
+void main() {
+  group('macros_test', () {
+    setUpAll(() {
+      logWarnings(Level.WARNING);
+      expected = expectedLibrary();
+      actual = parser.parse(
+        Config.fromYaml(yaml.loadYaml('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Macros Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  - 'test/header_parser_tests/macros.h'
+${strings.headerFilter}:
+  ${strings.include}:
+    - 'macros.h'
+        ''') as yaml.YamlMap),
+      );
+    });
+    test('Total bindings count', () {
+      expect(actual.bindings.length, expected.bindings.length);
+    });
+
+    test('TEST1', () {
+      expect(actual.getBindingAsString('TEST1'),
+          expected.getBindingAsString('TEST1'));
+    });
+    test('TEST2', () {
+      expect(actual.getBindingAsString('TEST2'),
+          expected.getBindingAsString('TEST2'));
+    });
+    test('TEST3', () {
+      expect(actual.getBindingAsString('TEST3'),
+          expected.getBindingAsString('TEST3'));
+    });
+
+    test('TEST4', () {
+      expect(actual.getBindingAsString('TEST4'),
+          expected.getBindingAsString('TEST4'));
+    });
+
+    test('TEST5', () {
+      expect(actual.getBindingAsString('TEST5'),
+          expected.getBindingAsString('TEST5'));
+    });
+    test('TEST6', () {
+      expect(actual.getBindingAsString('TEST6'),
+          expected.getBindingAsString('TEST6'));
+    });
+    test('TEST8', () {
+      expect(actual.getBindingAsString('TEST8'),
+          expected.getBindingAsString('TEST8'));
+    });
+  });
+}
+
+Library expectedLibrary() {
+  return Library(
+    name: 'NativeLibrary',
+    bindings: [
+      Constant(name: 'TEST1', rawType: 'double', rawValue: '1.1'),
+      Constant(name: 'TEST2', rawType: 'int', rawValue: '10'),
+      Constant(name: 'TEST3', rawType: 'double', rawValue: '11.1'),
+      Constant(name: 'TEST4', rawType: 'String', rawValue: "'test'"),
+      Constant(name: 'TEST5', rawType: 'int', rawValue: '4'),
+      Constant(name: 'TEST6', rawType: 'int', rawValue: '1'),
+      Constant(name: 'TEST8', rawType: 'int', rawValue: '5'),
+    ],
+  );
+}
diff --git a/test/header_parser_tests/unnamed_enums.h b/test/header_parser_tests/unnamed_enums.h
new file mode 100644
index 0000000..ecb4a85
--- /dev/null
+++ b/test/header_parser_tests/unnamed_enums.h
@@ -0,0 +1,13 @@
+// Only this should be parsed.
+enum{
+    A=1,
+    B=2,
+    C=3
+};
+
+// Shouldn't be parsed.
+typedef enum{
+    E,
+    F,
+    G
+} Named;
diff --git a/test/header_parser_tests/unnamed_enums_test.dart b/test/header_parser_tests/unnamed_enums_test.dart
new file mode 100644
index 0000000..7c07602
--- /dev/null
+++ b/test/header_parser_tests/unnamed_enums_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/config_provider.dart';
+import 'package:test/test.dart';
+import 'package:yaml/yaml.dart' as yaml;
+import 'package:ffigen/src/strings.dart' as strings;
+
+import '../test_utils.dart';
+
+Library actual, expected;
+
+void main() {
+  group('unnamed_enums_test', () {
+    setUpAll(() {
+      logWarnings();
+      expected = expectedLibrary();
+      actual = parser.parse(
+        Config.fromYaml(yaml.loadYaml('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Unnamed Enums Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  - 'test/header_parser_tests/unnamed_enums.h'
+${strings.headerFilter}:
+  ${strings.include}:
+    - 'unnamed_enums.h'
+${strings.enums}:
+  ${strings.exclude}:
+    ${strings.names}:
+      - Named
+        ''') as yaml.YamlMap),
+      );
+    });
+
+    test('Total bindings count', () {
+      expect(actual.bindings.length, expected.bindings.length);
+    });
+
+    test('Parse unnamed enum Values', () {
+      expect(actual.getBindingAsString('A'), expected.getBindingAsString('A'));
+      expect(actual.getBindingAsString('B'), expected.getBindingAsString('B'));
+      expect(actual.getBindingAsString('C'), expected.getBindingAsString('C'));
+    });
+
+    test('Ignore unnamed enums inside typedefs', () {
+      expect(() => actual.getBindingAsString('E'),
+          throwsA(TypeMatcher<NotFoundException>()));
+      expect(() => actual.getBindingAsString('F'),
+          throwsA(TypeMatcher<NotFoundException>()));
+      expect(() => actual.getBindingAsString('G'),
+          throwsA(TypeMatcher<NotFoundException>()));
+    });
+  });
+}
+
+Library expectedLibrary() {
+  return Library(
+    name: 'Bindings',
+    bindings: [
+      Constant(
+        name: 'A',
+        rawType: 'int',
+        rawValue: '1',
+      ),
+      Constant(
+        name: 'B',
+        rawType: 'int',
+        rawValue: '2',
+      ),
+      Constant(
+        name: 'C',
+        rawType: 'int',
+        rawValue: '3',
+      ),
+    ],
+  );
+}
diff --git a/test/large_integration_tests/_expected_cjson_bindings.dart b/test/large_integration_tests/_expected_cjson_bindings.dart
index e7766d2..7beb2ef 100644
--- a/test/large_integration_tests/_expected_cjson_bindings.dart
+++ b/test/large_integration_tests/_expected_cjson_bindings.dart
@@ -1063,6 +1063,38 @@
   ffi.Pointer<ffi.NativeFunction<_typedefC_12>> free_fn;
 }
 
+const int CJSON_VERSION_MAJOR = 1;
+
+const int CJSON_VERSION_MINOR = 7;
+
+const int CJSON_VERSION_PATCH = 12;
+
+const int cJSON_Invalid = 0;
+
+const int cJSON_False = 1;
+
+const int cJSON_True = 2;
+
+const int cJSON_NULL = 4;
+
+const int cJSON_Number = 8;
+
+const int cJSON_String = 16;
+
+const int cJSON_Array = 32;
+
+const int cJSON_Object = 64;
+
+const int cJSON_Raw = 128;
+
+const int cJSON_IsReference = 256;
+
+const int cJSON_StringIsConst = 512;
+
+const int CJSON_NESTING_LIMIT = 1000;
+
+const double CJSON_DOUBLE_PRECISION = 1e-16;
+
 typedef _c_cJSON_Version = ffi.Pointer<ffi.Int8> Function();
 
 typedef _dart_cJSON_Version = ffi.Pointer<ffi.Int8> Function();
diff --git a/test/large_integration_tests/_expected_libclang_bindings.dart b/test/large_integration_tests/_expected_libclang_bindings.dart
index c6642d8..f857457 100644
--- a/test/large_integration_tests/_expected_libclang_bindings.dart
+++ b/test/large_integration_tests/_expected_libclang_bindings.dart
@@ -4418,6 +4418,14 @@
   static const int CXIndexOpt_SkipParsedBodiesInSession = 16;
 }
 
+const int CINDEX_VERSION_MAJOR = 0;
+
+const int CINDEX_VERSION_MINOR = 59;
+
+const int CINDEX_VERSION = 59;
+
+const String CINDEX_VERSION_STRING = '0.59';
+
 typedef _c_clang_disposeStringSet = ffi.Void Function(
   ffi.Pointer<CXStringSet> set_1,
 );
diff --git a/test/large_integration_tests/_expected_sqlite_bindings.dart b/test/large_integration_tests/_expected_sqlite_bindings.dart
index ba750ec..ad214b3 100644
--- a/test/large_integration_tests/_expected_sqlite_bindings.dart
+++ b/test/large_integration_tests/_expected_sqlite_bindings.dart
@@ -9856,6 +9856,887 @@
 
 class fts5_api extends ffi.Struct {}
 
+const String SQLITE_VERSION = '3.32.3';
+
+const int SQLITE_VERSION_NUMBER = 3032003;
+
+const String SQLITE_SOURCE_ID =
+    '2020-06-18 14:00:33 7ebdfa80be8e8e73324b8d66b3460222eb74c7e9dfd655b48d6ca7e1933cc8fd';
+
+const int SQLITE_OK = 0;
+
+const int SQLITE_ERROR = 1;
+
+const int SQLITE_INTERNAL = 2;
+
+const int SQLITE_PERM = 3;
+
+const int SQLITE_ABORT = 4;
+
+const int SQLITE_BUSY = 5;
+
+const int SQLITE_LOCKED = 6;
+
+const int SQLITE_NOMEM = 7;
+
+const int SQLITE_READONLY = 8;
+
+const int SQLITE_INTERRUPT = 9;
+
+const int SQLITE_IOERR = 10;
+
+const int SQLITE_CORRUPT = 11;
+
+const int SQLITE_NOTFOUND = 12;
+
+const int SQLITE_FULL = 13;
+
+const int SQLITE_CANTOPEN = 14;
+
+const int SQLITE_PROTOCOL = 15;
+
+const int SQLITE_EMPTY = 16;
+
+const int SQLITE_SCHEMA = 17;
+
+const int SQLITE_TOOBIG = 18;
+
+const int SQLITE_CONSTRAINT = 19;
+
+const int SQLITE_MISMATCH = 20;
+
+const int SQLITE_MISUSE = 21;
+
+const int SQLITE_NOLFS = 22;
+
+const int SQLITE_AUTH = 23;
+
+const int SQLITE_FORMAT = 24;
+
+const int SQLITE_RANGE = 25;
+
+const int SQLITE_NOTADB = 26;
+
+const int SQLITE_NOTICE = 27;
+
+const int SQLITE_WARNING = 28;
+
+const int SQLITE_ROW = 100;
+
+const int SQLITE_DONE = 101;
+
+const int SQLITE_ERROR_MISSING_COLLSEQ = 257;
+
+const int SQLITE_ERROR_RETRY = 513;
+
+const int SQLITE_ERROR_SNAPSHOT = 769;
+
+const int SQLITE_IOERR_READ = 266;
+
+const int SQLITE_IOERR_SHORT_READ = 522;
+
+const int SQLITE_IOERR_WRITE = 778;
+
+const int SQLITE_IOERR_FSYNC = 1034;
+
+const int SQLITE_IOERR_DIR_FSYNC = 1290;
+
+const int SQLITE_IOERR_TRUNCATE = 1546;
+
+const int SQLITE_IOERR_FSTAT = 1802;
+
+const int SQLITE_IOERR_UNLOCK = 2058;
+
+const int SQLITE_IOERR_RDLOCK = 2314;
+
+const int SQLITE_IOERR_DELETE = 2570;
+
+const int SQLITE_IOERR_BLOCKED = 2826;
+
+const int SQLITE_IOERR_NOMEM = 3082;
+
+const int SQLITE_IOERR_ACCESS = 3338;
+
+const int SQLITE_IOERR_CHECKRESERVEDLOCK = 3594;
+
+const int SQLITE_IOERR_LOCK = 3850;
+
+const int SQLITE_IOERR_CLOSE = 4106;
+
+const int SQLITE_IOERR_DIR_CLOSE = 4362;
+
+const int SQLITE_IOERR_SHMOPEN = 4618;
+
+const int SQLITE_IOERR_SHMSIZE = 4874;
+
+const int SQLITE_IOERR_SHMLOCK = 5130;
+
+const int SQLITE_IOERR_SHMMAP = 5386;
+
+const int SQLITE_IOERR_SEEK = 5642;
+
+const int SQLITE_IOERR_DELETE_NOENT = 5898;
+
+const int SQLITE_IOERR_MMAP = 6154;
+
+const int SQLITE_IOERR_GETTEMPPATH = 6410;
+
+const int SQLITE_IOERR_CONVPATH = 6666;
+
+const int SQLITE_IOERR_VNODE = 6922;
+
+const int SQLITE_IOERR_AUTH = 7178;
+
+const int SQLITE_IOERR_BEGIN_ATOMIC = 7434;
+
+const int SQLITE_IOERR_COMMIT_ATOMIC = 7690;
+
+const int SQLITE_IOERR_ROLLBACK_ATOMIC = 7946;
+
+const int SQLITE_IOERR_DATA = 8202;
+
+const int SQLITE_LOCKED_SHAREDCACHE = 262;
+
+const int SQLITE_LOCKED_VTAB = 518;
+
+const int SQLITE_BUSY_RECOVERY = 261;
+
+const int SQLITE_BUSY_SNAPSHOT = 517;
+
+const int SQLITE_BUSY_TIMEOUT = 773;
+
+const int SQLITE_CANTOPEN_NOTEMPDIR = 270;
+
+const int SQLITE_CANTOPEN_ISDIR = 526;
+
+const int SQLITE_CANTOPEN_FULLPATH = 782;
+
+const int SQLITE_CANTOPEN_CONVPATH = 1038;
+
+const int SQLITE_CANTOPEN_DIRTYWAL = 1294;
+
+const int SQLITE_CANTOPEN_SYMLINK = 1550;
+
+const int SQLITE_CORRUPT_VTAB = 267;
+
+const int SQLITE_CORRUPT_SEQUENCE = 523;
+
+const int SQLITE_CORRUPT_INDEX = 779;
+
+const int SQLITE_READONLY_RECOVERY = 264;
+
+const int SQLITE_READONLY_CANTLOCK = 520;
+
+const int SQLITE_READONLY_ROLLBACK = 776;
+
+const int SQLITE_READONLY_DBMOVED = 1032;
+
+const int SQLITE_READONLY_CANTINIT = 1288;
+
+const int SQLITE_READONLY_DIRECTORY = 1544;
+
+const int SQLITE_ABORT_ROLLBACK = 516;
+
+const int SQLITE_CONSTRAINT_CHECK = 275;
+
+const int SQLITE_CONSTRAINT_COMMITHOOK = 531;
+
+const int SQLITE_CONSTRAINT_FOREIGNKEY = 787;
+
+const int SQLITE_CONSTRAINT_FUNCTION = 1043;
+
+const int SQLITE_CONSTRAINT_NOTNULL = 1299;
+
+const int SQLITE_CONSTRAINT_PRIMARYKEY = 1555;
+
+const int SQLITE_CONSTRAINT_TRIGGER = 1811;
+
+const int SQLITE_CONSTRAINT_UNIQUE = 2067;
+
+const int SQLITE_CONSTRAINT_VTAB = 2323;
+
+const int SQLITE_CONSTRAINT_ROWID = 2579;
+
+const int SQLITE_CONSTRAINT_PINNED = 2835;
+
+const int SQLITE_NOTICE_RECOVER_WAL = 283;
+
+const int SQLITE_NOTICE_RECOVER_ROLLBACK = 539;
+
+const int SQLITE_WARNING_AUTOINDEX = 284;
+
+const int SQLITE_AUTH_USER = 279;
+
+const int SQLITE_OK_LOAD_PERMANENTLY = 256;
+
+const int SQLITE_OK_SYMLINK = 512;
+
+const int SQLITE_OPEN_READONLY = 1;
+
+const int SQLITE_OPEN_READWRITE = 2;
+
+const int SQLITE_OPEN_CREATE = 4;
+
+const int SQLITE_OPEN_DELETEONCLOSE = 8;
+
+const int SQLITE_OPEN_EXCLUSIVE = 16;
+
+const int SQLITE_OPEN_AUTOPROXY = 32;
+
+const int SQLITE_OPEN_URI = 64;
+
+const int SQLITE_OPEN_MEMORY = 128;
+
+const int SQLITE_OPEN_MAIN_DB = 256;
+
+const int SQLITE_OPEN_TEMP_DB = 512;
+
+const int SQLITE_OPEN_TRANSIENT_DB = 1024;
+
+const int SQLITE_OPEN_MAIN_JOURNAL = 2048;
+
+const int SQLITE_OPEN_TEMP_JOURNAL = 4096;
+
+const int SQLITE_OPEN_SUBJOURNAL = 8192;
+
+const int SQLITE_OPEN_MASTER_JOURNAL = 16384;
+
+const int SQLITE_OPEN_NOMUTEX = 32768;
+
+const int SQLITE_OPEN_FULLMUTEX = 65536;
+
+const int SQLITE_OPEN_SHAREDCACHE = 131072;
+
+const int SQLITE_OPEN_PRIVATECACHE = 262144;
+
+const int SQLITE_OPEN_WAL = 524288;
+
+const int SQLITE_OPEN_NOFOLLOW = 16777216;
+
+const int SQLITE_IOCAP_ATOMIC = 1;
+
+const int SQLITE_IOCAP_ATOMIC512 = 2;
+
+const int SQLITE_IOCAP_ATOMIC1K = 4;
+
+const int SQLITE_IOCAP_ATOMIC2K = 8;
+
+const int SQLITE_IOCAP_ATOMIC4K = 16;
+
+const int SQLITE_IOCAP_ATOMIC8K = 32;
+
+const int SQLITE_IOCAP_ATOMIC16K = 64;
+
+const int SQLITE_IOCAP_ATOMIC32K = 128;
+
+const int SQLITE_IOCAP_ATOMIC64K = 256;
+
+const int SQLITE_IOCAP_SAFE_APPEND = 512;
+
+const int SQLITE_IOCAP_SEQUENTIAL = 1024;
+
+const int SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN = 2048;
+
+const int SQLITE_IOCAP_POWERSAFE_OVERWRITE = 4096;
+
+const int SQLITE_IOCAP_IMMUTABLE = 8192;
+
+const int SQLITE_IOCAP_BATCH_ATOMIC = 16384;
+
+const int SQLITE_LOCK_NONE = 0;
+
+const int SQLITE_LOCK_SHARED = 1;
+
+const int SQLITE_LOCK_RESERVED = 2;
+
+const int SQLITE_LOCK_PENDING = 3;
+
+const int SQLITE_LOCK_EXCLUSIVE = 4;
+
+const int SQLITE_SYNC_NORMAL = 2;
+
+const int SQLITE_SYNC_FULL = 3;
+
+const int SQLITE_SYNC_DATAONLY = 16;
+
+const int SQLITE_FCNTL_LOCKSTATE = 1;
+
+const int SQLITE_FCNTL_GET_LOCKPROXYFILE = 2;
+
+const int SQLITE_FCNTL_SET_LOCKPROXYFILE = 3;
+
+const int SQLITE_FCNTL_LAST_ERRNO = 4;
+
+const int SQLITE_FCNTL_SIZE_HINT = 5;
+
+const int SQLITE_FCNTL_CHUNK_SIZE = 6;
+
+const int SQLITE_FCNTL_FILE_POINTER = 7;
+
+const int SQLITE_FCNTL_SYNC_OMITTED = 8;
+
+const int SQLITE_FCNTL_WIN32_AV_RETRY = 9;
+
+const int SQLITE_FCNTL_PERSIST_WAL = 10;
+
+const int SQLITE_FCNTL_OVERWRITE = 11;
+
+const int SQLITE_FCNTL_VFSNAME = 12;
+
+const int SQLITE_FCNTL_POWERSAFE_OVERWRITE = 13;
+
+const int SQLITE_FCNTL_PRAGMA = 14;
+
+const int SQLITE_FCNTL_BUSYHANDLER = 15;
+
+const int SQLITE_FCNTL_TEMPFILENAME = 16;
+
+const int SQLITE_FCNTL_MMAP_SIZE = 18;
+
+const int SQLITE_FCNTL_TRACE = 19;
+
+const int SQLITE_FCNTL_HAS_MOVED = 20;
+
+const int SQLITE_FCNTL_SYNC = 21;
+
+const int SQLITE_FCNTL_COMMIT_PHASETWO = 22;
+
+const int SQLITE_FCNTL_WIN32_SET_HANDLE = 23;
+
+const int SQLITE_FCNTL_WAL_BLOCK = 24;
+
+const int SQLITE_FCNTL_ZIPVFS = 25;
+
+const int SQLITE_FCNTL_RBU = 26;
+
+const int SQLITE_FCNTL_VFS_POINTER = 27;
+
+const int SQLITE_FCNTL_JOURNAL_POINTER = 28;
+
+const int SQLITE_FCNTL_WIN32_GET_HANDLE = 29;
+
+const int SQLITE_FCNTL_PDB = 30;
+
+const int SQLITE_FCNTL_BEGIN_ATOMIC_WRITE = 31;
+
+const int SQLITE_FCNTL_COMMIT_ATOMIC_WRITE = 32;
+
+const int SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE = 33;
+
+const int SQLITE_FCNTL_LOCK_TIMEOUT = 34;
+
+const int SQLITE_FCNTL_DATA_VERSION = 35;
+
+const int SQLITE_FCNTL_SIZE_LIMIT = 36;
+
+const int SQLITE_FCNTL_CKPT_DONE = 37;
+
+const int SQLITE_FCNTL_RESERVE_BYTES = 38;
+
+const int SQLITE_FCNTL_CKPT_START = 39;
+
+const int SQLITE_GET_LOCKPROXYFILE = 2;
+
+const int SQLITE_SET_LOCKPROXYFILE = 3;
+
+const int SQLITE_LAST_ERRNO = 4;
+
+const int SQLITE_ACCESS_EXISTS = 0;
+
+const int SQLITE_ACCESS_READWRITE = 1;
+
+const int SQLITE_ACCESS_READ = 2;
+
+const int SQLITE_SHM_UNLOCK = 1;
+
+const int SQLITE_SHM_LOCK = 2;
+
+const int SQLITE_SHM_SHARED = 4;
+
+const int SQLITE_SHM_EXCLUSIVE = 8;
+
+const int SQLITE_SHM_NLOCK = 8;
+
+const int SQLITE_CONFIG_SINGLETHREAD = 1;
+
+const int SQLITE_CONFIG_MULTITHREAD = 2;
+
+const int SQLITE_CONFIG_SERIALIZED = 3;
+
+const int SQLITE_CONFIG_MALLOC = 4;
+
+const int SQLITE_CONFIG_GETMALLOC = 5;
+
+const int SQLITE_CONFIG_SCRATCH = 6;
+
+const int SQLITE_CONFIG_PAGECACHE = 7;
+
+const int SQLITE_CONFIG_HEAP = 8;
+
+const int SQLITE_CONFIG_MEMSTATUS = 9;
+
+const int SQLITE_CONFIG_MUTEX = 10;
+
+const int SQLITE_CONFIG_GETMUTEX = 11;
+
+const int SQLITE_CONFIG_LOOKASIDE = 13;
+
+const int SQLITE_CONFIG_PCACHE = 14;
+
+const int SQLITE_CONFIG_GETPCACHE = 15;
+
+const int SQLITE_CONFIG_LOG = 16;
+
+const int SQLITE_CONFIG_URI = 17;
+
+const int SQLITE_CONFIG_PCACHE2 = 18;
+
+const int SQLITE_CONFIG_GETPCACHE2 = 19;
+
+const int SQLITE_CONFIG_COVERING_INDEX_SCAN = 20;
+
+const int SQLITE_CONFIG_SQLLOG = 21;
+
+const int SQLITE_CONFIG_MMAP_SIZE = 22;
+
+const int SQLITE_CONFIG_WIN32_HEAPSIZE = 23;
+
+const int SQLITE_CONFIG_PCACHE_HDRSZ = 24;
+
+const int SQLITE_CONFIG_PMASZ = 25;
+
+const int SQLITE_CONFIG_STMTJRNL_SPILL = 26;
+
+const int SQLITE_CONFIG_SMALL_MALLOC = 27;
+
+const int SQLITE_CONFIG_SORTERREF_SIZE = 28;
+
+const int SQLITE_CONFIG_MEMDB_MAXSIZE = 29;
+
+const int SQLITE_DBCONFIG_MAINDBNAME = 1000;
+
+const int SQLITE_DBCONFIG_LOOKASIDE = 1001;
+
+const int SQLITE_DBCONFIG_ENABLE_FKEY = 1002;
+
+const int SQLITE_DBCONFIG_ENABLE_TRIGGER = 1003;
+
+const int SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER = 1004;
+
+const int SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION = 1005;
+
+const int SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE = 1006;
+
+const int SQLITE_DBCONFIG_ENABLE_QPSG = 1007;
+
+const int SQLITE_DBCONFIG_TRIGGER_EQP = 1008;
+
+const int SQLITE_DBCONFIG_RESET_DATABASE = 1009;
+
+const int SQLITE_DBCONFIG_DEFENSIVE = 1010;
+
+const int SQLITE_DBCONFIG_WRITABLE_SCHEMA = 1011;
+
+const int SQLITE_DBCONFIG_LEGACY_ALTER_TABLE = 1012;
+
+const int SQLITE_DBCONFIG_DQS_DML = 1013;
+
+const int SQLITE_DBCONFIG_DQS_DDL = 1014;
+
+const int SQLITE_DBCONFIG_ENABLE_VIEW = 1015;
+
+const int SQLITE_DBCONFIG_LEGACY_FILE_FORMAT = 1016;
+
+const int SQLITE_DBCONFIG_TRUSTED_SCHEMA = 1017;
+
+const int SQLITE_DBCONFIG_MAX = 1017;
+
+const int SQLITE_DENY = 1;
+
+const int SQLITE_IGNORE = 2;
+
+const int SQLITE_CREATE_INDEX = 1;
+
+const int SQLITE_CREATE_TABLE = 2;
+
+const int SQLITE_CREATE_TEMP_INDEX = 3;
+
+const int SQLITE_CREATE_TEMP_TABLE = 4;
+
+const int SQLITE_CREATE_TEMP_TRIGGER = 5;
+
+const int SQLITE_CREATE_TEMP_VIEW = 6;
+
+const int SQLITE_CREATE_TRIGGER = 7;
+
+const int SQLITE_CREATE_VIEW = 8;
+
+const int SQLITE_DELETE = 9;
+
+const int SQLITE_DROP_INDEX = 10;
+
+const int SQLITE_DROP_TABLE = 11;
+
+const int SQLITE_DROP_TEMP_INDEX = 12;
+
+const int SQLITE_DROP_TEMP_TABLE = 13;
+
+const int SQLITE_DROP_TEMP_TRIGGER = 14;
+
+const int SQLITE_DROP_TEMP_VIEW = 15;
+
+const int SQLITE_DROP_TRIGGER = 16;
+
+const int SQLITE_DROP_VIEW = 17;
+
+const int SQLITE_INSERT = 18;
+
+const int SQLITE_PRAGMA = 19;
+
+const int SQLITE_READ = 20;
+
+const int SQLITE_SELECT = 21;
+
+const int SQLITE_TRANSACTION = 22;
+
+const int SQLITE_UPDATE = 23;
+
+const int SQLITE_ATTACH = 24;
+
+const int SQLITE_DETACH = 25;
+
+const int SQLITE_ALTER_TABLE = 26;
+
+const int SQLITE_REINDEX = 27;
+
+const int SQLITE_ANALYZE = 28;
+
+const int SQLITE_CREATE_VTABLE = 29;
+
+const int SQLITE_DROP_VTABLE = 30;
+
+const int SQLITE_FUNCTION = 31;
+
+const int SQLITE_SAVEPOINT = 32;
+
+const int SQLITE_COPY = 0;
+
+const int SQLITE_RECURSIVE = 33;
+
+const int SQLITE_TRACE_STMT = 1;
+
+const int SQLITE_TRACE_PROFILE = 2;
+
+const int SQLITE_TRACE_ROW = 4;
+
+const int SQLITE_TRACE_CLOSE = 8;
+
+const int SQLITE_LIMIT_LENGTH = 0;
+
+const int SQLITE_LIMIT_SQL_LENGTH = 1;
+
+const int SQLITE_LIMIT_COLUMN = 2;
+
+const int SQLITE_LIMIT_EXPR_DEPTH = 3;
+
+const int SQLITE_LIMIT_COMPOUND_SELECT = 4;
+
+const int SQLITE_LIMIT_VDBE_OP = 5;
+
+const int SQLITE_LIMIT_FUNCTION_ARG = 6;
+
+const int SQLITE_LIMIT_ATTACHED = 7;
+
+const int SQLITE_LIMIT_LIKE_PATTERN_LENGTH = 8;
+
+const int SQLITE_LIMIT_VARIABLE_NUMBER = 9;
+
+const int SQLITE_LIMIT_TRIGGER_DEPTH = 10;
+
+const int SQLITE_LIMIT_WORKER_THREADS = 11;
+
+const int SQLITE_PREPARE_PERSISTENT = 1;
+
+const int SQLITE_PREPARE_NORMALIZE = 2;
+
+const int SQLITE_PREPARE_NO_VTAB = 4;
+
+const int SQLITE_INTEGER = 1;
+
+const int SQLITE_FLOAT = 2;
+
+const int SQLITE_BLOB = 4;
+
+const int SQLITE_NULL = 5;
+
+const int SQLITE_TEXT = 3;
+
+const int SQLITE3_TEXT = 3;
+
+const int SQLITE_UTF8 = 1;
+
+const int SQLITE_UTF16LE = 2;
+
+const int SQLITE_UTF16BE = 3;
+
+const int SQLITE_UTF16 = 4;
+
+const int SQLITE_ANY = 5;
+
+const int SQLITE_UTF16_ALIGNED = 8;
+
+const int SQLITE_DETERMINISTIC = 2048;
+
+const int SQLITE_DIRECTONLY = 524288;
+
+const int SQLITE_SUBTYPE = 1048576;
+
+const int SQLITE_INNOCUOUS = 2097152;
+
+const int SQLITE_WIN32_DATA_DIRECTORY_TYPE = 1;
+
+const int SQLITE_WIN32_TEMP_DIRECTORY_TYPE = 2;
+
+const int SQLITE_INDEX_SCAN_UNIQUE = 1;
+
+const int SQLITE_INDEX_CONSTRAINT_EQ = 2;
+
+const int SQLITE_INDEX_CONSTRAINT_GT = 4;
+
+const int SQLITE_INDEX_CONSTRAINT_LE = 8;
+
+const int SQLITE_INDEX_CONSTRAINT_LT = 16;
+
+const int SQLITE_INDEX_CONSTRAINT_GE = 32;
+
+const int SQLITE_INDEX_CONSTRAINT_MATCH = 64;
+
+const int SQLITE_INDEX_CONSTRAINT_LIKE = 65;
+
+const int SQLITE_INDEX_CONSTRAINT_GLOB = 66;
+
+const int SQLITE_INDEX_CONSTRAINT_REGEXP = 67;
+
+const int SQLITE_INDEX_CONSTRAINT_NE = 68;
+
+const int SQLITE_INDEX_CONSTRAINT_ISNOT = 69;
+
+const int SQLITE_INDEX_CONSTRAINT_ISNOTNULL = 70;
+
+const int SQLITE_INDEX_CONSTRAINT_ISNULL = 71;
+
+const int SQLITE_INDEX_CONSTRAINT_IS = 72;
+
+const int SQLITE_INDEX_CONSTRAINT_FUNCTION = 150;
+
+const int SQLITE_MUTEX_FAST = 0;
+
+const int SQLITE_MUTEX_RECURSIVE = 1;
+
+const int SQLITE_MUTEX_STATIC_MASTER = 2;
+
+const int SQLITE_MUTEX_STATIC_MEM = 3;
+
+const int SQLITE_MUTEX_STATIC_MEM2 = 4;
+
+const int SQLITE_MUTEX_STATIC_OPEN = 4;
+
+const int SQLITE_MUTEX_STATIC_PRNG = 5;
+
+const int SQLITE_MUTEX_STATIC_LRU = 6;
+
+const int SQLITE_MUTEX_STATIC_LRU2 = 7;
+
+const int SQLITE_MUTEX_STATIC_PMEM = 7;
+
+const int SQLITE_MUTEX_STATIC_APP1 = 8;
+
+const int SQLITE_MUTEX_STATIC_APP2 = 9;
+
+const int SQLITE_MUTEX_STATIC_APP3 = 10;
+
+const int SQLITE_MUTEX_STATIC_VFS1 = 11;
+
+const int SQLITE_MUTEX_STATIC_VFS2 = 12;
+
+const int SQLITE_MUTEX_STATIC_VFS3 = 13;
+
+const int SQLITE_TESTCTRL_FIRST = 5;
+
+const int SQLITE_TESTCTRL_PRNG_SAVE = 5;
+
+const int SQLITE_TESTCTRL_PRNG_RESTORE = 6;
+
+const int SQLITE_TESTCTRL_PRNG_RESET = 7;
+
+const int SQLITE_TESTCTRL_BITVEC_TEST = 8;
+
+const int SQLITE_TESTCTRL_FAULT_INSTALL = 9;
+
+const int SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS = 10;
+
+const int SQLITE_TESTCTRL_PENDING_BYTE = 11;
+
+const int SQLITE_TESTCTRL_ASSERT = 12;
+
+const int SQLITE_TESTCTRL_ALWAYS = 13;
+
+const int SQLITE_TESTCTRL_RESERVE = 14;
+
+const int SQLITE_TESTCTRL_OPTIMIZATIONS = 15;
+
+const int SQLITE_TESTCTRL_ISKEYWORD = 16;
+
+const int SQLITE_TESTCTRL_SCRATCHMALLOC = 17;
+
+const int SQLITE_TESTCTRL_INTERNAL_FUNCTIONS = 17;
+
+const int SQLITE_TESTCTRL_LOCALTIME_FAULT = 18;
+
+const int SQLITE_TESTCTRL_EXPLAIN_STMT = 19;
+
+const int SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD = 19;
+
+const int SQLITE_TESTCTRL_NEVER_CORRUPT = 20;
+
+const int SQLITE_TESTCTRL_VDBE_COVERAGE = 21;
+
+const int SQLITE_TESTCTRL_BYTEORDER = 22;
+
+const int SQLITE_TESTCTRL_ISINIT = 23;
+
+const int SQLITE_TESTCTRL_SORTER_MMAP = 24;
+
+const int SQLITE_TESTCTRL_IMPOSTER = 25;
+
+const int SQLITE_TESTCTRL_PARSER_COVERAGE = 26;
+
+const int SQLITE_TESTCTRL_RESULT_INTREAL = 27;
+
+const int SQLITE_TESTCTRL_PRNG_SEED = 28;
+
+const int SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS = 29;
+
+const int SQLITE_TESTCTRL_LAST = 29;
+
+const int SQLITE_STATUS_MEMORY_USED = 0;
+
+const int SQLITE_STATUS_PAGECACHE_USED = 1;
+
+const int SQLITE_STATUS_PAGECACHE_OVERFLOW = 2;
+
+const int SQLITE_STATUS_SCRATCH_USED = 3;
+
+const int SQLITE_STATUS_SCRATCH_OVERFLOW = 4;
+
+const int SQLITE_STATUS_MALLOC_SIZE = 5;
+
+const int SQLITE_STATUS_PARSER_STACK = 6;
+
+const int SQLITE_STATUS_PAGECACHE_SIZE = 7;
+
+const int SQLITE_STATUS_SCRATCH_SIZE = 8;
+
+const int SQLITE_STATUS_MALLOC_COUNT = 9;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_USED = 0;
+
+const int SQLITE_DBSTATUS_CACHE_USED = 1;
+
+const int SQLITE_DBSTATUS_SCHEMA_USED = 2;
+
+const int SQLITE_DBSTATUS_STMT_USED = 3;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_HIT = 4;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE = 5;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL = 6;
+
+const int SQLITE_DBSTATUS_CACHE_HIT = 7;
+
+const int SQLITE_DBSTATUS_CACHE_MISS = 8;
+
+const int SQLITE_DBSTATUS_CACHE_WRITE = 9;
+
+const int SQLITE_DBSTATUS_DEFERRED_FKS = 10;
+
+const int SQLITE_DBSTATUS_CACHE_USED_SHARED = 11;
+
+const int SQLITE_DBSTATUS_CACHE_SPILL = 12;
+
+const int SQLITE_DBSTATUS_MAX = 12;
+
+const int SQLITE_STMTSTATUS_FULLSCAN_STEP = 1;
+
+const int SQLITE_STMTSTATUS_SORT = 2;
+
+const int SQLITE_STMTSTATUS_AUTOINDEX = 3;
+
+const int SQLITE_STMTSTATUS_VM_STEP = 4;
+
+const int SQLITE_STMTSTATUS_REPREPARE = 5;
+
+const int SQLITE_STMTSTATUS_RUN = 6;
+
+const int SQLITE_STMTSTATUS_MEMUSED = 99;
+
+const int SQLITE_CHECKPOINT_PASSIVE = 0;
+
+const int SQLITE_CHECKPOINT_FULL = 1;
+
+const int SQLITE_CHECKPOINT_RESTART = 2;
+
+const int SQLITE_CHECKPOINT_TRUNCATE = 3;
+
+const int SQLITE_VTAB_CONSTRAINT_SUPPORT = 1;
+
+const int SQLITE_VTAB_INNOCUOUS = 2;
+
+const int SQLITE_VTAB_DIRECTONLY = 3;
+
+const int SQLITE_ROLLBACK = 1;
+
+const int SQLITE_FAIL = 3;
+
+const int SQLITE_REPLACE = 5;
+
+const int SQLITE_SCANSTAT_NLOOP = 0;
+
+const int SQLITE_SCANSTAT_NVISIT = 1;
+
+const int SQLITE_SCANSTAT_EST = 2;
+
+const int SQLITE_SCANSTAT_NAME = 3;
+
+const int SQLITE_SCANSTAT_EXPLAIN = 4;
+
+const int SQLITE_SCANSTAT_SELECTID = 5;
+
+const int SQLITE_SERIALIZE_NOCOPY = 1;
+
+const int SQLITE_DESERIALIZE_FREEONCLOSE = 1;
+
+const int SQLITE_DESERIALIZE_RESIZEABLE = 2;
+
+const int SQLITE_DESERIALIZE_READONLY = 4;
+
+const int NOT_WITHIN = 0;
+
+const int PARTLY_WITHIN = 1;
+
+const int FULLY_WITHIN = 2;
+
+const int FTS5_TOKENIZE_QUERY = 1;
+
+const int FTS5_TOKENIZE_PREFIX = 2;
+
+const int FTS5_TOKENIZE_DOCUMENT = 4;
+
+const int FTS5_TOKENIZE_AUX = 8;
+
+const int FTS5_TOKEN_COLOCATED = 1;
+
 typedef _c_sqlite3_libversion = ffi.Pointer<ffi.Int8> Function();
 
 typedef _dart_sqlite3_libversion = ffi.Pointer<ffi.Int8> Function();
diff --git a/test/prefix_tests/prefix.h b/test/prefix_tests/prefix.h
index 1e8b72d..d63d92a 100644
--- a/test/prefix_tests/prefix.h
+++ b/test/prefix_tests/prefix.h
@@ -2,6 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+#define Macro1 1
+#define Test_Macro2 2
+
 struct Struct1
 {
 };
diff --git a/test/prefix_tests/prefix_test.dart b/test/prefix_tests/prefix_test.dart
index abbe2b4..ba1e56d 100644
--- a/test/prefix_tests/prefix_test.dart
+++ b/test/prefix_tests/prefix_test.dart
@@ -15,10 +15,12 @@
 final functionPrefix = 'fff';
 final structPrefix = 'sss';
 final enumPrefix = 'eee';
+final macroPrefix = 'mmm';
 
 final functionPrefixReplacedWith = 'rf';
 final structPrefixReplacedWith = 'rs';
 final enumPrefixReplacedWith = 're';
+final macroPrefixReplacedWith = 'rm';
 
 void main() {
   group('prefix_test', () {
@@ -51,6 +53,10 @@
   ${strings.prefix_replacement}:
     'Test_': '$enumPrefixReplacedWith'
 
+macros:
+  ${strings.prefix}: $macroPrefix
+  ${strings.prefix_replacement}:
+    'Test_': '$macroPrefixReplacedWith'
     ''') as yaml.YamlMap));
     });
 
@@ -66,6 +72,10 @@
       expect(actual.getBindingAsString('${enumPrefix}Enum1'),
           expected.getBindingAsString('${enumPrefix}Enum1'));
     });
+    test('Macro prefix', () {
+      expect(actual.getBindingAsString('${macroPrefix}Macro1'),
+          expected.getBindingAsString('${macroPrefix}Macro1'));
+    });
     test('Function prefix-replacement', () {
       expect(
           actual.getBindingAsString(
@@ -87,6 +97,13 @@
           expected.getBindingAsString(
               '${enumPrefix}${enumPrefixReplacedWith}Enum2'));
     });
+    test('Macro prefix-replacement', () {
+      expect(
+          actual.getBindingAsString(
+              '${macroPrefix}${macroPrefixReplacedWith}Macro2'),
+          expected.getBindingAsString(
+              '${macroPrefix}${macroPrefixReplacedWith}Macro2'));
+    });
   });
 }
 
@@ -141,6 +158,18 @@
           EnumConstant(name: 'g', value: 2),
         ],
       ),
+      Constant(
+        originalName: 'Macro1',
+        name: '${macroPrefix}Macro1',
+        rawType: 'int',
+        rawValue: '1',
+      ),
+      Constant(
+        originalName: 'TestMacro2',
+        name: '${macroPrefix}${macroPrefixReplacedWith}Macro2',
+        rawType: 'int',
+        rawValue: '2',
+      ),
     ],
   );
 }
diff --git a/tool/libclang_config.yaml b/tool/libclang_config.yaml
index 8159870..bc0754c 100644
--- a/tool/libclang_config.yaml
+++ b/tool/libclang_config.yaml
@@ -32,6 +32,7 @@
       - CXTypeKind
       - CXDiagnosticDisplayOptions
       - CXTranslationUnit_Flags
+      - CXEvalResultKind
 
 structs:
   include:
@@ -54,6 +55,12 @@
       - clang_disposeDiagnostic
       - clang_parseTranslationUnit
       - clang_disposeTranslationUnit
+      - clang_EvalResult_getKind
+      - clang_EvalResult_getAsInt
+      - clang_EvalResult_getAsLongLong
+      - clang_EvalResult_getAsDouble
+      - clang_EvalResult_getAsStr
+      - clang_EvalResult_dispose
       - clang_getCString_wrap
       - clang_disposeString_wrap
       - clang_getCursorKind_wrap
@@ -85,3 +92,8 @@
       - clang_getFileName_wrap
       - clang_getNumElements_wrap
       - clang_getArrayElementType_wrap
+      - clang_Cursor_isMacroFunctionLike_wrap
+      - clang_Cursor_isMacroBuiltin_wrap
+      - clang_Cursor_Evaluate_wrap
+      - clang_Cursor_isAnonymous_wrap
+      - clang_Cursor_isAnonymousRecordDecl_wrap