Add --no-default <regex> flag

Sometimes, we need customize the implement of `Default` for certain types,
In these cases, the `nodefault` annotation can be used to prevent bindgen
to autoderive the `Default` traits for a type.
diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md
index e2347fb..16291c3 100644
--- a/book/src/SUMMARY.md
+++ b/book/src/SUMMARY.md
@@ -18,6 +18,7 @@
     - [Replacing One Type with Another](./replacing-types.md)
     - [Preventing the Derivation of `Copy` and `Clone`](./nocopy.md)
     - [Preventing the Derivation of `Debug`](./nodebug.md)
+    - [Preventing the Derivation of `Default`](./nodefault.md)
 - [Generating Bindings to C++](./cpp.md)
 - [Generating Bindings to Objective-c](./objc.md)
 - [Using Unions](./using-unions.md)
diff --git a/book/src/nodefault.md b/book/src/nodefault.md
new file mode 100644
index 0000000..37896f6
--- /dev/null
+++ b/book/src/nodefault.md
@@ -0,0 +1,48 @@
+# Preventing the Derivation of `Default`
+
+`bindgen` will attempt to derive/impl the `Default` traits on a best-effort basis.
+Sometimes, we need customize the implement of `Default` for certain types,
+In these cases, the `nodefault` annotation can be used to prevent bindgen 
+to autoderive the `Default` traits for a type.
+
+### Library
+
+* [`bindgen::Builder::no_default`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.no_default)
+
+### Command Line
+
+* `--no-default <regex>`
+
+### Annotations
+
+```c
+/**
+ * We need to specify some preset values as the Default of Header.
+ *
+ * for example:
+ *
+ * <div rustbindgen nodefault></div>
+ */
+struct Header {
+    unsigned int magic;
+    unsigned char data[252];
+};
+
+...
+```
+
+### Customize Implements
+
+```rust,ignore
+// Include the generated bindings.
+include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+
+impl Default for Header {
+    fn default() -> Self {
+        Self {
+            magic: 0x10203040u32,
+            data: [0; 252usize],
+        }
+    }
+}
+```
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 754c2c8..15aea22 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -118,7 +118,7 @@
         derivable_traits |= DerivableTraits::DEBUG;
     }
 
-    if item.can_derive_default(ctx) {
+    if item.can_derive_default(ctx) && !item.annotations().disallow_default() {
         derivable_traits |= DerivableTraits::DEFAULT;
     }
 
@@ -1900,8 +1900,10 @@
         }
 
         if !derivable_traits.contains(DerivableTraits::DEFAULT) {
-            needs_default_impl =
-                ctx.options().derive_default && !self.is_forward_declaration();
+            needs_default_impl = ctx.options().derive_default &&
+                !self.is_forward_declaration() &&
+                !ctx.no_default_by_name(item) &&
+                !item.annotations().disallow_default();
         }
 
         let all_template_params = item.all_template_params(ctx);
diff --git a/src/ir/analysis/derive.rs b/src/ir/analysis/derive.rs
index 48c544f..6c50fa6 100644
--- a/src/ir/analysis/derive.rs
+++ b/src/ir/analysis/derive.rs
@@ -446,11 +446,11 @@
         match self {
             DeriveTrait::Copy => ctx.no_copy_by_name(item),
             DeriveTrait::Debug => ctx.no_debug_by_name(item),
+            DeriveTrait::Default => ctx.no_default_by_name(item),
             DeriveTrait::Hash => ctx.no_hash_by_name(item),
             DeriveTrait::PartialEqOrPartialOrd => {
                 ctx.no_partialeq_by_name(item)
             }
-            _ => false,
         }
     }
 
diff --git a/src/ir/annotations.rs b/src/ir/annotations.rs
index da4ef4f..12664f6 100644
--- a/src/ir/annotations.rs
+++ b/src/ir/annotations.rs
@@ -40,6 +40,8 @@
     disallow_copy: bool,
     /// Manually disable deriving debug on this type.
     disallow_debug: bool,
+    /// Manually disable deriving/implement default on this type.
+    disallow_default: bool,
     /// Whether fields should be marked as private or not. You can set this on
     /// structs (it will apply to all the fields), or individual fields.
     private_fields: Option<bool>,
@@ -81,6 +83,7 @@
             use_instead_of: None,
             disallow_copy: false,
             disallow_debug: false,
+            disallow_default: false,
             private_fields: None,
             accessor_kind: None,
             constify_enum_variant: false,
@@ -155,6 +158,11 @@
         self.disallow_debug
     }
 
