mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
27f850e433
Before this commit, when GlobalDeclCreationAction needed to emit literals for initialization of global variables, it did it using custom code. This was not working properly, an in some cases it emitted short literals which are not allowed in C. Hence the generated C code that was impossible to recompile without syntax errors. This commit fixes this problem, using the getLiteralFromConstant method of StmtBuilder. In order to do this, we need to make the StmtBuilder available inside the GlobalDeclCreationAction, which is not a very clean design. However, we are already planning to merge the GlobalDeclCreationAction and the StmtBuilder class, so this issue will be taken care of in the future.
124 lines
3.6 KiB
C++
124 lines
3.6 KiB
C++
#ifndef REVNGC_ASTBUILDANALYSIS_H
|
|
#define REVNGC_ASTBUILDANALYSIS_H
|
|
/// \brief DataFlow analysis to build the AST for a Function
|
|
|
|
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
// LLVM includes
|
|
#include <llvm/ADT/SmallVector.h>
|
|
#include <llvm/IR/Dominators.h>
|
|
#include <llvm/IR/Instructions.h>
|
|
|
|
// clang includes
|
|
#include <clang/Basic/Specifiers.h>
|
|
|
|
// revng includes
|
|
#include <revng/ADT/SmallMap.h>
|
|
#include <revng/Support/Assert.h>
|
|
#include <revng/Support/MonotoneFramework.h>
|
|
|
|
namespace clang {
|
|
class ASTContext;
|
|
class Expr;
|
|
class FieldDecl;
|
|
class FunctionDecl;
|
|
class LabelDecl;
|
|
class VarDecl;
|
|
class Stmt;
|
|
class TypeDecl;
|
|
} // namespace clang
|
|
|
|
namespace llvm {
|
|
class AllocaInst;
|
|
class BasicBlock;
|
|
class Constant;
|
|
class Function;
|
|
class PHINode;
|
|
class Type;
|
|
} // namespace llvm
|
|
|
|
namespace IR2AST {
|
|
|
|
using AllocaVarDeclMap = std::map<llvm::AllocaInst *, clang::VarDecl *>;
|
|
using BBLabelsMap = std::map<llvm::BasicBlock *, clang::LabelDecl *>;
|
|
using DeclMap = std::map<llvm::Instruction *, clang::VarDecl *>;
|
|
using FunctionsMap = std::map<llvm::Function *, clang::FunctionDecl *>;
|
|
using GlobalsMap = std::map<const llvm::GlobalVariable *, clang::VarDecl *>;
|
|
using StmtMap = std::map<llvm::Instruction *, clang::Stmt *>;
|
|
using StmtMultiMap = std::map<llvm::Instruction *,
|
|
llvm::SmallVector<clang::Stmt *, 2>>;
|
|
using TypeDeclMap = std::map<const llvm::Type *, clang::TypeDecl *>;
|
|
using FieldDeclMap = std::map<clang::TypeDecl *,
|
|
llvm::SmallVector<clang::FieldDecl *, 8>>;
|
|
|
|
class StmtBuilder {
|
|
|
|
private:
|
|
using PHIIncomingMap = SmallMap<llvm::PHINode *, unsigned, 4>;
|
|
using BBPHIMap = SmallMap<llvm::BasicBlock *, PHIIncomingMap, 4>;
|
|
|
|
const std::set<llvm::Instruction *> &ToSerialize;
|
|
clang::ASTContext &ASTCtx;
|
|
uint64_t NVar;
|
|
|
|
public:
|
|
AllocaVarDeclMap AllocaDecls;
|
|
BBLabelsMap BBLabelDecls;
|
|
DeclMap VarDecls;
|
|
FunctionsMap &FunctionDecls;
|
|
GlobalsMap &GlobalDecls;
|
|
StmtMap InstrStmts;
|
|
StmtMultiMap AdditionalStmts;
|
|
TypeDeclMap TypeDecls;
|
|
FieldDeclMap FieldDecls;
|
|
BBPHIMap &BlockToPHIIncoming;
|
|
|
|
public:
|
|
StmtBuilder(const std::set<llvm::Instruction *> &ToSerialize,
|
|
clang::ASTContext &Ctx,
|
|
GlobalsMap &GMap,
|
|
FunctionsMap &FMap,
|
|
BBPHIMap &BlockToPHIIncoming,
|
|
TypeDeclMap &TypeDecls,
|
|
FieldDeclMap &FieldDecls) :
|
|
ToSerialize(ToSerialize),
|
|
ASTCtx(Ctx),
|
|
NVar(0),
|
|
AllocaDecls(),
|
|
BBLabelDecls(),
|
|
VarDecls(),
|
|
FunctionDecls(FMap),
|
|
GlobalDecls(GMap),
|
|
InstrStmts(),
|
|
TypeDecls(TypeDecls),
|
|
FieldDecls(FieldDecls),
|
|
BlockToPHIIncoming(BlockToPHIIncoming) {}
|
|
|
|
void createAST(llvm::Function &F, clang::FunctionDecl &FD);
|
|
|
|
clang::Expr *getExprForValue(llvm::Value *V);
|
|
clang::Expr *getUIntLiteral(uint64_t U);
|
|
clang::Expr *getBoolLiteral(bool V);
|
|
clang::Expr *getLiteralFromConstant(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(llvm::Instruction *I, clang::FunctionDecl &FD);
|
|
clang::Stmt *buildStmt(llvm::Instruction &I);
|
|
clang::Expr *createRValueExprForBinaryOperator(llvm::Instruction &I);
|
|
clang::Expr *getParenthesizedExprForValue(llvm::Value *V);
|
|
|
|
private:
|
|
clang::VarDecl *LoopStateVarDecl = nullptr;
|
|
clang::VarDecl *SwitchStateVarDecl = nullptr;
|
|
};
|
|
} // namespace IR2AST
|
|
#endif // REVNGC_ASTBUILDANALYSIS_H
|