// 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 . #include "goatc.hh" #include #include #include #include bool goatc::Visitor::VisitDecl (clang::Decl* decl) { if (auto* named_decl = llvm::dyn_cast (decl)) { clang::FullSourceLoc loc = this->ctx->getFullLoc (decl->getBeginLoc ()); if (loc.isValid ()) llvm::outs () << "Found " << named_decl->getQualifiedNameAsString () << " at " << loc.getSpellingLineNumber () << ':' << loc.getSpellingColumnNumber () << '\n'; } return true; } void goatc::Consumer::HandleTranslationUnit (clang::ASTContext& ctx) { this->visitor.TraverseDecl (ctx.getTranslationUnitDecl ()); } clang::PluginASTAction::ActionType goatc::Action::getActionType () { return AddBeforeMainAction; } std::unique_ptr goatc::Action::CreateASTConsumer (clang::CompilerInstance& ci, llvm::StringRef in_file) { return std::make_unique (&ci.getASTContext (), 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 goatc::Action::ParseArgs (const clang::CompilerInstance& ci, const std::vector &args) { auto& d = ci.getDiagnostics (); for (unsigned i = 0, e = args.size(); i < e; ++i) if (args[i] == "-h" || args[i] == "--help") { printHelp (llvm::outs ()); // 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; }