From 6d4c7b30940bf1df8c9f3faaf6de7be6e58b344c Mon Sep 17 00:00:00 2001
From: Andre Maroneze <andre.maroneze@cea.fr>
Date: Mon, 11 Jan 2021 17:34:29 +0100
Subject: [PATCH] [Kernel] add support of build databases to
 -json-compilation-database

---
 .../ast_queries/json_compilation_database.ml  | 20 ++++++++++++++++++-
 tests/jcdb/build_commands.json                | 20 +++++++++++++++++++
 tests/jcdb/jbdb.c                             |  7 +++++++
 tests/jcdb/jbdb2.c                            |  7 +++++++
 tests/jcdb/oracle/jbdb.res.oracle             | 10 ++++++++++
 tests/jcdb/oracle/jbdb2.res.oracle            | 10 ++++++++++
 6 files changed, 73 insertions(+), 1 deletion(-)
 create mode 100644 tests/jcdb/build_commands.json
 create mode 100644 tests/jcdb/jbdb.c
 create mode 100644 tests/jcdb/jbdb2.c
 create mode 100644 tests/jcdb/oracle/jbdb.res.oracle
 create mode 100644 tests/jcdb/oracle/jbdb2.res.oracle

diff --git a/src/kernel_services/ast_queries/json_compilation_database.ml b/src/kernel_services/ast_queries/json_compilation_database.ml
index 11c2802451c..01fbfdb999c 100644
--- a/src/kernel_services/ast_queries/json_compilation_database.ml
+++ b/src/kernel_services/ast_queries/json_compilation_database.ml
@@ -211,6 +211,16 @@ let update_flags_verbosely path flags =
   | Not_found ->
     Flags.add path flags
 
+let parse_build_entry bcdb_dir r =
+  let open Yojson.Basic.Util in
+  let filenames = r |> member "sources" |> to_list |> List.map to_string in
+  let args = List.map to_string (r |> member "arguments" |> to_list) in
+  let flags = filter_useful_flags ~requote:true args in
+  List.iter (fun filename ->
+      let path = Datatype.Filepath.of_string ~base_name:bcdb_dir filename in
+      update_flags_verbosely path flags
+    ) filenames
+
 let parse_compilation_entry jcdb_dir r =
   let open Yojson.Basic.Util in
   let filename = r |> member "file" |> to_string in
@@ -259,7 +269,15 @@ let compute_flags_from_file () =
       let r_list =
         Yojson.Basic.from_file jcdb_path |> Yojson.Basic.Util.to_list
       in
-      List.iter (parse_compilation_entry jcdb_dir) r_list;
+      let is_build_database =
+        try
+          List.hd r_list |> Yojson.Basic.Util.member "sources" <> `Null
+        with _ -> false
+      in
+      let parse_entry =
+        if is_build_database then parse_build_entry else parse_compilation_entry
+      in
+      List.iter (parse_entry jcdb_dir) r_list;
     with
     | Sys_error msg
     | Yojson.Json_error msg
diff --git a/tests/jcdb/build_commands.json b/tests/jcdb/build_commands.json
new file mode 100644
index 00000000000..f12bcb79f60
--- /dev/null
+++ b/tests/jcdb/build_commands.json
@@ -0,0 +1,20 @@
+[
+    {
+        "command": "/usr/bin/gcc -c jbdb.c jbdb2.c -DRETCODE=0",
+        "arguments": [
+            "/usr/bin/gcc",
+            "-c",
+            "jbdb.c",
+            "jbdb2.c",
+            "-DRETCODE=0"
+        ],
+        "sources": [
+            "jbdb.c",
+            "jbdb2.c"
+        ],
+        "targets": [
+            "jbdb.o",
+            "jbdb2.o"
+        ]
+    }
+]
diff --git a/tests/jcdb/jbdb.c b/tests/jcdb/jbdb.c
new file mode 100644
index 00000000000..d7321842442
--- /dev/null
+++ b/tests/jcdb/jbdb.c
@@ -0,0 +1,7 @@
+/* run.config
+OPT: -json-compilation-database @PTEST_DIR@/build_commands.json -print
+*/
+
+int f2 () {
+  return RETCODE; // defined in build_commands.json
+}
diff --git a/tests/jcdb/jbdb2.c b/tests/jcdb/jbdb2.c
new file mode 100644
index 00000000000..db89a97f607
--- /dev/null
+++ b/tests/jcdb/jbdb2.c
@@ -0,0 +1,7 @@
+/* run.config
+OPT: -json-compilation-database @PTEST_DIR@/build_commands.json -print
+*/
+
+int f1 () {
+  return RETCODE; // defined in build_commands.json
+}
diff --git a/tests/jcdb/oracle/jbdb.res.oracle b/tests/jcdb/oracle/jbdb.res.oracle
new file mode 100644
index 00000000000..592d8314fdb
--- /dev/null
+++ b/tests/jcdb/oracle/jbdb.res.oracle
@@ -0,0 +1,10 @@
+[kernel] Parsing tests/jcdb/jbdb.c (with preprocessing)
+/* Generated by Frama-C */
+int f2(void)
+{
+  int __retres;
+  __retres = 0;
+  return __retres;
+}
+
+
diff --git a/tests/jcdb/oracle/jbdb2.res.oracle b/tests/jcdb/oracle/jbdb2.res.oracle
new file mode 100644
index 00000000000..376850836aa
--- /dev/null
+++ b/tests/jcdb/oracle/jbdb2.res.oracle
@@ -0,0 +1,10 @@
+[kernel] Parsing tests/jcdb/jbdb2.c (with preprocessing)
+/* Generated by Frama-C */
+int f1(void)
+{
+  int __retres;
+  __retres = 0;
+  return __retres;
+}
+
+
-- 
GitLab