+    /// Should we avoid implementing the `Default` trait?
+    pub fn disallow_default(&self) -> bool {
+        self.disallow_default
+    }
+
     /// Should the fields be private?
     pub fn private_fields(&self) -> Option<bool> {
         self.private_fields
@@ -181,6 +189,7 @@
                     "hide" => self.hide = true,
                     "nocopy" => self.disallow_copy = true,
                     "nodebug" => self.disallow_debug = true,
+                    "nodefault" => self.disallow_default = true,
                     "replaces" => {
                         self.use_instead_of = Some(
                             attr.value.split("::").map(Into::into).collect(),
diff --git a/src/ir/context.rs b/src/ir/context.rs
index bb0c3f9..1a54375 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -2591,6 +2591,12 @@
         self.options().no_debug_types.matches(&name)
     }
 
+    /// Check if `--no-default` flag is enabled for this item.
+    pub fn no_default_by_name(&self, item: &Item) -> bool {
+        let name = item.path_for_whitelisting(self)[1..].join("::");
+        self.options().no_default_types.matches(&name)
+    }
+
     /// Check if `--no-hash` flag is enabled for this item.
     pub fn no_hash_by_name(&self, item: &Item) -> bool {
         let name = item.path_for_whitelisting(self)[1..].join("::");
diff --git a/src/lib.rs b/src/lib.rs
index 37c301d..09410b5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -298,6 +298,7 @@
             (&self.options.no_partialeq_types, "--no-partialeq"),
             (&self.options.no_copy_types, "--no-copy"),
             (&self.options.no_debug_types, "--no-debug"),
+            (&self.options.no_default_types, "--no-default"),
             (&self.options.no_hash_types, "--no-hash"),
         ];
 
@@ -1446,6 +1447,13 @@
         self
     }
 
+    /// Don't derive/impl `Default` for a given type. Regular
+    /// expressions are supported.
+    pub fn no_default<T: Into<String>>(mut self, arg: T) -> Self {
+        self.options.no_default_types.insert(arg.into());
+        self
+    }
+
     /// Don't derive `Hash` for a given type. Regular
     /// expressions are supported.
     pub fn no_hash<T: Into<String>>(mut self, arg: T) -> Builder {
@@ -1745,6 +1753,9 @@
     /// The set of types that we should not derive `Debug` for.
     no_debug_types: RegexSet,
 
+    /// The set of types that we should not derive/impl `Default` for.
+    no_default_types: RegexSet,
+
     /// The set of types that we should not derive `Hash` for.
     no_hash_types: RegexSet,
 
@@ -1786,6 +1797,7 @@
             &mut self.no_partialeq_types,
             &mut self.no_copy_types,
             &mut self.no_debug_types,
+            &mut self.no_default_types,
             &mut self.no_hash_types,
         ];
         let record_matches = self.record_matches;
@@ -1886,6 +1898,7 @@
             no_partialeq_types: Default::default(),
             no_copy_types: Default::default(),
             no_debug_types: Default::default(),
+            no_default_types: Default::default(),
             no_hash_types: Default::default(),
             array_pointers_in_arguments: false,
             wasm_import_module_name: None,
diff --git a/src/options.rs b/src/options.rs
index 8c85aba..657c3c9 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -451,6 +451,13 @@
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
+            Arg::with_name("no-default")
+                .long("no-default")
+                .help("Avoid deriving/implement Default for types matching <regex>.")
+                .value_name("regex")
+                .takes_value(true)
+                .multiple(true)
+                .number_of_values(1),
             Arg::with_name("no-hash")
                 .long("no-hash")
                 .help("Avoid deriving Hash for types matching <regex>.")
@@ -871,6 +878,12 @@
         }
     }
 
