From e4beb61b7b28fe7360394a2821b63469d245d559 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Mon, 26 Apr 2021 10:39:29 -0400 Subject: [PATCH] check class data members for write funciton --- tools/include/eosio/codegen.hpp | 79 +++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index f3013b709..6ff54b013 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -280,7 +280,19 @@ namespace eosio { namespace cdt { return true; } - void process_function(FunctionDecl *func_decl) { + FunctionDecl* get_rhs_fd(Expr *rhs) const { + while (ImplicitCastExpr *ice = dyn_cast(rhs)) { + rhs = ice->getSubExpr(); + } + if (DeclRefExpr *rhs_dre = dyn_cast(rhs)) { + if (FunctionDecl *fd = dyn_cast(rhs_dre->getFoundDecl())) { + return fd; + } + } + return nullptr; + } + + void process_function(FunctionDecl* func_decl) { if (func_decl->isThisDeclarationADefinition() && func_decl->hasBody()) { Stmt *stmts = func_decl->getBody(); for (auto it = stmts->child_begin(); it != stmts->child_end(); it++) { @@ -308,20 +320,19 @@ namespace eosio { namespace cdt { if (indi_func_map.count(dre->getFoundDecl()) != 0) { func_calls[func_decl].push_back(call); } + } else if (MemberExpr *me = dyn_cast(expr)) { + if (indi_func_map.count(me->getMemberDecl()) != 0) { + func_calls[func_decl].push_back(call); + } } } } else if (DeclStmt *ds = dyn_cast(s)) { if (ds->isSingleDecl()) { if (VarDecl *vd = dyn_cast(ds->getSingleDecl())) { if (Expr *init = vd->getInit()) { - while (ImplicitCastExpr *ice = dyn_cast(init)) { - init = ice->getSubExpr(); - } - if (DeclRefExpr *dre = dyn_cast(init)) { - if (FunctionDecl *fd = dyn_cast(dre->getFoundDecl())) { - if (func_calls.count(fd) != 0) { - indi_func_map[vd] = fd; - } + if (FunctionDecl *fd = get_rhs_fd(init)) { + if (func_calls.count(fd) != 0) { + indi_func_map[vd] = fd; } } } @@ -329,16 +340,13 @@ namespace eosio { namespace cdt { } } else if (BinaryOperator *bo = dyn_cast(s)) { if (Expr *lhs = bo->getLHS()) { - if (DeclRefExpr *lhs_dre = dyn_cast(lhs)) { - if (Expr *rhs = bo->getRHS()) { - while (ImplicitCastExpr *ice = dyn_cast(rhs)) { - rhs = ice->getSubExpr(); - } - if (DeclRefExpr *rhs_dre = dyn_cast(rhs)) { - if (FunctionDecl *fd = dyn_cast(rhs_dre->getFoundDecl())) { - if (func_calls.count(fd) != 0) { - indi_func_map[lhs_dre->getFoundDecl()] = fd; - } + if (Expr *rhs = bo->getRHS()) { + if (FunctionDecl *fd = get_rhs_fd(rhs)) { + if (func_calls.count(fd) != 0) { + if (DeclRefExpr *lhs_dre = dyn_cast(lhs)) { + indi_func_map[lhs_dre->getFoundDecl()] = fd; + } else if (MemberExpr *lhs_me = dyn_cast(lhs)) { + indi_func_map[lhs_me->getMemberDecl()] = fd; } } } @@ -350,8 +358,18 @@ namespace eosio { namespace cdt { } } - void process_class() { - // TODO(handel member variables) + void process_class(CXXRecordDecl* decl) { + for(auto it = decl->decls_begin(); it != decl->decls_end(); ++it) { + if(FieldDecl *f = dyn_cast(*it) ) { + if (Expr *init = f->getInClassInitializer()) { + if (FunctionDecl *fd = get_rhs_fd(init)) { + if (func_calls.count(fd) != 0) { + indi_func_map[f] = fd; + } + } + } + } + } } virtual bool VisitFunctionDecl(FunctionDecl* func_decl) { @@ -376,14 +394,9 @@ namespace eosio { namespace cdt { } else if (auto* vd = dyn_cast(decl)) { if (vd->hasGlobalStorage()) { if (Expr *init = vd->getInit()) { - while (ImplicitCastExpr *ice = dyn_cast(init)) { - init = ice->getSubExpr(); - } - if (DeclRefExpr *dre = dyn_cast(init)) { - if (FunctionDecl *fd = dyn_cast(dre->getFoundDecl())) { - if (func_calls.count(fd) != 0) { - indi_func_map[vd] = fd; - } + if (FunctionDecl *fd = get_rhs_fd(init)) { + if (func_calls.count(fd) != 0) { + indi_func_map[vd] = fd; } } } @@ -391,6 +404,14 @@ namespace eosio { namespace cdt { } return true; } + + virtual bool VisitCXXRecordDecl(CXXRecordDecl* decl) { + codegen& cg = codegen::get(); + if (decl->isEosioContract()) { + process_class(decl); + } + return true; + } }; class eosio_codegen_consumer : public ASTConsumer, public generation_utils {