Files
revng-revng/lib/Decompiler/ASTBuildAnalysis.h
T
2021-04-27 21:19:06 +02:00

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