+    if let Some(no_default) = matches.values_of("no-default") {
+        for regex in no_default {
+            builder = builder.no_default(regex);
+        }
+    }
+
     if let Some(no_hash) = matches.values_of("no-hash") {
         for regex in no_hash {
             builder = builder.no_hash(regex);
diff --git a/tests/expectations/tests/no_default.rs b/tests/expectations/tests/no_default.rs
new file mode 100644
index 0000000..27ea303
--- /dev/null
+++ b/tests/expectations/tests/no_default.rs
@@ -0,0 +1,23 @@
+#![allow(
+    dead_code,
+    non_snake_case,
+    non_camel_case_types,
+    non_upper_case_globals
+)]
+
+/// <div rustbindgen nodefault></div>
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct DefaultButWait {
+    pub whatever: ::std::os::raw::c_int,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct DefaultButWaitDerived {
+    pub whatever: DefaultButWait,
+}
+impl Default for DefaultButWaitDerived {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
diff --git a/tests/expectations/tests/no_default_bypass_derive_default.rs b/tests/expectations/tests/no_default_bypass_derive_default.rs
new file mode 100644
index 0000000..4b97e3f
--- /dev/null
+++ b/tests/expectations/tests/no_default_bypass_derive_default.rs
@@ -0,0 +1,22 @@
+#![allow(
+    dead_code,
+    non_snake_case,
+    non_camel_case_types,
+    non_upper_case_globals
+)]
+
+#[repr(C)]
+pub struct Generic<T> {
+    pub t: [T; 40usize],
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+impl<T> Default for Generic<T> {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+#[repr(C)]
+pub struct NoDefault<T> {
+    pub t: [T; 40usize],
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
diff --git a/tests/expectations/tests/no_default_opaque.rs b/tests/expectations/tests/no_default_opaque.rs
new file mode 100644
index 0000000..3c92855
--- /dev/null
+++ b/tests/expectations/tests/no_default_opaque.rs
@@ -0,0 +1,26 @@
+#![allow(
+    dead_code,
+    non_snake_case,
+    non_camel_case_types,
+    non_upper_case_globals
+)]
+
+#[repr(C)]
+#[repr(align(4))]
+#[derive(Debug, Copy, Clone)]
+pub struct NoDefault {
+    pub _bindgen_opaque_blob: u32,
+}
+#[test]
+fn bindgen_test_layout_NoDefault() {
+    assert_eq!(
+        ::std::mem::size_of::<NoDefault>(),
+        4usize,
+        concat!("Size of: ", stringify!(NoDefault))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<NoDefault>(),
+        4usize,
+        concat!("Alignment of ", stringify!(NoDefault))
+    );
+}
diff --git a/tests/expectations/tests/no_default_whitelisted.rs b/tests/expectations/tests/no_default_whitelisted.rs
new file mode 100644
index 0000000..980f157
--- /dev/null
+++ b/tests/expectations/tests/no_default_whitelisted.rs
@@ -0,0 +1,35 @@
+#![allow(
+    dead_code,
+    non_snake_case,
+    non_camel_case_types,
+    non_upper_case_globals
+)]
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct NoDefault {
+    pub i: ::std::os::raw::c_int,
+}
+#[test]
+fn bindgen_test_layout_NoDefault() {
+    assert_eq!(
+        ::std::mem::size_of::<NoDefault>(),
+        4usize,
+        concat!("Size of: ", stringify!(NoDefault))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<NoDefault>(),
+        4usize,
+        concat!("Alignment of ", stringify!(NoDefault))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<NoDefault>())).i as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(NoDefault),
+            "::",
+            stringify!(i)
+        )
+    );
+}
diff --git a/tests/headers/no_default.hpp b/tests/headers/no_default.hpp
new file mode 100644
index 0000000..79d25fb
--- /dev/null
+++ b/tests/headers/no_default.hpp
@@ -0,0 +1,11 @@
+
+/** <div rustbindgen nodefault></div> */
+template<typename T>
+class DefaultButWait {
+    int whatever;
+};
+
+template<typename T>
+class DefaultButWaitDerived {
+    DefaultButWait<T> whatever;
+};
diff --git a/tests/headers/no_default_bypass_derive_default.hpp b/tests/headers/no_default_bypass_derive_default.hpp
new file mode 100644
index 0000000..0f83390
--- /dev/null
+++ b/tests/headers/no_default_bypass_derive_default.hpp
@@ -0,0 +1,11 @@
+// bindgen-flags: --no-default "NoDefault"
+
+template<typename T>
+class Generic {
+  T t[40];
+};
+
+template<typename T>
+class NoDefault {
+  T t[40];
+};
diff --git a/tests/headers/no_default_opaque.hpp b/tests/headers/no_default_opaque.hpp
new file mode 100644
index 0000000..3245d8f
--- /dev/null
+++ b/tests/headers/no_default_opaque.hpp
@@ -0,0 +1,5 @@
+// bindgen-flags: --opaque-type "NoDefault" --no-default "NoDefault"
+
+class NoDefault {
+  int i;
+};
diff --git a/tests/headers/no_default_whitelisted.hpp b/tests/headers/no_default_whitelisted.hpp
new file mode 100644
index 0000000..12676be
--- /dev/null
+++ b/tests/headers/no_default_whitelisted.hpp
@@ -0,0 +1,5 @@
+// bindgen-flags: --whitelist-type "NoDefault" --no-default "NoDefault"
+
+class NoDefault {
+  int i;
+};