#pragma once // // Copyright (c) rev.ng Labs Srl. See LICENSE.md for details. // #include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" #include "clang/Frontend/ASTConsumers.h" #include "clang/Frontend/FrontendAction.h" #include "revng/Model/Binary.h" #include "revng/Model/ForwardDecls.h" #include "revng/TupleTree/TupleTree.h" #include "ImportModelFromCAnalysis.h" namespace revng { struct ParseCCodeError { std::string ErrorMessage; unsigned Line = 0; unsigned Column = 0; }; } // namespace revng namespace clang { class CompilerInstance; namespace tooling { class HeaderToModelDiagnosticConsumer : public clang::DiagnosticConsumer { public: HeaderToModelDiagnosticConsumer(clang::DiagnosticsEngine &D) : Client(D.getClient()), ClientOwner(D.takeClient()) {} void EndSourceFile() override; void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) override; std::optional &getError() { return Error; } private: clang::DiagnosticConsumer *Client; std::unique_ptr ClientOwner; std::optional Error; }; class HeaderToModelAction : public ASTFrontendAction { protected: HeaderToModelAction(TupleTree &Model, enum ImportModelFromCOption AnalysisOption, std::optional &Error) : Model(Model), AnalysisOption(AnalysisOption), Error(Error) {} public: virtual std::unique_ptr newASTConsumer() = 0; virtual std::unique_ptr CreateASTConsumer(CompilerInstance &, llvm::StringRef) override; virtual bool BeginInvocation(clang::CompilerInstance &CI) override; virtual void EndSourceFile() override; protected: TupleTree &Model; // This indiacates which feature is used (edit/add type, edit function // prototype). enum ImportModelFromCOption AnalysisOption; // This holds the error message reported by clang or revng, if any. std::optional &Error; private: HeaderToModelDiagnosticConsumer *DiagConsumer = nullptr; }; // Handle Edit Type option. class HeaderToModelEditTypeAction : public HeaderToModelAction { public: HeaderToModelEditTypeAction(TupleTree &Model, std::optional &Error, std::optional &Type) : HeaderToModelAction(Model, ImportModelFromCOption::EditType, Error), Type(Type) {} private: // Type to be edited. std::optional &Type; public: virtual std::unique_ptr newASTConsumer() override; }; // Handle Edit Function Prototype option. class HeaderToModelEditFunctionAction : public HeaderToModelAction { public: HeaderToModelEditFunctionAction(TupleTree &Model, std::optional &Error, std::optional &Function) : HeaderToModelAction(Model, ImportModelFromCOption::EditFunctionPrototype, Error), Function(Function) {} private: // Function to be edited if we are editing function prototype. std::optional &Function; public: virtual std::unique_ptr newASTConsumer() override; }; // Handle Add Type option. class HeaderToModelAddTypeAction : public HeaderToModelAction { public: HeaderToModelAddTypeAction(TupleTree &Model, std::optional &Error) : HeaderToModelAction(Model, ImportModelFromCOption::AddType, Error) {} public: virtual std::unique_ptr newASTConsumer() override; }; } // end namespace tooling } // namespace clang