Snap for 6533464 from 98780c6c162e8a7804eb906eb1cda968c98f9791 to sdk-release

Change-Id: Ief1d584c24e2ad55287d685ec3f895eefca5967a
diff --git a/METADATA b/METADATA
index 0eea29b..cfcfea7 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@
     type: GIT
     value: "https://github.com/google/benchmark.git"
   }
-  version: "a77d5f70efaebe2b7e8c10134526a23a7ce7ef35"
+  version: "d3ad0b9d11c190cb58de5fb17c3555def61fdc96"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 4
+    month: 5
     day: 13
   }
 }
diff --git a/WORKSPACE b/WORKSPACE
index 8df248a..dc6ea02 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -13,3 +13,18 @@
     strip_prefix = "googletest-3f0cf6b62ad1eb50d8736538363d3580dd640c3e",
     urls = ["https://github.com/google/googletest/archive/3f0cf6b62ad1eb50d8736538363d3580dd640c3e.zip"],
 )
+
+http_archive(
+    name = "pybind11",
+    build_file = "@//bindings/python:pybind11.BUILD",
+    sha256 = "1eed57bc6863190e35637290f97a20c81cfe4d9090ac0a24f3bbf08f265eb71d",
+    strip_prefix = "pybind11-2.4.3",
+    urls = ["https://github.com/pybind/pybind11/archive/v2.4.3.tar.gz"],
+)
+
+new_local_repository(
+    name = "python_headers",
+    build_file = "@//bindings/python:python_headers.BUILD",
+    path = "/usr/include/python3.6",  # May be overwritten by setup.py.
+)
+
diff --git a/bindings/python/BUILD b/bindings/python/BUILD
new file mode 100644
index 0000000..9559a76
--- /dev/null
+++ b/bindings/python/BUILD
@@ -0,0 +1,3 @@
+exports_files(glob(["*.BUILD"]))
+exports_files(["build_defs.bzl"])
+
diff --git a/bindings/python/benchmark/BUILD b/bindings/python/benchmark/BUILD
new file mode 100644
index 0000000..49f536e
--- /dev/null
+++ b/bindings/python/benchmark/BUILD
@@ -0,0 +1,38 @@
+load("//bindings/python:build_defs.bzl", "py_extension")
+
+py_library(
+    name = "benchmark",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = [
+        ":_benchmark",
+        # pip; absl:app
+    ],
+)
+
+py_extension(
+    name = "_benchmark",
+    srcs = ["benchmark.cc"],
+    copts = [
+        "-fexceptions",
+        "-fno-strict-aliasing",
+    ],
+    features = ["-use_header_modules"],
+    deps = [
+        "//:benchmark",
+        "@pybind11",
+        "@python_headers",
+    ],
+)
+
+py_test(
+    name = "example",
+    srcs = ["example.py"],
+    python_version = "PY3",
+    srcs_version = "PY3",
+    visibility = ["//visibility:public"],
+    deps = [
+        ":benchmark",
+    ],
+)
+
diff --git a/bindings/python/benchmark/__init__.py b/bindings/python/benchmark/__init__.py
new file mode 100644
index 0000000..27f76e0
--- /dev/null
+++ b/bindings/python/benchmark/__init__.py
@@ -0,0 +1,62 @@
+# Copyright 2020 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Python benchmarking utilities.
+
+Example usage:
+  import benchmark
+
+  @benchmark.register
+  def my_benchmark(state):
+      ...  # Code executed outside `while` loop is not timed.
+
+      while state:
+        ...  # Code executed within `while` loop is timed.
+
+  if __name__ == '__main__':
+    benchmark.main()
+"""
+
+from absl import app
+from benchmark import _benchmark
+
+__all__ = [
+    "register",
+    "main",
+]
+
+__version__ = "0.1.0"
+
+
+def register(f=None, *, name=None):
+  if f is None:
+    return lambda f: register(f, name=name)
+  if name is None:
+    name = f.__name__
+  _benchmark.RegisterBenchmark(name, f)
+  return f
+
+
+def _flags_parser(argv):
+  argv = _benchmark.Initialize(argv)
+  return app.parse_flags_with_usage(argv)
+
+
+def _run_benchmarks(argv):
+  if len(argv) > 1:
+    raise app.UsageError('Too many command-line arguments.')
+  return _benchmark.RunSpecifiedBenchmarks()
+
+
+def main(argv=None):
+  return app.run(_run_benchmarks, argv=argv, flags_parser=_flags_parser)
diff --git a/bindings/python/benchmark/benchmark.cc b/bindings/python/benchmark/benchmark.cc
new file mode 100644
index 0000000..ef95559
--- /dev/null
+++ b/bindings/python/benchmark/benchmark.cc
@@ -0,0 +1,47 @@
+// Benchmark for Python.
+
+#include "benchmark/benchmark.h"
+#include "pybind11/pybind11.h"
+#include "pybind11/stl.h"
+
+namespace {
+namespace py = ::pybind11;
+
+std::vector<std::string> Initialize(const std::vector<std::string>& argv) {
+  // The `argv` pointers here become invalid when this function returns, but
+  // benchmark holds the pointer to `argv[0]`. We create a static copy of it
+  // so it persists, and replace the pointer below.
+  static std::string executable_name(argv[0]);
+  std::vector<char*> ptrs;
+  ptrs.reserve(argv.size());
+  for (auto& arg : argv) {
+    ptrs.push_back(const_cast<char*>(arg.c_str()));
+  }
+  ptrs[0] = const_cast<char*>(executable_name.c_str());
+  int argc = static_cast<int>(argv.size());
+  benchmark::Initialize(&argc, ptrs.data());
+  std::vector<std::string> remaining_argv;
+  remaining_argv.reserve(argc);
+  for (int i = 0; i < argc; ++i) {
+    remaining_argv.emplace_back(ptrs[i]);
+  }
+  return remaining_argv;
+}
+
+void RegisterBenchmark(const char* name, py::function f) {
+  benchmark::RegisterBenchmark(name, [f](benchmark::State& state) {
+    f(&state);
+  });
+}
+
+PYBIND11_MODULE(_benchmark, m) {
+  m.def("Initialize", Initialize);
+  m.def("RegisterBenchmark", RegisterBenchmark);
+  m.def("RunSpecifiedBenchmarks",
+        []() { benchmark::RunSpecifiedBenchmarks(); });
+
+  py::class_<benchmark::State>(m, "State")
+      .def("__bool__", &benchmark::State::KeepRunning)
+      .def_property_readonly("keep_running", &benchmark::State::KeepRunning);
+};
+}  // namespace
diff --git a/bindings/python/benchmark/example.py b/bindings/python/benchmark/example.py
new file mode 100644
index 0000000..24da127
--- /dev/null
+++ b/bindings/python/benchmark/example.py
@@ -0,0 +1,32 @@
+# Copyright 2020 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Example of Python using C++ benchmark framework."""
+
+import benchmark
+
+
+@benchmark.register
+def empty(state):
+  while state:
+    pass
+
+
+@benchmark.register
+def sum_million(state):
+  while state:
+    sum(range(1_000_000))
+
+
+if __name__ == '__main__':
+  benchmark.main()
diff --git a/bindings/python/build_defs.bzl b/bindings/python/build_defs.bzl
new file mode 100644
index 0000000..45907aa
--- /dev/null
+++ b/bindings/python/build_defs.bzl
@@ -0,0 +1,25 @@
+_SHARED_LIB_SUFFIX = {
+    "//conditions:default": ".so",
+    "//:windows": ".dll",
+}
+
+def py_extension(name, srcs, hdrs = [], copts = [], features = [], deps = []):
+    for shared_lib_suffix in _SHARED_LIB_SUFFIX.values():
+        shared_lib_name = name + shared_lib_suffix
+        native.cc_binary(
+            name = shared_lib_name,
+            linkshared = 1,
+            linkstatic = 1,
+            srcs = srcs + hdrs,
+            copts = copts,
+            features = features,
+            deps = deps,
+        )
+
+    return native.py_library(
+        name = name,
+        data = select({
+            platform: [name + shared_lib_suffix]
+            for platform, shared_lib_suffix in _SHARED_LIB_SUFFIX.items()
+        }),
+    )
diff --git a/bindings/python/pybind11.BUILD b/bindings/python/pybind11.BUILD
new file mode 100644
index 0000000..bc83350
--- /dev/null
+++ b/bindings/python/pybind11.BUILD
@@ -0,0 +1,20 @@
+cc_library(
+    name = "pybind11",
+    hdrs = glob(
+        include = [
+            "include/pybind11/*.h",
+            "include/pybind11/detail/*.h",
+        ],
+        exclude = [
+            "include/pybind11/common.h",
+            "include/pybind11/eigen.h",
+        ],
+    ),
+    copts = [
+        "-fexceptions",
+        "-Wno-undefined-inline",
+        "-Wno-pragma-once-outside-header",
+    ],
+    includes = ["include"],
+    visibility = ["//visibility:public"],
+)
diff --git a/bindings/python/python_headers.BUILD b/bindings/python/python_headers.BUILD
new file mode 100644
index 0000000..9c34cf6
--- /dev/null
+++ b/bindings/python/python_headers.BUILD
@@ -0,0 +1,6 @@
+cc_library(
+    name = "python_headers",
+    hdrs = glob(["**/*.h"]),
+    includes = ["."],
+    visibility = ["//visibility:public"],
+)
diff --git a/bindings/python/requirements.txt b/bindings/python/requirements.txt
new file mode 100644
index 0000000..f5bbe7e
--- /dev/null
+++ b/bindings/python/requirements.txt
@@ -0,0 +1,2 @@
+absl-py>=0.7.1
+
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..f4c0633
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,124 @@
+import os
+import posixpath
+import re
+import shutil
+import sys
+
+from distutils import sysconfig
+import setuptools
+from setuptools.command import build_ext
+
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+
+IS_WINDOWS = sys.platform.startswith('win')
+
+
+def _get_version():
+  """Parse the version string from __init__.py."""
+  with open(os.path.join(here, 'bindings', 'python', 'benchmark', '__init__.py')) as f:
+    try:
+      version_line = next(
+          line for line in f if line.startswith('__version__'))
+    except StopIteration:
+      raise ValueError('__version__ not defined in __init__.py')
+    else:
+      ns = {}
+      exec(version_line, ns)  # pylint: disable=exec-used
+      return ns['__version__']
+
+
+def _parse_requirements(path):
+  with open(os.path.join(here, path)) as f:
+    return [
+        line.rstrip() for line in f
+        if not (line.isspace() or line.startswith('#'))
+    ]
+
+
+class BazelExtension(setuptools.Extension):
+  """A C/C++ extension that is defined as a Bazel BUILD target."""
+
+  def __init__(self, name, bazel_target):
+    self.bazel_target = bazel_target
+    self.relpath, self.target_name = (
+        posixpath.relpath(bazel_target, '//').split(':'))
+    setuptools.Extension.__init__(self, name, sources=[])
+
+
+class BuildBazelExtension(build_ext.build_ext):
+  """A command that runs Bazel to build a C/C++ extension."""
+
+  def run(self):
+    for ext in self.extensions:
+      self.bazel_build(ext)
+    build_ext.build_ext.run(self)
+
+  def bazel_build(self, ext):
+    with open('WORKSPACE', 'r') as f:
+      workspace_contents = f.read()
+
+    with open('WORKSPACE', 'w') as f:
+      f.write(re.sub(
+          r'(?<=path = ").*(?=",  # May be overwritten by setup\.py\.)',
+          sysconfig.get_python_inc().replace(os.path.sep, posixpath.sep),
+          workspace_contents))
+
+    if not os.path.exists(self.build_temp):
+      os.makedirs(self.build_temp)
+
+    bazel_argv = [
+        'bazel',
+        'build',
+        ext.bazel_target,
+        '--symlink_prefix=' + os.path.join(self.build_temp, 'bazel-'),
+        '--compilation_mode=' + ('dbg' if self.debug else 'opt'),
+    ]
+
+    if IS_WINDOWS:
+      # Link with python*.lib.
+      for library_dir in self.library_dirs:
+        bazel_argv.append('--linkopt=/LIBPATH:' + library_dir)
+
+    self.spawn(bazel_argv)
+
+    shared_lib_suffix = '.dll' if IS_WINDOWS else '.so'
+    ext_bazel_bin_path = os.path.join(
+        self.build_temp, 'bazel-bin',
+        ext.relpath, ext.target_name + shared_lib_suffix)
+    ext_dest_path = self.get_ext_fullpath(ext.name)
+    ext_dest_dir = os.path.dirname(ext_dest_path)
+    if not os.path.exists(ext_dest_dir):
+      os.makedirs(ext_dest_dir)
+    shutil.copyfile(ext_bazel_bin_path, ext_dest_path)
+
+
+setuptools.setup(
+    name='google-benchmark',
+    version=_get_version(),
+    url='https://github.com/google/benchmark',
+    description='A library to benchmark code snippets.',
+    author='Google',
+    author_email='benchmark-py@google.com',
+    # Contained modules and scripts.
+    package_dir={'': 'bindings/python'},
+    packages=setuptools.find_packages('bindings/python'),
+    install_requires=_parse_requirements('bindings/python/requirements.txt'),
+    cmdclass=dict(build_ext=BuildBazelExtension),
+    ext_modules=[BazelExtension('benchmark._benchmark', '//bindings/python/benchmark:_benchmark')],
+    zip_safe=False,
+    # PyPI package information.
+    classifiers=[
+        'Development Status :: 4 - Beta',
+        'Intended Audience :: Developers',
+        'Intended Audience :: Science/Research',
+        'License :: OSI Approved :: Apache Software License',
+        'Programming Language :: Python :: 3.6',
+        'Programming Language :: Python :: 3.7',
+        'Topic :: Software Development :: Testing',
+        'Topic :: System :: Benchmark',
+    ],
+    license='Apache 2.0',
+    keywords='benchmark',
+)
diff --git a/src/benchmark.cc b/src/benchmark.cc
index b751b9c..1c049f2 100644
--- a/src/benchmark.cc
+++ b/src/benchmark.cc
@@ -284,10 +284,10 @@
 }
 
 // Disable deprecated warnings temporarily because we need to reference
