diff --git a/Clang_utils.cpp b/Clang_utils.cpp
index d1bf4e32ac2ea9145a8e95e283e775830d98a2c4..5f86ad3fd67e7f111a4ef19f29fb1f188fc7fe3b 100644
--- a/Clang_utils.cpp
+++ b/Clang_utils.cpp
@@ -68,6 +68,10 @@ compare_qualified_name(qualified_name n1, qualified_name n2) {
 
 int compare_template_parameter(template_parameter tp1, template_parameter tp2);
 
+int compare_signature(signature s1, signature s2);
+
+int compare_capture(capture c1, capture c2);
+
 int
 compare_typ(typ t1, typ t2) {
   int result = 0;
@@ -158,11 +162,93 @@ compare_typ(typ t1, typ t2) {
         result = compare_qualified_name(t1->cons_typ.Named.name,
             t2->cons_typ.Named.name);
         break;
+      case LAMBDA:
+        result =
+          compare_signature(
+            t1->cons_typ.Lambda.proto, t2->cons_typ.Lambda.proto);
+        if (result==0) {
+          /* capture */ list l1 = t1->cons_typ.Lambda.closure;
+          /* capture */ list l2 = t2->cons_typ.Lambda.closure;
+          while (result == 0 && l1 && l2) {
+            result =
+              compare_capture(
+                (capture)l1->element.container,
+                (capture)l2->element.container);
+            l1 = l1->next;
+            l2 = l2->next;
+          }
+          if (result == 0 && (l1 || l2)) {
+            if (!l1) result = -1; else result = 1;
+          }
+        }
+        break;
     }
   };
   return result;
 }
 
+int compare_qual_type(qual_type t1, qual_type t2) {
+  int result = compare_typ(t1->plain_type, t2->plain_type);
+  if (result == 0) {
+    /* specifier */ list l1 = t1 -> qualifier;
+    /* specifier */ list l2 = t2 -> qualifier;
+    while (result == 0 && l1 && l2) {
+      if (l1->element.plain < l2->element.plain) result = -1;
+      if (l1->element.plain > l2->element.plain) result = 1;
+      l1 = l1 -> next; l2 = l2->next;
+    }
+    if (result != 0) return result;
+    if (l1 && !l2) return 1;
+    if (!l1 && l2) return -1;
+    return 0;
+  } else return result;
+}
+
+int compare_signature(signature s1, signature s2) {
+  int result = compare_qual_type(s1->result, s2->result);
+  if (result!=0) return result;
+  /* qual_type */ list l1 = s1->parameter;
+  /* qual_type */ list l2 = s2->parameter;
+  while (l1 && l2) {
+    result = compare_qual_type(
+      (qual_type)l1->element.container,(qual_type)l2->element.container);
+    if (result != 0) return result;
+    l1 = l1->next; l2 = l2->next;
+  }
+  if (l1 && !l2) return 1;
+  if (!l1 && l2) return -1;
+  if (s1->variadic && !s2->variadic) return 1;
+  if (!s1->variadic && s2->variadic) return -1;
+  return 0;
+}
+
+int compare_capture(capture c1, capture c2) {
+  if (c1->tag_capture < c2->tag_capture) return -1;
+  if (c2->tag_capture < c1->tag_capture) return 1;
+  switch(c1->tag_capture) {
+    case CAP_ID: {
+      int result =
+        compare_qual_type (c1->cons_capture.Cap_id.cap_id_type,
+                           c2->cons_capture.Cap_id.cap_id_type);
+      if (result !=0) return result;
+      if (c1->cons_capture.Cap_id.cap_id_ref &&
+          !c2->cons_capture.Cap_id.cap_id_ref) return 1;
+      if (!c1->cons_capture.Cap_id.cap_id_ref &&
+          c2->cons_capture.Cap_id.cap_id_ref) return -1;
+      return 0;
+    }
+    case CAP_THIS:
+      if (c1->cons_capture.Cap_this.cap_this_ref &&
+          !c2->cons_capture.Cap_this.cap_this_ref) return 1;
+      if (!c1->cons_capture.Cap_this.cap_this_ref &&
+          c2->cons_capture.Cap_this.cap_this_ref) return -1;
+      return 0;
+  }
+  /* we can only get there if c1->tag_capture
+     ends up not being an enum tag_capture */
+  assert(false);
+}
+
 int
 compare_compilation_constant(compilation_constant cc1, compilation_constant cc2)
 { int result = 0;