mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
133 lines
3.7 KiB
C++
133 lines
3.7 KiB
C++
#pragma once
|
|
|
|
/// \brief DataFlow analysis to build the AST for a Function
|
|
|
|
//
|
|
// Copyright rev.ng Srls. See LICENSE.md for details.
|
|
//
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/Analysis/ScalarEvolution.h"
|
|
#include "llvm/IR/Dominators.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
|
|
#include "clang/Basic/Specifiers.h"
|
|
|
|
#include "revng/ADT/SmallMap.h"
|
|
#include "revng/Support/Assert.h"
|
|
#include "revng/Support/MonotoneFramework.h"
|
|
|
|
#include "revng-c/Decompiler/DLALayouts.h"
|
|
#include "revng-c/Decompiler/MarkForSerialization.h"
|
|
|
|
namespace clang {
|
|
class ASTContext;
|
|
class Expr;
|
|
class FunctionDecl;
|
|
class LabelDecl;
|
|
class VarDecl;
|
|
class Stmt;
|
|
} // namespace clang
|
|
|
|
namespace llvm {
|
|
class AllocaInst;
|
|
class BasicBlock;
|
|
class Constant;
|
|
class Function;
|
|
class PHINode;
|
|
} // namespace llvm
|
|
|
|
class DeclCreator;
|
|
|
|
namespace IR2AST {
|
|
|
|
using AllocaVarDeclMap = std::map<const llvm::AllocaInst *, clang::VarDecl *>;
|
|
using BBLabelsMap = std::map<llvm::BasicBlock *, clang::LabelDecl *>;
|
|
using DeclMap = std::map<const llvm::Value *, clang::VarDecl *>;
|
|
using StmtMap = std::map<const llvm::Instruction *, clang::Stmt *>;
|
|
using StmtMultiMap = std::map<const llvm::Instruction *,
|
|
llvm::SmallVector<clang::Stmt *, 2>>;
|
|
|
|
class StmtBuilder {
|
|
|
|
private:
|
|
using PHIIncomingMap = SmallMap<llvm::PHINode *, unsigned, 4>;
|
|
using BBPHIMap = SmallMap<llvm::BasicBlock *, PHIIncomingMap, 4>;
|
|
|
|
clang::ASTContext &ASTCtx;
|
|
const SerializationMap &ToSerialize;
|
|
const dla::ValueLayoutMap *ValueLayouts;
|
|
llvm::ScalarEvolution *SE;
|
|
uint64_t NVar;
|
|
|
|
public:
|
|
AllocaVarDeclMap AllocaDecls;
|
|
BBLabelsMap BBLabelDecls;
|
|
DeclMap VarDecls;
|
|
StmtMap InstrStmts;
|
|
StmtMultiMap AdditionalStmts;
|
|
BBPHIMap &BlockToPHIIncoming;
|
|
|
|
public:
|
|
StmtBuilder(clang::ASTContext &Ctx,
|
|
const SerializationMap &ToSerialize,
|
|
const dla::ValueLayoutMap *VL,
|
|
llvm::ScalarEvolution *SCEV,
|
|
BBPHIMap &BlockToPHIIncoming,
|
|
DeclCreator &TT) :
|
|
ASTCtx(Ctx),
|
|
ToSerialize(ToSerialize),
|
|
ValueLayouts(VL),
|
|
SE(SCEV),
|
|
NVar(0),
|
|
AllocaDecls(),
|
|
BBLabelDecls(),
|
|
VarDecls(),
|
|
InstrStmts(),
|
|
BlockToPHIIncoming(BlockToPHIIncoming),
|
|
Declarator(TT) {}
|
|
|
|
void createAST(llvm::Function &F, clang::FunctionDecl &FD);
|
|
|
|
clang::Expr *getExprForValue(const llvm::Value *V);
|
|
clang::Expr *getUIntLiteral(uint64_t U);
|
|
clang::Expr *getBoolLiteral(bool V);
|
|
clang::Expr *getLiteralFromConstant(const llvm::Constant *C);
|
|
|
|
clang::VarDecl *getOrCreateLoopStateVarDecl(clang::FunctionDecl &FD);
|
|
clang::VarDecl *getOrCreateSwitchStateVarDecl(clang::FunctionDecl &FD);
|
|
|
|
clang::VarDecl *getLoopStateVarDecl() const { return LoopStateVarDecl; }
|
|
clang::VarDecl *getSwitchStateVarDecl() const { return SwitchStateVarDecl; }
|
|
|
|
private:
|
|
clang::VarDecl *
|
|
createVarDecl(const llvm::Instruction *I, clang::FunctionDecl &FD);
|
|
clang::VarDecl *createVarDecl(llvm::Constant *I,
|
|
llvm::Value *NamingVal,
|
|
clang::FunctionDecl &FD);
|
|
clang::Expr *buildPointerArithmeticExpr(llvm::Instruction &I);
|
|
clang::Stmt *buildStmt(llvm::Instruction &I);
|
|
clang::Expr *createRValueExprForBinaryOperator(llvm::Instruction &I);
|
|
clang::Expr *getParenthesizedExprForValue(const llvm::Value *V);
|
|
|
|
public:
|
|
struct LayoutChildInfo {
|
|
const dla::Layout *Parent;
|
|
unsigned ChildId;
|
|
};
|
|
|
|
private:
|
|
clang::Expr *getMemberAccessExpr(clang::Expr *BaseExpr,
|
|
const LayoutChildInfo &ChildInfo,
|
|
bool IsArrow);
|
|
|
|
private:
|
|
clang::VarDecl *LoopStateVarDecl = nullptr;
|
|
clang::VarDecl *SwitchStateVarDecl = nullptr;
|
|
|
|
DeclCreator &Declarator;
|
|
};
|
|
|
|
} // namespace IR2AST
|