-// CSVReporter but don't want to trigger -Werror=-Wdeprecated
+// CSVReporter but don't want to trigger -Werror=-Wdeprecated-declarations
 #ifdef __GNUC__
 #pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 #endif
 
 std::unique_ptr<BenchmarkReporter> CreateReporter(
diff --git a/src/cycleclock.h b/src/cycleclock.h
index 3901da6..179c67c 100644
--- a/src/cycleclock.h
+++ b/src/cycleclock.h
@@ -86,15 +86,15 @@
   // This returns a time-base, which is not always precisely a cycle-count.
 #if defined(__powerpc64__) || defined(__ppc64__)
   int64_t tb;
-  asm volatile("mfspr %0, 268" : "=r" (tb));
+  asm volatile("mfspr %0, 268" : "=r"(tb));
   return tb;
 #else
   uint32_t tbl, tbu0, tbu1;
   asm volatile(
-    "mftbu %0\n"
-    "mftbl %1\n"
-    "mftbu %2"
-    : "=r"(tbu0), "=r"(tbl), "=r"(tbu1));
+      "mftbu %0\n"
+      "mftbl %1\n"
+      "mftbu %2"
+      : "=r"(tbu0), "=r"(tbl), "=r"(tbu1));
   tbl &= -static_cast<int32_t>(tbu0 == tbu1);
   // high 32 bits in tbu1; low 32 bits in tbl  (tbu0 is no longer needed)
   return (static_cast<uint64_t>(tbu1) << 32) | tbl;
