Files
revng-revng/lib/ImportModelFromC/HeaderToModel.h
T
Djordje Todorovic 5c0167f792 Add ImportModelFromC Analysis
This analysis will be used for the following features:

1) Edit Type in the Model
2) Edit Function Prototype in the Model
3) Add Type to the Model

It takes C code as an input, parses it and produces a Model
type that represents the C type.
2023-07-24 11:51:47 +02:00

131 lines
3.8 KiB
C++

#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<revng::ParseCCodeError> &getError() { return Error; }
private:
clang::DiagnosticConsumer *Client;
std::unique_ptr<clang::DiagnosticConsumer> ClientOwner;
std::optional<revng::ParseCCodeError> Error;
};
class HeaderToModelAction : public ASTFrontendAction {
protected:
HeaderToModelAction(TupleTree<model::Binary> &Model,
enum ImportModelFromCOption AnalysisOption,
std::optional<revng::ParseCCodeError> &Error) :
Model(Model), AnalysisOption(AnalysisOption), Error(Error) {}
public:
virtual std::unique_ptr<ASTConsumer> newASTConsumer() = 0;
virtual std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance &, llvm::StringRef) override;
virtual bool BeginInvocation(clang::CompilerInstance &CI) override;
virtual void EndSourceFile() override;
protected:
TupleTree<model::Binary> &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<revng::ParseCCodeError> &Error;
private:
HeaderToModelDiagnosticConsumer *DiagConsumer = nullptr;
};
// Handle Edit Type option.
class HeaderToModelEditTypeAction : public HeaderToModelAction {
public:
HeaderToModelEditTypeAction(TupleTree<model::Binary> &Model,
std::optional<revng::ParseCCodeError> &Error,
std::optional<model::Type *> &Type) :
HeaderToModelAction(Model, ImportModelFromCOption::EditType, Error),
Type(Type) {}
private:
// Type to be edited.
std::optional<model::Type *> &Type;
public:
virtual std::unique_ptr<ASTConsumer> newASTConsumer() override;
};
// Handle Edit Function Prototype option.
class HeaderToModelEditFunctionAction : public HeaderToModelAction {
public:
HeaderToModelEditFunctionAction(TupleTree<model::Binary> &Model,
std::optional<revng::ParseCCodeError> &Error,
std::optional<model::Function> &Function) :
HeaderToModelAction(Model,
ImportModelFromCOption::EditFunctionPrototype,
Error),
Function(Function) {}
private:
// Function to be edited if we are editing function prototype.
std::optional<model::Function> &Function;
public:
virtual std::unique_ptr<ASTConsumer> newASTConsumer() override;
};
// Handle Add Type option.
class HeaderToModelAddTypeAction : public HeaderToModelAction {
public:
HeaderToModelAddTypeAction(TupleTree<model::Binary> &Model,
std::optional<revng::ParseCCodeError> &Error) :
HeaderToModelAction(Model, ImportModelFromCOption::AddType, Error) {}
public:
virtual std::unique_ptr<ASTConsumer> newASTConsumer() override;
};
} // end namespace tooling
} // namespace clang