versioner: handle _FILE_OFFSET_BITS=64.

Compile headers with both -D_FILE_OFFSET_BITS=32 and -D_FILE_OFFSET_BITS=64.

Bug: http://b/30170081
Change-Id: I92651e075cc69bdc1a2581f99892c9a7fdcdb35b
Test: python run_tests.py
diff --git a/tools/versioner/src/DeclarationDatabase.cpp b/tools/versioner/src/DeclarationDatabase.cpp
index 8e8d84f..88f7b55 100644
--- a/tools/versioner/src/DeclarationDatabase.cpp
+++ b/tools/versioner/src/DeclarationDatabase.cpp
@@ -288,7 +288,7 @@
 
 std::string to_string(const CompilationType& type) {
   std::stringstream ss;
-  ss << to_string(type.arch) << "-" << type.api_level;
+  ss << to_string(type.arch) << "-" << type.api_level << " [fob = " << type.file_offset_bits << "]";
   return ss.str();
 }
 
diff --git a/tools/versioner/src/DeclarationDatabase.h b/tools/versioner/src/DeclarationDatabase.h
index 8fe12ea..b130ca9 100644
--- a/tools/versioner/src/DeclarationDatabase.h
+++ b/tools/versioner/src/DeclarationDatabase.h
@@ -43,10 +43,11 @@
 struct CompilationType {
   Arch arch;
   int api_level;
+  int file_offset_bits;
 
  private:
   auto tie() const {
-    return std::tie(arch, api_level);
+    return std::tie(arch, api_level, file_offset_bits);
   }
 
  public:
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index b18c3c2..432fd66 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -89,6 +89,8 @@
       command.push_back(std::move(header_path));
     }
 
+    command.push_back("-D_FILE_OFFSET_BITS="s + std::to_string(type.file_offset_bits));
+
     return CompileCommand(cwd, filename, command);
   }
 
@@ -184,8 +186,13 @@
       if (api_level < min_api) {
         continue;
       }
-      CompilationType type = { .arch = arch, .api_level = api_level };
-      result.insert(type);
+
+      for (int file_offset_bits : { 32, 64 }) {
+        CompilationType type = {
+          .arch = arch, .api_level = api_level, .file_offset_bits = file_offset_bits
+        };
+        result.insert(type);
+      }
     }
   }
   return result;
diff --git a/tools/versioner/tests/compilation_error/expected_fail b/tools/versioner/tests/compilation_error/expected_fail
index 62a643f..f18b625 100644
--- a/tools/versioner/tests/compilation_error/expected_fail
+++ b/tools/versioner/tests/compilation_error/expected_fail
@@ -1,2 +1 @@
-versioner: compilation failure for arm-9 in /android/aosp/bionic/tools/versioner/tests/compilation_error/headers/foo.h
 versioner: compilation generated warnings or errors
diff --git a/tools/versioner/tests/missing_api/expected_fail b/tools/versioner/tests/missing_api/expected_fail
index 65a25f2..18e7845 100644
--- a/tools/versioner/tests/missing_api/expected_fail
+++ b/tools/versioner/tests/missing_api/expected_fail
@@ -1,4 +1,3 @@
-foo: declaration marked available but symbol missing in [arm-12]
   foo: introduced = 9
     extern declaration @ headers/foo.h:1:1
       introduced = 9
diff --git a/tools/versioner/tests/missing_arch/expected_fail b/tools/versioner/tests/missing_arch/expected_fail
index ed8ab79..82c2b28 100644
--- a/tools/versioner/tests/missing_arch/expected_fail
+++ b/tools/versioner/tests/missing_arch/expected_fail
@@ -1,4 +1,3 @@
-foo: declaration marked available but symbol missing in [x86-9]
   foo: no availability
     extern declaration @ headers/foo.h:1:1
       no availability
diff --git a/tools/versioner/tests/preprocessor_file_offset_bits/expected/foo.h b/tools/versioner/tests/preprocessor_file_offset_bits/expected/foo.h
new file mode 100644
index 0000000..7d31ec3
--- /dev/null
+++ b/tools/versioner/tests/preprocessor_file_offset_bits/expected/foo.h
@@ -0,0 +1,34 @@
+typedef int off_t;
+typedef int ssize_t;
+typedef unsigned size_t;
+
+#if !defined(__LP64__) && defined(_FILE_OFFSET_BITS)
+#if _FILE_OFFSET_BITS == 64
+#define __USE_FILE_OFFSET64 1
+#endif
+#endif
+
+#define __RENAME(x) __asm__(#x)
+
+#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= 21
+int truncate(const char* __path, off_t __length) __RENAME(truncate64) __INTRODUCED_IN(21);
+#else
+int truncate(const char* __path, off_t __length);
+#endif
+
+#if defined(__USE_FILE_OFFSET64)
+
+#if __ANDROID_API__ >= 12
+ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset) __RENAME(pread64)
+    __INTRODUCED_IN(12);
+#endif /* __ANDROID_API__ >= 12 */
+
+#else
+ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset);
+#endif
+
+#if defined(__USE_FILE_OFFSET64)
+off_t lseek(int __fd, off_t __offset, int __whence) __RENAME(lseek64);
+#else
+off_t lseek(int __fd, off_t __offset, int __whence);
+#endif
diff --git a/tools/versioner/tests/preprocessor_file_offset_bits/headers/foo.h b/tools/versioner/tests/preprocessor_file_offset_bits/headers/foo.h
new file mode 100644
index 0000000..868d1fc
--- /dev/null
+++ b/tools/versioner/tests/preprocessor_file_offset_bits/headers/foo.h
@@ -0,0 +1,30 @@
+typedef int off_t;
+typedef int ssize_t;
+typedef unsigned size_t;
+
+#if !defined(__LP64__) && defined(_FILE_OFFSET_BITS)
+#if _FILE_OFFSET_BITS == 64
+#define __USE_FILE_OFFSET64 1
+#endif
+#endif
+
+#define __RENAME(x) __asm__(#x)
+
+#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= 21
+int truncate(const char* __path, off_t __length) __RENAME(truncate64) __INTRODUCED_IN(21);
+#else
+int truncate(const char* __path, off_t __length);
+#endif
+
+#if defined(__USE_FILE_OFFSET64)
+ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset) __RENAME(pread64)
+    __INTRODUCED_IN(12);
+#else
+ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset);
+#endif
+
+#if defined(__USE_FILE_OFFSET64)
+off_t lseek(int __fd, off_t __offset, int __whence) __RENAME(lseek64);
+#else
+off_t lseek(int __fd, off_t __offset, int __whence);
+#endif
diff --git a/tools/versioner/tests/preprocessor_file_offset_bits/run.sh b/tools/versioner/tests/preprocessor_file_offset_bits/run.sh
new file mode 100644
index 0000000..c503867
--- /dev/null
+++ b/tools/versioner/tests/preprocessor_file_offset_bits/run.sh
@@ -0,0 +1,5 @@
+set -e
+
+rm -rf out
+versioner headers -i -o out
+diff -q -w -B out expected