@@ -179,14 +179,14 @@
   // This asm also includes the PowerPC overflow handling strategy, as above.
   // Implemented in assembly because Clang insisted on branching.
   asm volatile(
-    "rdcycleh %0\n"
-    "rdcycle %1\n"
-    "rdcycleh %2\n"
-    "sub %0, %0, %2\n"
-    "seqz %0, %0\n"
-    "sub %0, zero, %0\n"
-    "and %1, %1, %0\n"
-    : "=r"(cycles_hi0), "=r"(cycles_lo), "=r"(cycles_hi1));
+      "rdcycleh %0\n"
+      "rdcycle %1\n"
+      "rdcycleh %2\n"
+      "sub %0, %0, %2\n"
+      "seqz %0, %0\n"
+      "sub %0, zero, %0\n"
+      "and %1, %1, %0\n"
+      : "=r"(cycles_hi0), "=r"(cycles_lo), "=r"(cycles_hi1));
   return (static_cast<uint64_t>(cycles_hi1) << 32) | cycles_lo;
 #else
   uint64_t cycles;
diff --git a/src/string_util.cc b/src/string_util.cc
index 39b01a1..ac60b55 100644
--- a/src/string_util.cc
+++ b/src/string_util.cc
@@ -1,6 +1,9 @@
 #include "string_util.h"
 
 #include <array>
+#ifdef BENCHMARK_STL_ANDROID_GNUSTL
+#include <cerrno>
+#endif
 #include <cmath>
 #include <cstdarg>
 #include <cstdio>
diff --git a/test/output_test_helper.cc b/test/output_test_helper.cc
index bdb34c8..f99b3a8 100644
--- a/test/output_test_helper.cc
+++ b/test/output_test_helper.cc
@@ -374,10 +374,10 @@
 }
 
 // Disable deprecated warnings temporarily because we need to reference
-// CSVReporter but don't want to trigger -Werror=-Wdeprecated
+// CSVReporter but don't want to trigger -Werror=-Wdeprecated-declarations
 #ifdef __GNUC__
 #pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 #endif
 void RunOutputTests(int argc, char* argv[]) {
   using internal::GetTestCaseList;