5#include "clang/Basic/OperatorKinds.h"
6#include "clang/Basic/Diagnostic.h"
12#include <unordered_map>
20#define DEBUG_TYPE "HDL"
67 : diag_e{diag_engine},
68 ast_context_{ast_context},
69 mod_vname_map_{mod_vname_map},
70 allmethodecls_{allmethodecls},
71 overridden_method_map_{overridden_method_map} {
72 LLVM_DEBUG(llvm::dbgs() <<
"Entering HDLBody constructor\n");
79 LLVM_DEBUG(llvm::dbgs() <<
"Entering HDLBody Run Method\n");
102 LLVM_DEBUG(llvm::dbgs() <<
"Exiting HDLBody Run Method\n");
105 LLVM_DEBUG(llvm::dbgs() <<
"[[ Destructor HDLBody ]]\n");
112 LLVM_DEBUG(llvm::dbgs() <<
"In TraverseStmt\n");
113 if (stmt ==
nullptr)
return false;
115 if (isa<CompoundStmt>(stmt)) {
116 LLVM_DEBUG(llvm::dbgs()
117 <<
"calling traverse compoundstmt from traversestmt\n");
119 }
else if (isa<DeclStmt>(stmt)) {
120 RecursiveASTVisitor::TraverseStmt(stmt);
122 }
else if (isa<CallExpr>(stmt)) {
123 if (CXXOperatorCallExpr *opercall = dyn_cast<CXXOperatorCallExpr>(stmt)) {
124 LLVM_DEBUG(llvm::dbgs() <<
"found cxxoperatorcallexpr\n");
126 }
else if (isa<CXXMemberCallExpr>(stmt)) {
131 }
else if (isa<CXXDefaultArgExpr>(stmt)) {
133 }
else if (isa<ReturnStmt>(stmt)) {
134 RecursiveASTVisitor::TraverseStmt(stmt);
135 }
else if (isa<CXXTemporaryObjectExpr>(stmt)) {
136 RecursiveASTVisitor::TraverseStmt(stmt);
138 if (isa<CXXConstructExpr>(stmt)) {
139 CXXConstructExpr *exp = (CXXConstructExpr *)stmt;
145 if ((exp->getNumArgs() == 1) &&
146 ((isa<IntegerLiteral>(exp->getArg(0))) || (isa<CXXBoolLiteralExpr>(exp->getArg(0)))) ) {
147 LLVM_DEBUG(llvm::dbgs()
148 <<
"CXXConstructExpr followed by integer literal found\n");
151 if (isa<IntegerLiteral>(exp->getArg(0))) {
152 IntegerLiteral *lit = (IntegerLiteral *)exp->getArg(0);
156 CXXBoolLiteralExpr * boollit = (CXXBoolLiteralExpr *) exp->getArg(0);
157 if (boollit->getValue()) s =
"1";
else s =
"0";
158 h_ret =
new hNode(s, hNode::hdlopsEnum::hLiteral);
163 te->
Enumerate((exp->getType()).getTypePtr());
165 hNodep h_tmp =
new hNode(hNode::hdlopsEnum::hNoop);
167 hNode::hdlopsEnum::hLiteral, h_tmp);
172 LLVM_DEBUG(llvm::dbgs()
173 <<
"stmt type " << stmt->getStmtClassName()
174 <<
" not recognized, calling default recursive ast visitor\n");
176 RecursiveASTVisitor::TraverseStmt(stmt);
177 if (
h_ret != oldh_ret) {
180 <<
"default recursive ast visitor called - returning translation\n");
183 for (
auto arg : stmt->children()) {
184 LLVM_DEBUG(llvm::dbgs() <<
"child stmt type "
185 << ((Stmt *)arg)->getStmtClassName() <<
"\n");
186 if (isa<CXXThisExpr>(arg))
continue;
188 if (
h_ret == oldh_ret) {
189 LLVM_DEBUG(llvm::dbgs() <<
"child stmt not handled\n");
191 h_ret =
new hNode(arg->getStmtClassName(), hNode::hdlopsEnum::hUnimpl);
200 int nargs = ((CXXTemporaryObjectExpr *)stmt)->getNumArgs();
204 (hNode::hdlopsEnum::hLiteral));
206 Expr **objargs = ((CXXTemporaryObjectExpr *)stmt)->getArgs();
207 for (
int i = 0; i < nargs; i++) {
215 hNodep h_initlist =
new hNode(hNode::hdlopsEnum::hVarInitList);
216 for (
auto tmpexpr : ((InitListExpr *)stmt)->inits()) {
225 hNodep hretstmt =
new hNode(hNode::hdlopsEnum::hReturnStmt);
226 if (((ReturnStmt *)stmt)->getRetValue() !=
nullptr) {
235 LLVM_DEBUG(llvm::dbgs() <<
"Found case stmt\n");
237 hNodep hcasep =
new hNode(hNode::hdlopsEnum::hSwitchCase);
238 if (ConstantExpr *expr =
239 dyn_cast<ConstantExpr>(((CaseStmt *)stmt)->getLHS())) {
240 llvm::APSInt val = expr->getResultAsAPSInt();
243 hNode::hdlopsEnum::hLiteral));
247 if (
h_ret != old_hret)
259 hNodep hcasep =
new hNode(hNode::hdlopsEnum::hSwitchDefault);
261 if (
h_ret != old_hret)
271 LLVM_DEBUG(llvm::dbgs() <<
"Found break stmt\n");
273 : hNode::hdlopsEnum::hBreak);
278 LLVM_DEBUG(llvm::dbgs() <<
"Found continue stmt\n");
279 h_ret =
new hNode(hNode::hdlopsEnum::hContinue);
286 hNodep h_cstmt =
new hNode(hNode::hdlopsEnum::hCStmt);
288 for (clang::Stmt *stmt : cstmt->body()) {
302 LLVM_DEBUG(llvm::dbgs() <<
"stmt result was empty\n");
321 for (
auto *DI : declstmt->decls())
323 auto *vardecl = dyn_cast<VarDecl>(DI);
324 if (!vardecl)
continue;
333 LLVM_DEBUG(llvm::dbgs() <<
"ProcessVarDecl var name is " << vardecl->getName()
336 QualType q = vardecl->getType();
337 const Type *tp = q.getTypePtr();
338 LLVM_DEBUG(llvm::dbgs() <<
"ProcessVarDecl type name is " << q.getAsString()
349 std::vector<llvm::APInt> array_sizes =
353 hNodep h_varlist =
new hNode(hNode::hdlopsEnum::hPortsigvarlist);
357 hNode::hdlopsEnum::hVardecl, h_varlist);
361 if (h_varlist->
child_list.size() == 0)
return true;
367 bool isuserdefinedclass =
false;
377 LLVM_DEBUG(HDLt.
print(llvm::dbgs()));
383 isuserdefinedclass =
true;
406 string qualmethodname =
"ConstructorMethod";
407 if (Expr *declinit = vardecl->getInit()) {
408 LLVM_DEBUG(llvm::dbgs() <<
"ProcessVarDecl has an init: \n");
410 CXXConstructExpr *tmpdeclinit = dyn_cast<CXXConstructExpr>(declinit);
411 if ((tmpdeclinit != NULL) &&(tmpdeclinit->getConstructor()->hasTrivialBody())) {
412 isuserdefinedclass =
false;
415 if (isuserdefinedclass && (tmpdeclinit != NULL)) {
423 const CXXConstructorDecl *cnstrdcl = tmpdeclinit->getConstructor();
428 string methodname = cnstrdcl->getNameAsString();
429 qualmethodname = cnstrdcl->getQualifiedNameAsString();
431 LLVM_DEBUG(llvm::dbgs() <<
"ConstructorDecl " << methodname <<
", "
432 << qualmethodname <<
" for var follows\n");
433 LLVM_DEBUG(cnstrdcl->dump());
436 new hNode(qualmethodname, hNode::hdlopsEnum::hMethodCall);
437 const std::vector<StringRef> tmpmodstr{
"sc_module"};
439 LLVM_DEBUG(llvm::dbgs()
440 <<
"user-defined class is defined in sc module\n");
458 hNodep varinitp =
new hNode(hNode::hdlopsEnum::hVarAssign);
476 new hNode(expr->getOpcodeStr().str(),
477 hNode::hdlopsEnum::hBinop);
479 string opcodestr = expr->getOpcodeStr().str();
480 string exprtypstr = expr->getType().getAsString();
481 LLVM_DEBUG(llvm::dbgs() <<
"in TraverseBinaryOperator, opcode is "
482 << opcodestr <<
"\n");
504 if ((opcodestr ==
",") &&
511 LLVM_DEBUG(llvm::dbgs() <<
"found comma, with sc type, expr follows\n");
513 h_binop->
set(
"concat");
520 if (
h_ret == save_h_ret)
531 LLVM_DEBUG(llvm::dbgs() <<
"in TraverseUnaryOperator expr node is \n");
534 auto opcstr = expr->getOpcode();
538 if ((expr->getOpcodeStr(opcstr).str() ==
"++") ||
539 (expr->getOpcodeStr(opcstr).str() ==
"--")) {
540 if (expr->isPostfix())
541 h_unop =
new hNode(expr->getOpcodeStr(opcstr).str(),
542 hNode::hdlopsEnum::hPostfix);
544 h_unop =
new hNode(expr->getOpcodeStr(opcstr).str(),
545 hNode::hdlopsEnum::hPrefix);
547 h_unop =
new hNode(expr->getOpcodeStr(opcstr).str(),
548 hNode::hdlopsEnum::hUnop);
559 LLVM_DEBUG(llvm::dbgs() <<
"in VisitConditionalOperator expr node is \n");
562 hNodep h_condop =
new hNode(hNode::hdlopsEnum::hCondop);
574 LLVM_DEBUG(llvm::dbgs() <<
"In integerliteral\n");
576 h_ret =
new hNode(s, hNode::hdlopsEnum::hLiteral);
582 LLVM_DEBUG(llvm::dbgs() <<
"In boollitexpr\n");
583 bool v = b->getValue();
584 h_ret =
new hNode(v ?
"1" :
"0", hNode::hdlopsEnum::hLiteral);
591 LLVM_DEBUG(llvm::dbgs() <<
"In TraverseDeclRefExpr\n");
593 ValueDecl *value = expr->getDecl();
594 if (isa<EnumConstantDecl>(value)) {
595 EnumConstantDecl *cd = (EnumConstantDecl *)value;
596 LLVM_DEBUG(llvm::dbgs()
597 <<
"got enum constant value " << cd->getInitVal() <<
"\n");
599 hNode::hdlopsEnum::hLiteral);
605 string name = (expr->getNameInfo()).getName().getAsString();
606 LLVM_DEBUG(llvm::dbgs() <<
"name is " << name <<
"\n");
609 if (isa<VarDecl>(value) && ((VarDecl *)value)->isConstexpr()) {
610 VarDecl *vard = (VarDecl *)value;
611 Expr *einit = vard->getInit();
612 clang::Expr::EvalResult result;
613 if (einit->EvaluateAsInt(result, vard->getASTContext())) {
616 hNode::hdlopsEnum::hLiteral);
620 if (isa<FunctionDecl>(value)) {
636 FunctionDecl *funval = (FunctionDecl *)value;
638 string qualfuncname{value->getQualifiedNameAsString()};
648 hNodep hfuncall =
new hNode(qualfuncname, hNode::hdlopsEnum::hMethodCall);
651 string tmpname =
FindFname((FunctionDecl *)value);
653 LLVM_DEBUG(llvm::dbgs() <<
"adding method " << qualfuncname
654 <<
" with pointer " << value <<
" \n");
658 hfuncall->
set(tmpname);
663 string typname = (expr->getType()).getAsString();
664 if (typname.find(
"sc_dt::sc_concat") != std::string::npos) {
666 hNodep hconcat =
new hNode(name, hNode::hdlopsEnum::hBinop);
670 h_ret =
new hNode(name, hNode::hdlopsEnum::hBuiltinFunction);
676 string newname =
FindVname(expr->getDecl());
677 LLVM_DEBUG(llvm::dbgs() <<
"new name is " << newname <<
"\n");
678 LLVM_DEBUG(expr->getDecl()->dump(llvm::dbgs()));
681 new hNode(newname.empty() ? name : newname, hNode::hdlopsEnum::hVarref);
686 LLVM_DEBUG(llvm::dbgs()
687 <<
"In TraverseArraySubscriptExpr, base, idx, tree follow\n");
688 LLVM_DEBUG(llvm::dbgs() <<
"base:\n");
689 LLVM_DEBUG(expr->getBase()->dump(llvm::dbgs(),
ast_context_));
690 LLVM_DEBUG(llvm::dbgs() <<
"idx:\n");
691 LLVM_DEBUG(expr->getIdx()->dump(llvm::dbgs(),
ast_context_));
692 LLVM_DEBUG(llvm::dbgs() <<
"tree:\n");
694 hNodep h_arrexpr =
new hNode(
"ARRAYSUBSCRIPT", hNode::hdlopsEnum::hBinop);
704 bool is_explicitly_overridden =
false;
706 LangOptions LangOpts;
708 LangOpts.CPlusPlus =
true;
709 const PrintingPolicy Policy(LangOpts);
711 LLVM_DEBUG(llvm::dbgs()
712 <<
"In TraverseCXXMemberCallExpr, printing implicit object arg\n");
716 Expr *rawarg = (callexpr->getImplicitObjectArgument());
717 LLVM_DEBUG(llvm::dbgs() <<
"raw implicitobjectargument follows\n");
720 Expr *objarg = (callexpr->getImplicitObjectArgument())->IgnoreImplicit();
722 llvm::dbgs() <<
"implicitobjectargument, ignore implicit follows\n");
724 CXXRecordDecl *cdecl = callexpr->getRecordDecl();
725 const Type *typeformethodclass = cdecl->getTypeForDecl();
726 LLVM_DEBUG(llvm::dbgs() <<
"Type pointer from RecordDecl is "
727 << typeformethodclass <<
"\n");
730 if (dyn_cast<ImplicitCastExpr>(rawarg)) {
731 argtyp = rawarg->getType();
732 is_explicitly_overridden =
true;
734 argtyp = objarg->getType();
736 LLVM_DEBUG(llvm::dbgs() <<
"type of x in x.f(5) is "
737 << argtyp.getAsString(Policy) <<
"\n");
738 QualType objtyp = callexpr->getObjectType();
739 LLVM_DEBUG(llvm::dbgs() <<
"... and object type is "
740 << objtyp.getAsString(Policy) <<
"\n");
741 string methodname =
"NoMethod", qualmethodname =
"NoQualMethod";
743 CXXMethodDecl *methdcl = callexpr->getMethodDecl();
748 LLVM_DEBUG(llvm::dbgs() <<
"methoddecl follows\n");
749 LLVM_DEBUG(methdcl->dump(llvm::dbgs()));
750 if (isa<NamedDecl>(methdcl) && methdcl->getDeclName()) {
751 methodname = methdcl->getNameAsString();
752 qualmethodname = methdcl->getQualifiedNameAsString();
757 LLVM_DEBUG(llvm::dbgs()
758 <<
"here is method printname " << methodname <<
" and qual name "
759 << qualmethodname <<
" and declp " << methdcl <<
" \n");
760 if (methodname.compare(0, 8,
"operator") ==
763 LLVM_DEBUG(llvm::dbgs() <<
"Found operator conversion node\n");
770 hNode *h_callp = NULL;
771 LLVM_DEBUG(llvm::dbgs() <<
"found " << methodname <<
"\n");
782 bool foundsctype =
lutil.
isSCType(qualmethodname, typeformethodclass);
799 if ((methodname ==
"read") && foundsctype)
800 opc = hNode::hdlopsEnum::hSigAssignR;
801 else if ((methodname ==
"write") && foundsctype)
802 opc = hNode::hdlopsEnum::hSigAssignL;
804 opc = hNode::hdlopsEnum::hWait;
805 else if (foundsctype) {
806 opc = hNode::hdlopsEnum::hBuiltinFunction;
808 opc = hNode::hdlopsEnum::hMethodCall;
811 qualmethodname +=
":" + methodname;
815 h_callp =
new hNode(qualmethodname, opc);
818 string tmpname =
FindFname((FunctionDecl *)methdcl);
820 LLVM_DEBUG(llvm::dbgs() <<
"adding method " << qualmethodname
821 <<
" with pointer " << methdcl <<
" \n");
835 h_callp->
set(tmpname);
837 methodname = qualmethodname;
841 h_callp =
new hNode(methodname, opc);
844 if ((opc == hNode::hdlopsEnum::hWait) && (callexpr->getNumArgs() > 0)) {
855 if ((
add_info) || ((opc != hNode::hdlopsEnum::hMethodCall) ||
856 (opc == hNode::hdlopsEnum::hMethodCall) &&
862 for (
auto arg : callexpr->arguments()) {
876 case OO_GreaterEqual:
877 case OO_ExclaimEqual:
887 string operatorname = getOperatorSpelling(opcall->getOperator());
888 string operatortype = (opcall->getType()).getAsString();
891 LLVM_DEBUG(llvm::dbgs() <<
"In TraverseCXXOperatorCallExpr, Operator name is "
892 << operatorname <<
"\n");
893 LLVM_DEBUG(llvm::dbgs() <<
"Type name " << operatortype <<
"\n");
894 LLVM_DEBUG(opcall->getType()->dump(llvm::dbgs(),
ast_context_));
897 const Type *optypepointer = opcall->getType().getTypePtr();
919 if ((operatorname ==
"=") ||
924 (opcall->getType())->isBuiltinType() ||
925 ((operatorname ==
"<<") &&
926 (operatortype.find(
"sensitive") != std::string::npos))) {
927 LLVM_DEBUG(llvm::dbgs() <<
"Processing operator call type\n");
929 if ((operatorname.compare(
"()") == 0) &&
930 (operatortype.find(
"subref") != string::npos) &&
931 (opcall->getNumArgs() == 3)) {
933 h_operop =
new hNode(
"SLICE", hNode::hdlopsEnum::hBinop);
935 if (operatorname ==
"[]")
936 h_operop =
new hNode(
"ARRAYSUBSCRIPT", hNode::hdlopsEnum::hBinop);
937 else if ((operatorname ==
"++") || (operatorname ==
"--")) {
938 if (opcall->getNumArgs() == 2)
939 h_operop =
new hNode(operatorname, hNode::hdlopsEnum::hPostfix);
941 h_operop =
new hNode(operatorname, hNode::hdlopsEnum::hPrefix);
943 if (opcall->getNumArgs() == 1)
944 h_operop =
new hNode(operatorname, hNode::hdlopsEnum::hUnop);
946 h_operop =
new hNode(operatorname, hNode::hdlopsEnum::hBinop);
948 if ((operatorname ==
",") )
949 h_operop->
set(
"concat");
954 int nargs = (h_operop->
getopc() == hNode::hdlopsEnum::hPostfix ||
955 h_operop->
getopc() == hNode::hdlopsEnum::hPrefix)
957 : opcall->getNumArgs();
958 for (
int i = 0; i < nargs; i++) {
961 if (
h_ret == save_h_ret)
965 LLVM_DEBUG(llvm::dbgs()
966 <<
"operator call argument " << i <<
" follows\n");
967 LLVM_DEBUG(opcall->getArg(i)->dump(llvm::dbgs(),
ast_context_));
973 LLVM_DEBUG(llvm::dbgs() <<
"not yet implemented operator call expr, opc is "
974 << clang::getOperatorSpelling(opcall->getOperator())
975 <<
" num arguments " << opcall->getNumArgs()
978 h_ret =
new hNode(hNode::hdlopsEnum::hUnimpl);
983 bool founduserclass =
false;
984 LLVM_DEBUG(llvm::dbgs() <<
"In TraverseMemberExpr\n");
985 string nameinfo = (memberexpr->getMemberNameInfo()).getName().getAsString();
986 LLVM_DEBUG(llvm::dbgs() <<
"name is " << nameinfo
987 <<
", base and memberdecl trees follow\n");
988 LLVM_DEBUG(llvm::dbgs() <<
"base is \n");
989 LLVM_DEBUG(memberexpr->getBase()->dump(llvm::dbgs(),
ast_context_););
990 LLVM_DEBUG(llvm::dbgs() <<
"memberdecl is " << memberexpr->getMemberDecl()
993 LLVM_DEBUG(memberexpr->getMemberDecl()->dump(llvm::dbgs()));
994 if (FieldDecl *fld = dyn_cast<FieldDecl>(memberexpr->getMemberDecl())) {
995 LLVM_DEBUG(llvm::dbgs() <<
"and field decl parent record pointer is "
996 << fld->getParent() <<
"\n");
997 const Type *classrectype = fld->getParent()->getTypeForDecl();
998 LLVM_DEBUG(llvm::dbgs() <<
"and field decl parent record type is "
999 << classrectype <<
"\n");
1001 LLVM_DEBUG(llvm::dbgs()
1002 <<
"member expr, found user defined class in usertypes "
1003 << classrectype <<
"\n");
1004 founduserclass =
true;
1008 string thisref = founduserclass ?
"hthis##" :
"";
1012 if (
h_ret != old_h_ret) {
1013 if (
h_ret->
h_op == hNode::hdlopsEnum::hVarref) {
1016 hNode::hdlopsEnum::hVarref);
1018 h_ret = memexprnode;
1022 LLVM_DEBUG(llvm::dbgs()
1023 <<
"Value returned from member expr base was not Varref\n");
1025 string newname =
FindVname(memberexpr->getMemberDecl());
1026 LLVM_DEBUG(llvm::dbgs()
1027 <<
"member with base expr new name is " << newname <<
"\n");
1028 if ((newname ==
"")) {
1029 LLVM_DEBUG(llvm::dbgs() <<
"vname lookup of memberdecl is null, "
1030 "assuming field reference\n");
1031 hNodep hfieldref =
new hNode(hNode::hdlopsEnum::hFieldaccess);
1034 new hNode(thisref + nameinfo, hNode::hdlopsEnum::hField));
1039 new hNode(newname ==
"" ? thisref + nameinfo : thisref + newname,
1040 hNode::hdlopsEnum::hVarref);
1042 h_ret = memexprnode;
1048 string newname =
FindVname(memberexpr->getMemberDecl());
1049 LLVM_DEBUG(llvm::dbgs() <<
"member expr new name is " << newname <<
"\n");
1051 h_ret =
new hNode(newname.empty() ? thisref + nameinfo : thisref + newname,
1052 hNode::hdlopsEnum::hVarref);
1061 if (isa<FunctionDecl>(callexpr->getCalleeDecl()) &&
1062 ((FunctionDecl *)callexpr->getCalleeDecl())->isConstexpr()) {
1063 Expr::EvalResult res;
1064 if (callexpr->EvaluateAsRValue(
1065 res, callexpr->getCalleeDecl()->getASTContext())) {
1067 hNode::hdlopsEnum::hLiteral);
1082 hNode::hdlopsEnum::hMethodCall);
1085 for (
auto arg : callexpr->arguments()) {
1088 if (
h_ret != sret) {
1093 LLVM_DEBUG(llvm::dbgs() <<
"found a call expr"
1094 <<
" AST follows\n ");
1095 LLVM_DEBUG(callexpr->dump(llvm::dbgs(),
ast_context_););
1100 hNodep h_ifstmt, h_ifc = NULL, h_ifthen = NULL, h_ifelse = NULL;
1101 h_ifstmt =
new hNode(hNode::hdlopsEnum::hIfStmt);
1102 if (ifs->getConditionVariable()) {
1104 LLVM_DEBUG(llvm::dbgs() <<
"Variable declarations are not allowed in if "
1105 "conditions, skipping\n");
1115 if (ifs->getElse()) {
1121 if (h_ifelse) h_ifstmt->
child_list.push_back(h_ifelse);
1127 hNodep h_forstmt, h_forinit, h_forcond, h_forinc, h_forbody;
1128 LLVM_DEBUG(llvm::dbgs() <<
"For stmt\n");
1129 h_forstmt =
new hNode(hNode::hdlopsEnum::hForStmt);
1130 if ((fors->getInit() != NULL) && (isa<CompoundStmt>(fors->getInit())))
1131 LLVM_DEBUG(llvm::dbgs()
1132 <<
"Compound stmt not handled in for init, skipping\n");
1134 if ((fors->getInit() != NULL) && isa<DeclStmt>(fors->getInit())) {
1135 LLVM_DEBUG(llvm::dbgs() <<
"for init is a decl stmt\n");
1136 LLVM_DEBUG((fors->getInit())->dump(llvm::dbgs(),
ast_context_));
1140 h_forinit = (
h_ret == NULL) ?
new hNode(hNode::hdlopsEnum::hNoop)
1143 h_forcond = (
h_ret == NULL) ?
new hNode(hNode::hdlopsEnum::hNoop)
1146 h_forinc =(
h_ret == NULL) ?
new hNode(hNode::hdlopsEnum::hNoop)
1148 LLVM_DEBUG(llvm::dbgs() <<
"For loop body\n");
1149 LLVM_DEBUG(fors->getBody()->dump(llvm::dbgs(),
ast_context_););
1162 LLVM_DEBUG(llvm::dbgs() <<
"In ProcessSwitchCase\n");
1165 if (isa<DefaultStmt>(sc)) {
1166 LLVM_DEBUG(llvm::dbgs() <<
"Found default stmt in switchcase\n");
1167 hcasep =
new hNode(hNode::hdlopsEnum::hSwitchDefault);
1170 LLVM_DEBUG(llvm::dbgs() <<
"Found case stmt in switchcase\n");
1171 hcasep =
new hNode(hNode::hdlopsEnum::hSwitchCase);
1172 if (ConstantExpr *expr =
1173 dyn_cast<ConstantExpr>(((CaseStmt *)sc)->getLHS())) {
1174 llvm::APSInt val = expr->getResultAsAPSInt();
1177 hNode::hdlopsEnum::hLiteral));
1181 if (
h_ret != old_hret) {
1192 LLVM_DEBUG(llvm::dbgs() <<
"Switch stmt body -----\n");
1193 LLVM_DEBUG(switchs->getBody()->dump(llvm::dbgs(),
ast_context_););
1194 LLVM_DEBUG(llvm::dbgs() <<
"End Switch stmt body -----\n");
1196 h_switchstmt =
new hNode(hNode::hdlopsEnum::hSwitchStmt);
1203 if (
h_ret != old_ret) {
1206 h_switchstmt->
child_list.push_back(
new hNode(hNode::hdlopsEnum::hUnimpl));
1212 if (
h_ret != old_ret) {
1238 h_ret = h_switchstmt;
1244 hNodep h_whilestmt, h_whilecond, h_whilebody;
1245 LLVM_DEBUG(llvm::dbgs() <<
"While stmt\n");
1246 h_whilestmt =
new hNode(hNode::hdlopsEnum::hWhileStmt);
1247 if (whiles->getConditionVariable()) {
1250 <<
"Variable declarations not handled in while condition, skipping\n");
1254 h_whilecond =
h_ret;
1259 h_whilebody =
h_ret;
1260 h_whilestmt->
child_list.push_back(h_whilecond);
1261 h_whilestmt->
child_list.push_back(h_whilebody);
1262 h_ret = h_whilestmt;
1271 hNodep h_whilestmt, h_whilecond, h_whilebody;
1272 LLVM_DEBUG(llvm::dbgs() <<
"Do stmt\n");
1273 h_whilestmt =
new hNode(hNode::hdlopsEnum::hDoStmt);
1276 h_whilecond =
h_ret;
1280 h_whilebody =
h_ret;
1281 h_whilestmt->
child_list.push_back(h_whilecond);
1282 h_whilestmt->
child_list.push_back(h_whilebody);
1283 h_ret = h_whilestmt;
1310 LLVM_DEBUG(llvm::dbgs() <<
"Vname Dump\n");
1313 LLVM_DEBUG(llvm::dbgs() <<
"(" << var.first <<
"," << var.second.oldn
1314 <<
", " << var.second.newn <<
")\n");
1315 if (
add_info && (var.second.newn.find(gvar_prefix) == std::string::npos)) {
1319 var.second.h_vardeclp->h_op = hNode::hdlopsEnum::hVardeclrn;
1320 var.second.h_vardeclp->child_list.push_back(
1321 new hNode(var.second.oldn, hNode::hdlopsEnum::hLiteral));
1323 if (var.second.newn.find(gvar_prefix) == std::string::npos)
1325 hvns->
child_list.push_back(var.second.h_vardeclp);
1334 hNodep hassignchain =
new hNode(hNode::hdlopsEnum::hCStmt);
1343 std::reverse(hassignchain->
child_list.begin(),
1345 return hassignchain;
1348 int64_t waitarg = 0;
1350 clang::Expr::EvalResult result{};
1352 waitarg = result.Val.getInt().getExtValue();
1353 llvm::dbgs() <<
" wait arg val: " << waitarg <<
"\n";
1355 hNodep arglit =
new hNode( std::to_string(waitarg), hNode::hdlopsEnum::hLiteral);
1360 if (hswitchstmt->
child_list.size() == 0)
return;
1362 for (
int i = 1; i < hswitchstmt->
child_list.size(); i++) {
1364 hNode::hdlopsEnum::hSwitchCase) &&
1366 hNode::hdlopsEnum::hSwitchDefault)) {
1371 hswitchstmt->
child_list[i]->set(hNode::hdlopsEnum::hLast);
1378 [](
hNodep hp) { return hp->getopc() == hNode::hdlopsEnum::hLast; }),
void print(llvm::raw_ostream &modelout=llvm::outs(), unsigned int indnt=2)
usertype_info_t usertype_info
void SCtype2hcode(string prefix, Tree< TemplateType > *template_argtp, std::vector< llvm::APInt > *arr_sizes, hNode::hdlopsEnum h_op, hNodep &h_info)
void set(hdlopsEnum h, string s="")
std::vector< hNodep > child_list
void print(llvm::raw_ostream &modelout=llvm::outs(), unsigned int indnt=2)
void print(llvm::raw_ostream &modelout=llvm::outs(), unsigned int indnt=2)
method_object_map_t methodobjtypemap
void add_entry(T declp, string old_name, hNodep hnp)
void set_prefix(string prefix)
string find_entry_newn(T declp, bool set_ref=false)
bool isSCFunc(const string &tstring)
bool isSCMacro(const std::string &str_in)
bool isSCBuiltinType(const string &tstring, const Type *typ=NULL)
bool isSCType(const string &tstring, const clang::Type *typ=NULL)
static void make_ident(string &nm)
Tree< TemplateType > * getTemplateArgTreePtr()
void Enumerate(const clang::Type *type)
const ASTContext & ast_context_
bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *opcall)
bool VisitBinaryOperator(BinaryOperator *expr)
bool isLogicalOp(clang::OverloadedOperatorKind opc)
bool VisitCaseStmt(CaseStmt *stmt)
string FindFname(FunctionDecl *funcd)
hdecl_name_map_t vname_map
overridden_method_map_t & overridden_method_map_
hfunc_name_map_t methodecls
bool VisitCompoundStmt(CompoundStmt *compoundStmt)
bool VisitDefaultStmt(DefaultStmt *stmt)
void NormalizeSwitchStmt(hNodep hswitchbody)
void GetWaitArg(hNodep &h_callp, Expr *callarg)
bool VisitConditionalOperator(ConditionalOperator *expr)
bool VisitReturnStmt(ReturnStmt *stmt)
bool VisitDeclStmt(DeclStmt *declstmt)
bool ProcessVarDecl(VarDecl *vardecl)
bool VisitMemberExpr(MemberExpr *memberexpr)
string generate_vname(string nm)
bool VisitUnaryOperator(UnaryOperator *expr)
bool isUserClass(const Type *classrectype)
bool VisitArraySubscriptExpr(ArraySubscriptExpr *expr)
void AddVnames(hNodep &hvns)
bool VisitSwitchStmt(SwitchStmt *switchs)
bool TraverseStmt(Stmt *stmt)
HDLBody(clang::DiagnosticsEngine &diag_engine, const ASTContext &ast_context, hdecl_name_map_t &mod_vname_map, hfunc_name_map_t &allmethodecls, overridden_method_map_t &overridden_method_map)
hdecl_name_map_t & mod_vname_map_
hfunc_name_map_t & allmethodecls_
bool isAssignOp(hNodep hp)
bool VisitWhileStmt(WhileStmt *whiles)
bool VisitContinueStmt(ContinueStmt *stmt)
HDLType * HDLt_userclassesp_
void Run(Stmt *stmt, hNodep &h_top, HDLBodyMode runmode, HDLType *HDLt_userclassesp=NULL)
hNodep NormalizeAssignmentChain(hNodep hinp)
bool VisitInitListExpr(InitListExpr *stmt)
bool ProcessSwitchCase(SwitchCase *cases)
bool VisitDoStmt(DoStmt *whiles)
bool VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *b)
bool VisitIfStmt(IfStmt *ifs)
bool VisitCallExpr(CallExpr *callexpr)
bool VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *stmt)
bool VisitBreakStmt(BreakStmt *stmt)
string FindVname(NamedDecl *vard)
bool VisitCXXMemberCallExpr(CXXMemberCallExpr *callexpr)
bool VisitDeclRefExpr(DeclRefExpr *expr)
bool VisitForStmt(ForStmt *fors)
bool VisitIntegerLiteral(IntegerLiteral *lit)
std::unordered_map< const CXXMethodDecl *, const CXXMethodDecl * > overridden_method_map_t
ArraySizesType getConstantArraySizes(const clang::ValueDecl *fd)
bool isCXXMemberCallExprSystemCCall(const clang::CallExpr *ce, const std::vector< llvm::StringRef > &names)
bool isInNamespace(const clang::ValueDecl *fd, const std::vector< llvm::StringRef > &names)
std::string toString(const T &i)
userrectype_map_t userrectypes