summary refs log tree commit diff
path: root/goatc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'goatc.cc')
-rw-r--r--goatc.cc93
1 files changed, 93 insertions, 0 deletions
diff --git a/goatc.cc b/goatc.cc
new file mode 100644
index 0000000..354d377
--- /dev/null
+++ b/goatc.cc
@@ -0,0 +1,93 @@
+// Clang plugin implementation
+// Copyright (C) 2024  Nguyễn Gia Phong
+//
+// This file is part of GoatC.
+//
+// GoatC is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// GoatC is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with GoatC.  If not, see <https://www.gnu.org/licenses/>.
+
+#include "goatc.hh"
+
+#include <clang/AST/AST.h>
+#include <clang/AST/RecursiveASTVisitor.h>
+#include <clang/Frontend/CompilerInstance.h>
+#include <clang/Sema/Sema.h>
+#include <llvm/Support/raw_ostream.h>
+
+bool
+GoatCConsumer::HandleTopLevelDecl (clang::DeclGroupRef dg)
+{
+  if (this->noop)
+    return true;
+
+  for (auto const& d : dg)
+    if (auto const& nd = llvm::dyn_cast <clang::NamedDecl> (d))
+      llvm::errs() << "top-level-decl: \"" << nd->getNameAsString() << "\"\n";
+  return true;
+}
+
+clang::PluginASTAction::ActionType
+GoatCAction::getActionType ()
+{
+  return AddBeforeMainAction;
+}
+
+std::unique_ptr <clang::ASTConsumer>
+GoatCAction::CreateASTConsumer (clang::CompilerInstance& ci,
+                                llvm::StringRef in_file)
+{
+  llvm::errs () << in_file << '\n';
+  return std::make_unique <GoatCConsumer> (ci, in_file != this->source_file);
+}
+
+void
+printHelp (llvm::raw_ostream& ros)
+{
+  ros << "Usage: goatcflags [OPTION]...\n\nOptions:\n";
+  ros << "  -h, --help              show this help message and exit\n";
+  ros << "  -s, --source-file PATH  path to the file to be chimera'd\n";
+}
+
+bool
+GoatCAction::ParseArgs (const clang::CompilerInstance& ci,
+                        const std::vector <std::string> &args)
+{
+  auto& d = ci.getDiagnostics ();
+  for (unsigned i = 0, e = args.size(); i < e; ++i)
+    if (args[i] == "-h" || args[i] == "--help")
+      {
+        printHelp (llvm::errs ());
+        // FIXME: exit with status 0
+        return false;
+      }
+    else if (args[i] == "-s" || args[i] == "--source-file")
+      {
+        if (++i == e)
+          {
+            d.Report (d.getCustomDiagID (clang::DiagnosticsEngine::Error,
+                                         "missing --source-file argument"));
+            return false;
+          }
+        // TODO: check if file exists
+        this->source_file = args[i];
+      }
+
+  if (this->source_file.empty ())
+    {
+      d.Report (d.getCustomDiagID (clang::DiagnosticsEngine::Error,
+                                   "unspecified --source-file"));
+      return false;
+    }
+
+  return true;
+}