Auto merge of #1425 - emilio:cexpr-up, r=emilio

Update cexpr.

Fixes #1424.
diff --git a/book/src/tutorial-1.md b/book/src/tutorial-1.md
index 161b1c5..3256a60 100644
--- a/book/src/tutorial-1.md
+++ b/book/src/tutorial-1.md
@@ -5,5 +5,5 @@
 
 ```toml
 [build-dependencies]
-bindgen = "0.26.3"
+bindgen = "0.42.2"
 ```
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 9237203..5f0ccc0 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -637,6 +637,7 @@
 
         let path = self.canonical_path(ctx);
         let name = path[1..].join("::");
+        ctx.options().blacklisted_items.matches(&name) ||
         match self.kind {
             ItemKind::Type(..) => {
                 ctx.options().blacklisted_types.matches(&name) ||
diff --git a/src/lib.rs b/src/lib.rs
index b7608ce..039bd39 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -311,6 +311,20 @@
             })
             .count();
 
+        self.options
+            .blacklisted_items
+            .get_items()
+            .iter()
+            .map(|item| {
+                output_vector.push("--blacklist-item".into());
+                output_vector.push(
+                    item.trim_left_matches("^")
+                        .trim_right_matches("$")
+                        .into(),
+                );
+            })
+            .count();
+
         if !self.options.layout_tests {
             output_vector.push("--no-layout-tests".into());
         }
@@ -754,6 +768,14 @@
         self
     }
 
+    /// Hide the given item from the generated bindings, regardless of
+    /// whether it's a type, function, module, etc. Regular
+    /// expressions are supported.
+    pub fn blacklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
+        self.options.blacklisted_items.insert(arg);
+        self
+    }
+
     /// Treat the given type as opaque in the generated bindings. Regular
     /// expressions are supported.
     pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
@@ -1313,6 +1335,10 @@
     /// in the generated code.
     blacklisted_functions: RegexSet,
 
+    /// The set of items, regardless of item-type, that have been
+    /// blacklisted and should not appear in the generated code.
+    blacklisted_items: RegexSet,
+
     /// The set of types that should be treated as opaque structures in the
     /// generated code.
     opaque_types: RegexSet,
@@ -1531,6 +1557,7 @@
         self.whitelisted_functions.build();
         self.blacklisted_types.build();
         self.blacklisted_functions.build();
+        self.blacklisted_items.build();
         self.opaque_types.build();
         self.bitfield_enums.build();
         self.constified_enums.build();
@@ -1564,6 +1591,7 @@
             rust_features: rust_target.into(),
             blacklisted_types: Default::default(),
             blacklisted_functions: Default::default(),
+            blacklisted_items: Default::default(),
             opaque_types: Default::default(),
             rustfmt_path: Default::default(),
             whitelisted_types: Default::default(),
diff --git a/src/options.rs b/src/options.rs
index ce89c23..3594be4 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -78,6 +78,13 @@
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
+            Arg::with_name("blacklist-item")
+                .long("blacklist-item")
+                .help("Mark <item> as hidden.")
+                .value_name("item")
+                .takes_value(true)
+                .multiple(true)
+                .number_of_values(1),
             Arg::with_name("no-layout-tests")
                 .long("no-layout-tests")
                 .help("Avoid generating layout tests for any type."),
@@ -370,6 +377,12 @@
         }
     }
 
+    if let Some(hidden_identifiers) = matches.values_of("blacklist-item") {
+        for id in hidden_identifiers {
+            builder = builder.blacklist_item(id);
+        }
+    }
+
     if matches.is_present("builtins") {
         builder = builder.emit_builtins();
     }
diff --git a/tests/expectations/tests/blacklist-item.rs b/tests/expectations/tests/blacklist-item.rs
new file mode 100644
index 0000000..b1d5564
--- /dev/null
+++ b/tests/expectations/tests/blacklist-item.rs
@@ -0,0 +1,26 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(
+    dead_code,
+    non_snake_case,
+    non_camel_case_types,
+    non_upper_case_globals
+)]
+
+#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
+pub mod root {
+    #[allow(unused_imports)]
+    use self::super::root;
+    pub mod foo {
+        #[allow(unused_imports)]
+        use self::super::super::root;
+    }
+    pub mod bar {
+        #[allow(unused_imports)]
+        use self::super::super::root;
+        extern "C" {
+            #[link_name = "\u{1}_ZN3bar18NamespacedFunctionEv"]
+            pub fn NamespacedFunction();
+        }
+    }
+}
diff --git a/tests/headers/blacklist-item.hpp b/tests/headers/blacklist-item.hpp
new file mode 100644
index 0000000..8d569dd
--- /dev/null
+++ b/tests/headers/blacklist-item.hpp
@@ -0,0 +1,21 @@
+// bindgen-flags: --blacklist-item "SomeFunction" --blacklist-item "SOME_DEFUN" --blacklist-item "someVar" --blacklist-item "ExternFunction" --blacklist-item "foo::NamespacedFunction" --blacklist-item "someClass.*" --enable-cxx-namespaces
+
+void SomeFunction();
+extern int someVar;
+#define SOME_DEFUN 123
+
+class someClass {
+  void somePrivateMethod();
+public:
+  void somePublicMethod(int foo);
+};
+
+extern "C" void ExternFunction();
+
+namespace foo {
+  void NamespacedFunction();
+}
+
+namespace bar {
+  void NamespacedFunction();
+}