diff --git a/Documentation/hawkmoth/VERSION b/Documentation/hawkmoth/VERSION
index bd73f47072b1fe4b9914ec14a7f6d47fcc8f816a..2eb3c4fe4eebcdea3da0790cc0ba74cb286ec4f4 100644
--- a/Documentation/hawkmoth/VERSION
+++ b/Documentation/hawkmoth/VERSION
@@ -1 +1 @@
-0.4
+0.5
diff --git a/Documentation/hawkmoth/parser.py b/Documentation/hawkmoth/parser.py
index a070ad1cd0d38dcb83c854b154930ab4d385c549..d06321731c8ef69f2845427a9a8fcda88eb6bb67 100644
--- a/Documentation/hawkmoth/parser.py
+++ b/Documentation/hawkmoth/parser.py
@@ -34,7 +34,6 @@ Otherwise, documentation comments are passed through verbatim.
 """
 
 import enum
-import itertools
 import sys
 
 from clang.cindex import CursorKind, TypeKind
@@ -75,18 +74,22 @@ def comment_extract(tu):
             current_comment = token
             continue
 
+        # Store off the token's cursor for a slight performance improvement
+        # instead of accessing the `cursor` property multiple times.
+        token_cursor = token.cursor
+
         # cursors that are 1) never documented themselves, and 2) allowed
         # between comment and the actual cursor being documented
-        if (token.cursor.kind == CursorKind.INVALID_FILE or
-            token.cursor.kind == CursorKind.TYPE_REF or
-            token.cursor.kind == CursorKind.PREPROCESSING_DIRECTIVE or
-            token.cursor.kind == CursorKind.MACRO_INSTANTIATION):
+        if (token_cursor.kind == CursorKind.INVALID_FILE or
+            token_cursor.kind == CursorKind.TYPE_REF or
+            token_cursor.kind == CursorKind.PREPROCESSING_DIRECTIVE or
+            token_cursor.kind == CursorKind.MACRO_INSTANTIATION):
             continue
 
-        if cursor is not None and token.cursor == cursor:
+        if cursor is not None and token_cursor == cursor:
             continue
 
-        cursor = token.cursor
+        cursor = token_cursor
 
         # Note: current_comment may be None
         if current_comment != None and docstr.is_doc(current_comment.spelling):
@@ -125,16 +128,18 @@ def _get_macro_args(cursor):
     if cursor.kind != CursorKind.MACRO_DEFINITION:
         return None
 
+    tokens = cursor.get_tokens()
+
     # Use the first two tokens to make sure this starts with 'IDENTIFIER('
-    x = [token for token in itertools.islice(cursor.get_tokens(), 2)]
-    if (len(x) != 2 or x[0].spelling != cursor.spelling or
-        x[1].spelling != '(' or x[0].extent.end != x[1].extent.start):
+    one = next(tokens)
+    two = next(tokens, None)
+    if two is None or one.extent.end != two.extent.start or two.spelling != '(':
         return None
 
     # Naïve parsing of macro arguments
     # FIXME: This doesn't handle GCC named vararg extension FOO(vararg...)
     args = []
-    for token in itertools.islice(cursor.get_tokens(), 2, None):
+    for token in tokens:
         if token.spelling == ')':
             return args
         elif token.spelling == ',':