diff --git a/ccode/valaccodeparameter.vala b/ccode/valaccodeparameter.vala
index 9f1c2e1..9cc91ff 100644
--- a/ccode/valaccodeparameter.vala
+++ b/ccode/valaccodeparameter.vala
@@ -42,6 +42,14 @@ public class Vala.CCodeParameter : CCodeNode {
 	 */
 	public bool ellipsis { get; set; }
 
+	/**
+	 * This is a function pointer with no typedef'd name.
+	 *
+	 * type_name will contain the type with %s for the variable name. (e.g.,
+	 * int(*%s)())
+	 */
+	public bool is_anonymous_delegate { get; set; }
+
 	public CCodeParameter (string n, string type) {
 		name = n;
 		type_name = type;
@@ -52,12 +60,14 @@ public class Vala.CCodeParameter : CCodeNode {
 	}
 
 	public override void write (CCodeWriter writer) {
-		if (!ellipsis) {
+		if (ellipsis) {
+			writer.write_string ("...");
+		} else if (is_anonymous_delegate) {
+			writer.write_string (type_name.printf(name));
+		} else {
 			writer.write_string (type_name);
 			writer.write_string (" ");
 			writer.write_string (name);
-		} else {
-			writer.write_string ("...");
 		}
 	}
 }
diff --git a/ccode/valaccodestruct.vala b/ccode/valaccodestruct.vala
index 76f7679..2c72adf 100644
--- a/ccode/valaccodestruct.vala
+++ b/ccode/valaccodestruct.vala
@@ -59,9 +59,12 @@ public class Vala.CCodeStruct : CCodeNode {
 	 * @param type_name field type
 	 * @param name      member name
 	 */
-	public void add_field (string type_name, string name, string? declarator_suffix = null) {
+	public void add_field (string type_name, string name, string? declarator_suffix = null, bool anonymous_delegate = false) {
 		var decl = new CCodeDeclaration (type_name);
-		decl.add_declarator (new CCodeVariableDeclarator (name, null, declarator_suffix));
+		var decr = new CCodeVariableDeclarator (name, null, declarator_suffix);
+		decr.is_anonymous_delegate = anonymous_delegate;
+		decl.add_declarator (decr);
 		add_declaration (decl);
 	}
 	
diff --git a/ccode/valaccodevariabledeclarator.vala b/ccode/valaccodevariabledeclarator.vala
index 863ec83..7a9b256 100644
--- a/ccode/valaccodevariabledeclarator.vala
+++ b/ccode/valaccodevariabledeclarator.vala
@@ -47,6 +47,11 @@ public class Vala.CCodeVariableDeclarator : CCodeDeclarator {
 	 */
 	public bool init0 { get; set; }
 
+	/**
+	 * This is a function pointer with no typedef'd name.
+	 */
+	public bool is_anonymous_delegate { get; set; }
+
 	public CCodeVariableDeclarator (string name, CCodeExpression? initializer = null, string? declarator_suffix = null) {
 		this.name = name;
 		this.initializer = initializer;
@@ -61,10 +66,17 @@ public class Vala.CCodeVariableDeclarator : CCodeDeclarator {
 	}
 
 	public override void write (CCodeWriter writer) {
+		if (is_anonymous_delegate) {
+			writer.write_string("(*");
+		}
 		writer.write_string (name);
 		if (declarator_suffix != null) {
 			writer.write_string (declarator_suffix);
 		}
+		if (is_anonymous_delegate) {
+			writer.write_string(")()");
+		}
 
 		if (initializer != null) {
 			writer.write_string (" = ");
@@ -73,10 +85,17 @@ public class Vala.CCodeVariableDeclarator : CCodeDeclarator {
 	}
 
 	public override void write_declaration (CCodeWriter writer) {
+		if (is_anonymous_delegate) {
+			writer.write_string("(*");
+		}
 		writer.write_string (name);
 		if (declarator_suffix != null) {
 			writer.write_string (declarator_suffix);
 		}
+		if (is_anonymous_delegate) {
+			writer.write_string(")()");
+		}
 
 		if (initializer != null && init0) {
 			writer.write_string (" = ");
diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala
index cf7ce89..1fe030a 100644
--- a/codegen/valaccodeattribute.vala
+++ b/codegen/valaccodeattribute.vala
@@ -442,6 +442,7 @@ public class Vala.CCodeAttribute : AttributeCache {
 	public string? array_length_name { get; private set; }
 	public string? array_length_expr { get; private set; }
 	public bool delegate_target { get; private set; }
+	public bool anonymous_delegate { get; private set; }
 	public string sentinel { get; private set; }
 
 	private string _name;
@@ -497,6 +498,7 @@ public class Vala.CCodeAttribute : AttributeCache {
 				_pos = ccode.get_double ("pos");
 			}
 			delegate_target = ccode.get_bool ("delegate_target", true);
+			anonymous_delegate = ccode.get_bool ("anonymous_delegate");
 			sentinel = ccode.get_string ("sentinel");
 		}
 		if (node.get_attribute ("NoArrayLength") != null) {
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 0fd4c71..f2a7c63 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -920,13 +920,21 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 		generate_type_declaration (f.variable_type, decl_space);
 
-		string field_ctype = get_ccode_name (f.variable_type);
+		string field_ctype;
+		bool is_anonymous_delegate = get_ccode_anonymous_delegate(f.variable_type);
+		if (is_anonymous_delegate) {
+			field_ctype = get_ccode_name (((DelegateType)f.variable_type).delegate_symbol.return_type);
+	  } else {
+			field_ctype = get_ccode_name (f.variable_type);
+		}
 		if (f.is_volatile) {
 			field_ctype = "volatile " + field_ctype;
 		}
 
 		var cdecl = new CCodeDeclaration (field_ctype);
-		cdecl.add_declarator (new CCodeVariableDeclarator (get_ccode_name (f), null, get_ccode_declarator_suffix (f.variable_type)));
+		var cdecr = new CCodeVariableDeclarator (get_ccode_name (f), null, get_ccode_declarator_suffix (f.variable_type));
+		cdecr.is_anonymous_delegate = is_anonymous_delegate;
+		cdecl.add_declarator (cdecr);
 		if (f.is_private_symbol ()) {
 			cdecl.modifiers = CCodeModifiers.STATIC;
 		} else {
@@ -1007,7 +1015,15 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 		CCodeExpression lhs = null;
 
-		string field_ctype = get_ccode_name (f.variable_type);
+		string field_ctype;
+		bool is_anonymous_delegate = false;
+		if (f.variable_type is DelegateType && ((DelegateType)f.variable_type).delegate_symbol.anonymous_delegate) {
+			field_ctype = get_ccode_name(((DelegateType)f.variable_type).delegate_symbol.return_type);
+			is_anonymous_delegate = true;
+		} else {
+			field_ctype = get_ccode_name (f.variable_type);
+		}
+
 		if (f.is_volatile) {
 			field_ctype = "volatile " + field_ctype;
 		}
@@ -1107,7 +1123,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 			var var_decl = new CCodeVariableDeclarator (get_ccode_name (f), null, get_ccode_declarator_suffix (f.variable_type));
 			var_decl.initializer = default_value_for_type (f.variable_type, true);
-
+			var_decl.is_anonymous_delegate = is_anonymous_delegate;
 			if (class_init_context != null) {
 				push_context (class_init_context);
 			} else {
@@ -1710,7 +1727,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 		var param_type = param.variable_type.copy ();
 		param_type.value_owned = true;
-		data.add_field (get_ccode_name (param_type), get_variable_cname (param.name));
+		if (get_ccode_anonymous_delegate(param_type)) {
+			data.add_field (get_ccode_name (((DelegateType)param_type).delegate_symbol.return_type), get_variable_cname (param.name), null, true);
+		} else {
+			data.add_field (get_ccode_name (param_type), get_variable_cname (param.name));
+		}
 
 		bool is_unowned_delegate = param.variable_type is DelegateType && !param.variable_type.value_owned;
 
@@ -1789,7 +1810,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 				if (local.captured) {
 					generate_type_declaration (local.variable_type, cfile);
 
-					data.add_field (get_ccode_name (local.variable_type), get_local_cname (local) + get_ccode_declarator_suffix (local.variable_type));
+					if (get_ccode_anonymous_delegate(local.variable_type)) {
+						data.add_field (get_ccode_name (((DelegateType)local.variable_type).delegate_symbol.return_type), get_local_cname (local) + get_ccode_declarator_suffix (local.variable_type), null, true);
+					} else {
+						data.add_field (get_ccode_name (local.variable_type), get_local_cname (local) + get_ccode_declarator_suffix (local.variable_type));
+					}
 
 					if (local.variable_type is ArrayType) {
 						var array_type = (ArrayType) local.variable_type;
@@ -2171,8 +2196,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 					emit_context.closure_variable_clash_map.set (local, count);
 				}
 				emit_context.closure_variable_count_map.set (local.name, count + 1);
-
-				closure_struct.add_field (get_ccode_name (local.variable_type), get_local_cname (local) + get_ccode_declarator_suffix (local.variable_type));
+				if (get_ccode_anonymous_delegate(local.variable_type)) {
+					closure_struct.add_field (get_ccode_name (((DelegateType)local.variable_type).delegate_symbol.return_type), get_local_cname (local) + get_ccode_declarator_suffix (local.variable_type), null, true);
+				} else {
+					closure_struct.add_field (get_ccode_name (local.variable_type), get_local_cname (local) + get_ccode_declarator_suffix (local.variable_type));
+				}
 			} else {
 				var cvar = new CCodeVariableDeclarator (get_local_cname (local), null, get_ccode_declarator_suffix (local.variable_type));
 
@@ -2182,8 +2210,14 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 					cvar.initializer = default_value_for_type (local.variable_type, true);
 					cvar.init0 = true;
 				}
-
-				ccode.add_declaration (get_ccode_name (local.variable_type), cvar);
+				string ctypename;
+				if (local.variable_type is DelegateType && ((DelegateType)local.variable_type).delegate_symbol.anonymous_delegate) {
+					ctypename = get_ccode_name(((DelegateType)local.variable_type).delegate_symbol.return_type);
+					cvar.is_anonymous_delegate = true;
+				} else {
+					ctypename = get_ccode_name (local.variable_type);
+				}
+				ccode.add_declaration (ctypename, cvar);
 			}
 
 			if (local.variable_type is ArrayType) {
@@ -3185,7 +3219,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 	public void emit_temp_var (LocalVariable local) {
 		var init = !(local.name.has_prefix ("*") || local.no_init);
 		if (is_in_coroutine ()) {
-			closure_struct.add_field (get_ccode_name (local.variable_type), local.name);
+			if (get_ccode_anonymous_delegate(local.variable_type)) {
+				closure_struct.add_field (get_ccode_name (((DelegateType)local.variable_type).delegate_symbol.return_type), local.name, null, true);
+			} else {
+				closure_struct.add_field (get_ccode_name (local.variable_type), local.name);
+			}
 
 			// even though closure struct is zerod, we need to initialize temporary variables
 			// as they might be used multiple times when declared in a loop
@@ -3209,7 +3247,14 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 				cvar.initializer = default_value_for_type (local.variable_type, true);
 				cvar.init0 = true;
 			}
-			ccode.add_declaration (get_ccode_name (local.variable_type), cvar);
+			string ctype_name;
+			if (get_ccode_anonymous_delegate(local.variable_type)) {
+				ctype_name = get_ccode_name(((DelegateType)local.variable_type).delegate_symbol.return_type);
+				cvar.is_anonymous_delegate = true;
+			} else {
+				ctype_name = get_ccode_name (local.variable_type);
+			}
+			ccode.add_declaration (ctype_name, cvar);
 		}
 	}
 
@@ -5834,6 +5879,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		return get_ccode_attribute(node).delegate_target;
 	}
 
+	public static bool get_ccode_anonymous_delegate(DataType type) {
+		return (type is DelegateType) && ((DelegateType)type).delegate_symbol.anonymous_delegate;
+	}
+
 	public static double get_ccode_pos (Parameter param) {
 		return get_ccode_attribute(param).pos;
 	}
diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala
index 0c2242d..e8ffd35 100644
--- a/codegen/valaccodedelegatemodule.vala
+++ b/codegen/valaccodedelegatemodule.vala
@@ -446,20 +446,33 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
 		string ctypename = get_ccode_name (param.variable_type);
 		string target_ctypename = "void*";
 		string target_destroy_notify_ctypename = "GDestroyNotify";
+		bool is_anonymous = false;
+
+		if (param.variable_type is DelegateType
+		    && ((DelegateType)param.variable_type).delegate_symbol.anonymous_delegate) {
+			ctypename = get_ccode_name(((DelegateType)param.variable_type).delegate_symbol.return_type) + "(*%s)()";
+			is_anonymous = true;
+			if (param.direction != ParameterDirection.IN) {
+				ctypename = ctypename.printf("*%s");
+				target_ctypename += "*";
+				target_destroy_notify_ctypename += "*";
+			}
+		} else {
+			if (param.parent_symbol is Delegate
+			    && get_ccode_name (param.variable_type) == get_ccode_name (param.parent_symbol)) {
+				// recursive delegate
+				ctypename = "GCallback";
+			}
 
-		if (param.parent_symbol is Delegate
-		    && get_ccode_name (param.variable_type) == get_ccode_name (param.parent_symbol)) {
-			// recursive delegate
-			ctypename = "GCallback";
-		}
-
-		if (param.direction != ParameterDirection.IN) {
-			ctypename += "*";
-			target_ctypename += "*";
-			target_destroy_notify_ctypename += "*";
+			if (param.direction != ParameterDirection.IN) {
+				ctypename += "*";
+				target_ctypename += "*";
+				target_destroy_notify_ctypename += "*";
+			}
 		}
 
 		var main_cparam = new CCodeParameter (get_variable_cname (param.name), ctypename);
+		main_cparam.is_anonymous_delegate = is_anonymous;
 
 		cparam_map.set (get_param_pos (get_ccode_pos (param)), main_cparam);
 		if (carg_map != null) {
diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala
index b21829b..2ef3930 100644
--- a/codegen/valaccodestructmodule.vala
+++ b/codegen/valaccodestructmodule.vala
@@ -57,6 +57,10 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
 
 		foreach (Field f in st.get_fields ()) {
 			string field_ctype = get_ccode_name (f.variable_type);
+			bool is_anonymous_delegate = get_ccode_anonymous_delegate(f.variable_type);
+			if (is_anonymous_delegate) {
+				field_ctype = get_ccode_name(((DelegateType)f.variable_type).delegate_symbol.return_type);
+			}
 			if (f.is_volatile) {
 				field_ctype = "volatile " + field_ctype;
 			}
@@ -64,7 +68,7 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
 			if (f.binding == MemberBinding.INSTANCE)  {
 				generate_type_declaration (f.variable_type, decl_space);
 
-				instance_struct.add_field (field_ctype, get_ccode_name (f) + get_ccode_declarator_suffix (f.variable_type), f.deprecated ? " G_GNUC_DEPRECATED" : null);
+				instance_struct.add_field (field_ctype, get_ccode_name (f) + get_ccode_declarator_suffix (f.variable_type), f.deprecated ? " G_GNUC_DEPRECATED" : null, is_anonymous_delegate);
 				if (f.variable_type is ArrayType && get_ccode_array_length (f)) {
 					// create fields to store array dimensions
 					var array_type = (ArrayType) f.variable_type;
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 753d761..f3adf2f 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -304,6 +304,11 @@ public class Vala.GTypeModule : GErrorModule {
 
 		foreach (Field f in cl.get_fields ()) {
 			string field_ctype = get_ccode_name (f.variable_type);
+			bool is_anonymous_delegate = get_ccode_anonymous_delegate(f.variable_type);
+			if (is_anonymous_delegate) {
+				field_ctype = get_ccode_name(((DelegateType)f.variable_type).delegate_symbol.return_type);
+			}
+
 			if (f.is_volatile) {
 				field_ctype = "volatile " + field_ctype;
 			}
@@ -312,7 +317,7 @@ public class Vala.GTypeModule : GErrorModule {
 				if (f.binding == MemberBinding.INSTANCE) {
 					generate_type_declaration (f.variable_type, decl_space);
 
-					instance_struct.add_field (field_ctype, get_ccode_name (f), get_ccode_declarator_suffix (f.variable_type));
+					instance_struct.add_field (field_ctype, get_ccode_name (f), get_ccode_declarator_suffix (f.variable_type), is_anonymous_delegate);
 					if (f.variable_type is ArrayType && get_ccode_array_length (f)) {
 						// create fields to store array dimensions
 						var array_type = (ArrayType) f.variable_type;
@@ -419,7 +424,7 @@ public class Vala.GTypeModule : GErrorModule {
 				if (f.access == SymbolAccessibility.PRIVATE)  {
 					generate_type_declaration (f.variable_type, decl_space);
 
-					instance_priv_struct.add_field (field_ctype, get_ccode_name (f), get_ccode_declarator_suffix (f.variable_type));
+					instance_priv_struct.add_field (field_ctype, get_ccode_name (f), get_ccode_declarator_suffix (f.variable_type), get_ccode_anonymous_delegate(f.variable_type));
 					if (f.variable_type is ArrayType && get_ccode_array_length (f)) {
 						// create fields to store array dimensions
 						var array_type = (ArrayType) f.variable_type;
diff --git a/vala/valadelegate.vala b/vala/valadelegate.vala
index d949c61..6d9fd85 100644
--- a/vala/valadelegate.vala
+++ b/vala/valadelegate.vala
@@ -59,6 +59,12 @@ public class Vala.Delegate : TypeSymbol {
 		}
 	}
 
+	public bool anonymous_delegate {
+		get {
+			return get_attribute_bool ("CCode", "anonymous_delegate");
+		}
+	}
+
 	public DataType? sender_type { get; set; }
 
 	private List<TypeParameter> type_parameters = new ArrayList<TypeParameter> ();
diff --git a/vapi/posix.vapi b/vapi/posix.vapi
index 9578263..87a494e 100644
--- a/vapi/posix.vapi
+++ b/vapi/posix.vapi
@@ -2490,7 +2490,7 @@ namespace Posix {
 		}
 	}
 
-	[CCode (has_target = false)]
+	[CCode (has_target = false, anonymous_delegate = true)]
 	public delegate int GlobErrorFunction (string filename, int errcode);
 
 	[CCode (cheader_filename = "glob.h")]
