Add CC analysis support to ide_query
Introduces ide_query_cc_analyzer, which figures out relevant build targets that needs to be built for a given C++ source or header file.
Once these targets are built, it analyzes the sources in question and reports any generated files that are used back.
Full ide_query integration relies on this binary also being available in prebuilts clang-tools, it'll be done in a future patch.
Change-Id: Ib0ef6da7a2bc8ecf66940b326e037fb1ee230bf9
diff --git a/tools/ide_query/cc_analyzer/main.cc b/tools/ide_query/cc_analyzer/main.cc
new file mode 100644
index 0000000..8e00c63
--- /dev/null
+++ b/tools/ide_query/cc_analyzer/main.cc
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * 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.
+ */
+
+// Driver for c++ extractor. Operates in two modes:
+// - DEPS, scans build graph for active files and reports targets that need to
+// be build for analyzing that file.
+// - INPUTS, scans the source code for active files and returns all the sources
+// required for analyzing that file.
+//
+// Uses stdin/stdout to take in requests and provide responses.
+#include <unistd.h>
+
+#include <memory>
+#include <utility>
+
+#include "analyzer.h"
+#include "google/protobuf/message.h"
+#include "ide_query.pb.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace {
+enum class OpMode {
+ DEPS = 0,
+ INPUTS = 1,
+};
+llvm::cl::opt<OpMode> mode{
+ "mode",
+ llvm::cl::values(clEnumValN(OpMode::DEPS, "deps",
+ "Figure out targets that need to be build"),
+ clEnumValN(OpMode::INPUTS, "inputs",
+ "Figure out generated files used")),
+ llvm::cl::desc("Print the list of headers to insert and remove"),
+};
+
+ide_query::IdeAnalysis ReturnError(llvm::StringRef message) {
+ ide_query::IdeAnalysis result;
+ result.mutable_status()->set_code(ide_query::Status::FAILURE);
+ result.mutable_status()->set_message(message.str());
+ return result;
+}
+
+} // namespace
+
+int main(int argc, char* argv[]) {
+ llvm::InitializeAllTargetInfos();
+ llvm::cl::ParseCommandLineOptions(argc, argv);
+
+ ide_query::RepoState state;
+ if (!state.ParseFromFileDescriptor(STDIN_FILENO)) {
+ llvm::errs() << "Failed to parse input!\n";
+ return 1;
+ }
+
+ std::unique_ptr<google::protobuf::Message> result;
+ switch (mode) {
+ case OpMode::DEPS: {
+ result = std::make_unique<ide_query::DepsResponse>(
+ tools::ide_query::cc_analyzer::GetDeps(std::move(state)));
+ break;
+ }
+ case OpMode::INPUTS: {
+ result = std::make_unique<ide_query::IdeAnalysis>(
+ tools::ide_query::cc_analyzer::GetBuildInputs(std::move(state)));
+ break;
+ }
+ default:
+ llvm::errs() << "Unknown operation mode!\n";
+ return 1;
+ }
+ if (!result->SerializeToFileDescriptor(STDOUT_FILENO)) {
+ llvm::errs() << "Failed to serialize result!\n";
+ return 1;
+ }
+
+ return 0;
+}