systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
HDLMain.cpp
Go to the documentation of this file.
1// clang-format off
2#include <regex>
3#include <tuple>
4#include <unordered_map>
5#include "SystemCClang.h"
6#include "PortBinding.h"
7#include "ArrayTypeUtils.h"
8#include "Tree.h"
9#include "HDLMain.h"
10//#include "TemplateParametersMatcher.h"
11#include "SensitivityMatcher.h"
12#include "clang/Basic/FileManager.h"
13#include "llvm/Support/Debug.h"
14#include "clang/Basic/Diagnostic.h"
15
16#include "HDLHnode.h"
17#include "HDLThread.h"
18
19#include <iostream>
20
21#include "APIntUtils.h"
22// clang-format on
24#undef DEBUG_TYPE
25#define DEBUG_TYPE "HDL"
26
27using namespace std;
28using namespace hnode;
29using namespace systemc_clang;
30using namespace clang;
31
32namespace systemc_hdl {
33
34 std::unique_ptr<clang::tooling::FrontendActionFactory>
35 newFrontendActionFactory(const std::string &top_module) {
36 return std::unique_ptr<tooling::FrontendActionFactory>(
37 new HDLFrontendActionFactory(top_module));
38 }
39
40
50 Model *model = getSystemCModel();
51
52 std::error_code ec;
53 string outputfn;
54
56 //
57
58 LLVM_DEBUG(llvm::dbgs() << "HDL-FILE-OUTPUT: " << hdl_file_out_ << "\n"; );
59
60 SourceManager &sm = getSourceManager();
61 FileID fileID = sm.getMainFileID();
62 const FileEntry *fileentry = sm.getFileEntryForID(fileID);
63 auto opt_fref = sm.getFileEntryRefForID(fileID) ;
64 const FileEntryRef &fref = *opt_fref;
65
66
67 //FileID fileID = getSourceManager().getMainFileID();
68 //const FileEntry *fileentry = getSourceManager().getFileEntryForID(fileID);
69 if (hdl_file_out_ == "") {
70 if (!fileentry) {
71 outputfn = "HCodeout";
72 LLVM_DEBUG(llvm::dbgs()
73 << "Null file entry for tranlation unit for this astcontext\n");
74 } else {
75
76 outputfn = fref.getName().str();
77
78 //outputfn = fileentry->getName().str();
79 regex r("\\.cpp");
80 outputfn = regex_replace(outputfn, r, "_hdl");
81
82 LLVM_DEBUG(llvm::dbgs() << "File name is " << outputfn << "\n");
83 }
84 } else {
85 outputfn = hdl_file_out_;
86 }
87
88 llvm::raw_fd_ostream HCodeOut(outputfn + ".txt", ec,
89 llvm::sys::fs::CD_CreateAlways);
90 LLVM_DEBUG(llvm::dbgs() << "file " << outputfn
91 << ".txt, create error code is " << ec.value()
92 << "\n");
93
94 LLVM_DEBUG(llvm::dbgs() << "\n SC HDL plugin\n");
95
96 // typedef std::vector< modulePairType > moduleMapType;
97 // typedef std::pair<std::string, ModuleInstance *> modulePairType;
98
99
100 ModuleInstance *modinstance{model->getRootModuleInstance()};
101 if (modinstance == nullptr) {
102 LLVM_DEBUG(llvm::dbgs() << "\nRoot instance not found, exiting\n");
103 return false;
104 }
105
106 // generate module instance for top module and its submodules
107
108 //string modname = modinstance->getName()+mod_newn.newname(); // include original name for readability
109
110 hNodep h_module = new hNode(hNode::hdlopsEnum::hModule);
111
112 // need to provide an old name for module instance decl
113 // since it's not derived from clang NamedDecl and doesn't have
114 // a str() class to dereference llvm:StringRef
115
116 mod_name_map.add_entry(modinstance, modinstance->getName(), h_module);
117 LLVM_DEBUG(llvm::dbgs() << "\ntop level module " << modinstance->getName()
118 << " renamed " << h_module->getname() << "\n");
119
120 //mod_name_map[modinstance] = {modinstance->getName(),
121 // modname, h_module};
122
123 SCmodule2hcode(modinstance, h_module, HCodeOut);
124 // h_module->print(HCodeOut);
125
126 LLVM_DEBUG(llvm::dbgs() << "User Types Map\n");
127
128 while (!HDLt.usertype_info.usertypes.empty()) {
133 for (auto t : usertypestmp) {
134 LLVM_DEBUG(llvm::dbgs()
135 << "User Type --------\n"
136 << t.first << ":" << t.second.getTypePtr() << t.second.getAsString() <<"\n");
137 LLVM_DEBUG(t.second->dump(llvm::dbgs(), getContext()));
138 LLVM_DEBUG(llvm::dbgs() << "---------\n");
139 HDLt.addtype(t.first, t.second, getContext())->print(HCodeOut);
140 }
141 }
142 return true;
143 }
144
146 llvm::raw_fd_ostream &HCodeOut) {
147 const std::vector<ModuleInstance *> &submodv = mod->getNestedModuleInstances();
148 const std::vector<ModuleInstance *> &basemods = mod->getBaseInstances();
149
154 overridden_method_map_t overridden_method_map;
155
156 LLVM_DEBUG( llvm::dbgs() << "Processing module " << mod->getName() << " instance " << mod->getInstanceName() << "\n");
157 LLVM_DEBUG( llvm::dbgs() << "dumping base instances \n");
158 LLVM_DEBUG(mod->dump_base_instances(llvm::dbgs()));
159 LLVM_DEBUG( llvm::dbgs() << "end base instances \n");
160
161 const CXXRecordDecl *cdecl{mod->getModuleClassDecl()};
162 LLVM_DEBUG( llvm::dbgs() << "Methods in this module\n");
163 for (const auto &method : cdecl->methods()) {
164 if (isValidMethod(method)) {
165 if (method->isVirtual()) {
166 LLVM_DEBUG( llvm::dbgs() << "Virtual ");
167 }
168 LLVM_DEBUG(llvm::dbgs() << "Method name is " << method->getParent()->getNameAsString() << "::" << method->getNameAsString()
169 << "\n");
170 QualType qtype{method->getThisType()};
171 LLVM_DEBUG(qtype.getTypePtr()->dump());
172 LLVM_DEBUG(llvm::dbgs() << "\n");
173 if (method->getBody() != NULL) {
174 LLVM_DEBUG(llvm::dbgs() << "Body of method non-null\n");
175 //LLVM_DEBUG(method->getBody()->dump());
176 }
177 else LLVM_DEBUG(llvm::dbgs() << "Empty method body\n");
178
179 for (const auto &ometh : method->overridden_methods()) {
180 LLVM_DEBUG(llvm::dbgs() << " overridden method " << ometh->getParent()->getNameAsString() << "::" << ometh->getNameAsString() << "\n");
181 if (ometh->hasBody()) {
182 overridden_method_map[ometh] = method;
183 }
184 else LLVM_DEBUG(llvm::dbgs() << "Empty overridden method body\n");
185 }
186 }
187 }
188
189 LLVM_DEBUG(llvm::dbgs() <<"Overridden method map\n");
190 for (auto ov: overridden_method_map) {
191 LLVM_DEBUG(llvm::dbgs() << "Overridden method\n");
192 LLVM_DEBUG(ov.first->dump(llvm::dbgs()));
193 LLVM_DEBUG(llvm::dbgs() << "Overriding method\n");
194 LLVM_DEBUG(ov.second->dump(llvm::dbgs()));
195 }
196 LLVM_DEBUG(llvm::dbgs() <<"end Overridden method map\n");
197 LLVM_DEBUG( llvm::dbgs() << "End Methods in this module\n\n");
198
199 // look at constructor
200
201 // LLVM_DEBUG(llvm::dbgs() << "dumping module constructor stmt\n");
202
203 // LLVM_DEBUG(mod->getConstructorStmt()->dump(llvm::dbgs()));
204 //LLVM_DEBUG( llvm::dbgs() << "dumping module constructor decl body\n");
205 //LLVM_DEBUG(mod->getConstructorDecl()->getBody()->dump());
206 //LLVM_DEBUG( llvm::dbgs() << "end dumping module constructor decl body\n");
207 //LLVM_DEBUG(mod->getConstructorDecl()->dump(llvm::dbgs()));
208
209 LLVM_DEBUG(llvm::dbgs() << "submodule count is " << submodv.size() << "\n");
210
211 hdecl_name_map_t mod_vname_map("_scclang_global_");
212 xbodyp = new HDLBody(main_diag_engine, getContext(), mod_vname_map, allmethodecls, overridden_method_map);
213
215 module_vars.clear();
216 threadresetmap.clear();
217
218 // Ports
219 hNodep h_ports =
220 new hNode(hNode::hdlopsEnum::hPortsigvarlist); // list of ports, signals
221 h_module->child_list.push_back(h_ports);
222
223 // generate port, sig, var for module inheritance chain
224 ModuleInstance *mod_i = mod;
225 for (int i = 0; i <= basemods.size(); i++) {
226 SCport2hcode(mod_i->getIPorts(), hNode::hdlopsEnum::hPortin, h_ports, mod_vname_map);
227 SCport2hcode(mod_i->getInputStreamPorts(), hNode::hdlopsEnum::hPortin, h_ports, mod_vname_map);
228 SCport2hcode(mod_i->getOPorts(), hNode::hdlopsEnum::hPortout, h_ports, mod_vname_map);
229 SCport2hcode(mod_i->getOutputStreamPorts(), hNode::hdlopsEnum::hPortout,
230 h_ports, mod_vname_map);
231 SCport2hcode(mod_i->getIOPorts(), hNode::hdlopsEnum::hPortio, h_ports, mod_vname_map);
232
233 // Signals
234 SCsig2hcode(mod_i->getSignals(), hNode::hdlopsEnum::hSigdecl, h_ports, mod_vname_map);
235
236 SCport2hcode(mod_i->getOtherVars(), hNode::hdlopsEnum::hVardecl, h_ports, mod_vname_map);
237 if (i == basemods.size()) break;
238 mod_i = basemods[i];
239 }
240
241 // add the submodule declarations
242
243 for (const auto &smod : submodv) {
244 //std::vector<std::string> instnames;
245 if (smod->getInstanceInfo().isArrayType()) {
246 LLVM_DEBUG(llvm::dbgs() << "Array submodule " << smod->getInstanceInfo().getVarName() << "\n");
247 }
248 else {
249 LLVM_DEBUG(llvm::dbgs() << "Non-Array submodule " << smod->getInstanceInfo().getVarName() << "\n");
250 }
251
252 // Not doing below:
253 // we generate instance names based on the array indices so that the names match
254 // names used in the portbindings for each instance, which are generated in
255 // for loops (see HDLHNode.cpp code to unroll portbindings).
256
257 //GenerateInstanceNames(smod, instnames);
258 //bool frsttime = true;
259 //for (auto instname: instnames) {
260 //LLVM_DEBUG(llvm::dbgs() << "Instance " << instname << "\n");
261 //string instname = instnames[0];
262 LLVM_DEBUG(llvm::dbgs() << "Submod name is " << smod->getName() << "\n"); // fwd_lift
263
264 LLVM_DEBUG(llvm::dbgs() << "Instance Var name is " << smod->getInstanceInfo().getVarName() << "\n"); //u_xt
265 LLVM_DEBUG(llvm::dbgs() << "Instance name is " << smod->getInstanceInfo().getInstanceNames()[0] << "\n"); //u_xt_0
266 string instname = smod->getInstanceInfo().getVarName(); //smod->getInstanceInfo().getInstanceNames()[0];
267
268 hNodep h_smod =
269 new hNode(instname, hNode::hdlopsEnum::hModdecl);
270 h_ports->child_list.push_back(h_smod);
271 hNodep h_smodtypinfo = new hNode(hNode::hdlopsEnum::hTypeinfo);
272 //if (frsttime) { // only enter the first one into the map
273 mod_name_map.add_entry(smod, smod->getName(), h_smod);
274 h_smod->set(instname); // override name inserted by map service
275 //frsttime = false;
276 //}
277 hNodep h_smod_typep = new hNode( hNode::hdlopsEnum::hType);
278 if (smod->getInstanceInfo().isArrayType()) {
279 h_smod_typep->set("array##"+std::to_string(smod->getInstanceInfo().getInstanceNames().size()));
280 h_smod_typep->append(new hNode(mod_name_map.find_entry_newn(smod), hNode::hdlopsEnum::hType));
281 }
282 else {
283 h_smod_typep->set(mod_name_map.find_entry_newn(smod));
284 }
285 h_smodtypinfo->child_list.push_back(h_smod_typep);
286 h_smod->child_list.push_back(h_smodtypinfo);
287 }
288
289 // init block
290 mod_i = mod;
291 hNodep h_modinitblockhead = new hNode( hNode::hdlopsEnum::hNoop); // hold list of module constructors
292 hNodep h_constructor;
293 hNodep h_allsenslists = new hNode( hNode::hdlopsEnum::hNoop);
294 for (int i = 0; i <= basemods.size(); i++) {
295 if (mod_i->getConstructorDecl() ==NULL) continue; // null constructor
296 h_constructor = new hNode(mod_i->getInstanceInfo().getVarName(),// + (mod_i->getInstanceInfo().isArrayType()? "_0" :""),
297 hNode::hdlopsEnum::hModinitblock);
298 // SenseMapType sensmap = mod_i->getSensitivityMap();
299 // for (auto sensitem : sensmap) {
300 // sensitem->dump();
301 // }
302
303 xbodyp->Run(mod_i->getConstructorDecl()->getBody(), h_constructor,rmodinit);
304 LLVM_DEBUG(llvm::dbgs() << "HDL output for module constructor body\n");
305 LLVM_DEBUG(h_constructor->print(llvm::dbgs()));
306 HDLConstructorHcode hcxxbody;
307 hNodep modinithp = hcxxbody.ProcessCXXConstructorHcode(h_constructor);
308 if (modinithp->child_list.size() != 0) { // if there was an initblock
309 h_modinitblockhead->child_list.push_back(modinithp);
310 // need to add these nodes to h_senshead
311 std::vector<hNodep> slvec;
312 hcxxbody.GetSensLists(slvec);
313 h_allsenslists->child_list.insert(h_allsenslists->child_list.end(), slvec.begin(), slvec.end());
314 }
315
316 //h_constructor->print(HCodeOut);
317 if (i == basemods.size()) break;
318 mod_i = basemods[i];
319 }
320
321 //LLVM_DEBUG(llvm::dbgs() << "Module sensitivity lists follow\n");
322 //LLVM_DEBUG(h_allsenslists->print(llvm::dbgs()));
323 //LLVM_DEBUG(llvm::dbgs() << "Module sensitivity lists end\n");
324
325 // build map of thread name to reset var name for this module
326 //MakeResetMap(threadresetmap, h_allsenslists);
327
328 LLVM_DEBUG(llvm::dbgs() << "Module vname map size is " << mod_vname_map.size() << " \n");
329
330 // Processes
331 hNodep h_processes = new hNode(hNode::hdlopsEnum::hProcesses);
332 mod_i = mod;
333 for (int i = 0; i <= basemods.size(); i++) {
334 // send portsigvarlist (h_ports) to proc code gen so thread vars get promoted to module level
335 SCproc2hcode(mod_i->getProcessMap(), h_processes, h_ports, mod_vname_map, overridden_method_map, threadresetmap);
336 if (i == basemods.size()) break;
337 mod_i = basemods[i];
338 }
339 // add all the processes (including those in the inheritance chain) to the module
340 if (!h_processes->child_list.empty()) h_module->child_list.push_back(h_processes);
341
342 // add extra sig and var decls to shadow those referenced in threads
343 for (auto const &var: mod_vname_map) {
344 if (var.second.referenced) {
345 hNodep hvp = new hNode("_main_"+var.second.h_vardeclp->getname(), var.second.h_vardeclp->getopc());
346 hvp->child_list = var.second.h_vardeclp->child_list;
347 h_ports->append(hvp);
348 }
349 }
350
351
352 // now add init block
353 if (h_modinitblockhead->size()>0) {
354 h_module->append(h_modinitblockhead->child_list[0]);
355 //h_module->child_list.insert(h_module->child_list.end(), h_modinitblockhead->child_list.begin(), h_modinitblockhead->child_list.end());
356 hNodep hfirstblock = h_modinitblockhead->child_list[0];
357 for (int i = 1; i< h_modinitblockhead->size(); i++) { // in case of multiple modinit blocks due to inheritance
358 // join all their child_lists under the first mod_int
359 hfirstblock->child_list.insert(hfirstblock->child_list.end(),
360 h_modinitblockhead->child_list[i]->child_list.begin(),
361 h_modinitblockhead->child_list[i]->child_list.end());
362
363 }
364 }
365
366 // Functions
367 // Initially these are functions that were referenced in the module's sc_methods/threads
368 // Function calls within functions get added to all methodecls.
369
370 std::set<Decl *> generated_functions;
371 bool addfunc = false;
372 //while (allmethodecls.size() > 0) {
373 while (allmethodecls.size()>generated_functions.size()) {
374 LLVM_DEBUG(llvm::dbgs() << "Module Method/Function Map\n");
375
376 hfunc_name_map_t &modmethodecls = allmethodecls;
377 //modmethodecls =
378 // std::move(allmethodecls); // procedures/functions found in this module
379 LLVM_DEBUG(llvm::dbgs()
380 << "size of allmethodecls is " << allmethodecls.size() << "\n");
381 LLVM_DEBUG(allmethodecls.print(llvm::dbgs()));
382 LLVM_DEBUG(llvm::dbgs()
383 << "size of generated_functions is " << generated_functions.size() << "\n");
384 LLVM_DEBUG(llvm::dbgs()
385 << "size of modmethodecls is " << modmethodecls.size() << "\n");
386 //LLVM_DEBUG(modmethodecls.print(llvm::dbgs()));
387 LLVM_DEBUG(HDLt.print(llvm::dbgs()));
388 for (auto const &m : modmethodecls) {
389 //for (auto const &m : allmethodecls) {
390 LLVM_DEBUG(llvm::dbgs() << "Method --------\n"
391 << m.first << " " << m.second.newn << " generatedcount is " << generated_functions.count(m.first)<< "\n");
392 LLVM_DEBUG(m.first->dump(llvm::dbgs()));
393 LLVM_DEBUG(llvm::dbgs() << "---------\n");
394 if (generated_functions.count(m.first) > 0) continue; // already generated this one !!!!!
395 generated_functions.insert(m.first);
396 //clang::DiagnosticsEngine &diag_engine{getContext().getDiagnostics()};
397 if (m.first->hasBody()) { // && !m.first->hasTrivialBody()) {
398 //if (generated_functions.count(m.first) > 0) continue; // already generated this one !!!!!
399 //generated_functions.insert(m.first);
400 hNodep hfunc = new hNode(m.second.newn, hNode::hdlopsEnum::hFunction);
401 QualType qrettype = m.first->getReturnType(); // m.first->getDeclaredReturnType();
402 const clang::Type *rettype = qrettype.getTypePtr();
404 te->Enumerate(rettype);
405 HDLType HDLt2;
406 // what about returning an array type? this isn't handled
407 HDLt2.SCtype2hcode("", te->getTemplateArgTreePtr(), NULL,
408 hNode::hdlopsEnum::hFunctionRetType, hfunc);
409 CXXMethodDecl * thismethod = dyn_cast<CXXMethodDecl>(m.first);
410 bool isUserDefinedMethod = (thismethod != NULL) && (modmethodecls.methodobjtypemap.count(thismethod));//modmethodecls.methodobjtypemap.count(thismethod));
411 if (thismethod != NULL) {
412 LLVM_DEBUG(llvm::dbgs() << thismethod->getParent()->getQualifiedNameAsString() << " " << m.second.newn << " is a Method\n");
413 }
414 else LLVM_DEBUG(llvm::dbgs() << m.second.newn << " is a Function\n");
415 if ((m.first->getNumParams() > 0) || (thismethod != NULL)) {
416 hNodep hparams = new hNode(hNode::hdlopsEnum::hFunctionParams);
417 hNodep hparam_assign_list = new hNode(hNode::hdlopsEnum::hCStmt);
418 hfunc->child_list.push_back(hparams);
419
420 if (isUserDefinedMethod) { // user defined non scmodule method
421 hNodep hthisparam = new hNode("hthis", hNode::hdlopsEnum::hFunctionParamIO);
422 hNodep hthistype = new hNode(hNode::hdlopsEnum::hTypeinfo);
423 const clang::Type * tp = modmethodecls.methodobjtypemap[thismethod];// modmethodecls.methodobjtypemap[thismethod];
424 if (tp == NULL) {
425 LLVM_DEBUG(llvm::dbgs() <<"Couldn't find methodobjtypemap entry for " << thismethod << "\n");
426 }
427 else {
428 if (HDLt.usertype_info.userrectypes.count(tp)) {
429 LLVM_DEBUG(llvm::dbgs() << "Found methodobjtypemap entry for " << thismethod << " and userrectypes gives " << HDLt.usertype_info.userrectypes[tp] << "\n");
430 }
431 else {
432 LLVM_DEBUG(llvm::dbgs() << "Couldn't find userrectypes entry for " << tp << "\n");
433 LLVM_DEBUG(HDLt.print(llvm::dbgs()));
434 }
435 }
436 hthistype->append(new hNode(HDLt.usertype_info.userrectypes[tp],
437 hNode::hdlopsEnum::hType));
438 hthisparam->append(hthistype);
439 hparams->append(hthisparam);
440 }
441 for (int i = 0; i < m.first->getNumParams(); i++) {
442 ParmVarDecl *vardecl = m.first->getParamDecl(i);
443 QualType q = vardecl->getType();
444 const clang::Type *tp = q.getTypePtr();
445 LLVM_DEBUG(llvm::dbgs() << "ProcessParmVarDecl type name is "
446 << q.getAsString() << "\n");
448 te->Enumerate(tp);
449 HDLType HDLt1;
450 std::vector<llvm::APInt> array_sizes = sc_ast_matchers::utils::array_type::getConstantArraySizes(vardecl);
451 hNode::hdlopsEnum paramtype;
452 // special case if sc_min, max, abs, treat parameters as input
453 // unfortunately simulation library makes them I/O
454 //if (mutil.is_sc_macro(m.first)) paramtype = hNode::hdlopsEnum::hFunctionParamI;
455
456 // ============= CHECK ==============
457 //bool t1 = mutil.isSCByFunctionDecl(m.first);
458 bool t1 = mutil.checkNamespace(m.first);
459 bool t2 = mutil.isSCMacro(m.second.oldn);
460
461 if (t1 != t2) {
462 llvm::dbgs() << "@@@@ isSCMacro does not match. t1 = " << t1 << ", t2 = " << t2 << " " << m.second.oldn << "\n";
463 assert(0 && "isSCMacro does not match");
464 }
465 // ============= END CHECK ==============
466 //
467 if (mutil.isSCMacro(m.second.oldn)) {
468 paramtype = hNode::hdlopsEnum::hFunctionParamI;
469 }
470 else if ((vardecl->getType()->isReferenceType()) && !(vardecl->getType().getNonReferenceType().isConstQualified()))
471 paramtype = hNode::hdlopsEnum::hFunctionParamRef;
472 else { // handle actual parameter
473 // still messed up here for user defined struct: hFunctionParamI NONAME, hType fp_t_11_52_ NOLIST;
474 //hBinop = [
475 //hVarref _actual_scclang_global_3 NOLIST
476 //hVarref _actual NOLIST
477 paramtype = hNode::hdlopsEnum::hFunctionParamI;
478 // create an entry in mod_vname_map for this parameter's local variable
479 string objname = vardecl->getName().str()+"_actual";
480
481 HDLt1.SCtype2hcode(objname, te->getTemplateArgTreePtr(),
482 &array_sizes, hNode::hdlopsEnum::hVardecl, h_ports);
483 mod_vname_map.add_entry(vardecl, objname, h_ports->child_list.back());
484 hNodep hparam_assign = new hNode("=", hNode::hdlopsEnum::hBinop);
485 hNodep hv = new hNode(mod_vname_map.find_entry_newn(vardecl), hNode::hdlopsEnum::hVarref);
486 hparam_assign->append(hv);
487 hv = new hNode(vardecl->getName().str(), hNode::hdlopsEnum::hVarref);
488 //doesn't work when name isn't given hv = new hNode(objname, hNode::hdlopsEnum::hVarref); // dummy actual parameter for user defined types
489 hparam_assign->append(hv);
490 hparam_assign_list->append(hparam_assign);
491 }
492
493 HDLt1.SCtype2hcode(vardecl->getName().str(), te->getTemplateArgTreePtr(),
494 &array_sizes, paramtype, hparams);
495 }
496
497 if (hparam_assign_list->child_list.size()>0) { // there were some actual parameters
498 hNodep htmpf = new hNode( hNode::hdlopsEnum::hCStmt);
499 if (isUserDefinedMethod) {
500 xbodyp->Run(m.first->getBody(), htmpf, ruserdefclass, &HDLt); // suppress output of unqualified name
501 }
502 else {
503 xbodyp->Run(m.first->getBody(), htmpf,rnomode);
504 }
505
506 hNodep hfunccstmt = htmpf->child_list.back(); // htmpf is list of vardecls followed by function body in a cstmt
507 hfunccstmt->child_list.insert(hfunccstmt->child_list.begin(), hparam_assign_list->child_list.begin(), hparam_assign_list->child_list.end());
508
509 hfunc->child_list.insert(hfunc->child_list.end(), htmpf->child_list.begin(), htmpf->child_list.end());
510
511 }
512 else {
513 if (isUserDefinedMethod) {
514 xbodyp->Run(m.first->getBody(), hfunc, ruserdefclass, &HDLt); // suppress output of unqualified name
515 }
516 else {
517 xbodyp->Run(m.first->getBody(), hfunc,rnomode);
518 }
519 }
520 } // num of parameters > 0
521 else {
522 LLVM_DEBUG(llvm::dbgs() << " No parameters found for " << m.second.newn << "\n");
523 hNodep htmpf = new hNode( hNode::hdlopsEnum::hCStmt);
524 xbodyp->Run(m.first->getBody(), htmpf,rnomode);
525 hfunc->child_list.insert(hfunc->child_list.end(), htmpf->child_list.begin(), htmpf->child_list.end());
526 }
527 // If this function invoked other functions, add them to the list to be generated
528 allmethodecls.insertall(xbodyp->methodecls); // if a function called
529 h_processes->child_list.push_back(hfunc);
530 // LLVM_DEBUG(m.second->dump(llvm::dbgs()));
531 } // end non-null body
532 }
533 }
534
535 h_module->print(HCodeOut);
536 // now generate submodules
537 delete xbodyp; // release this hdlbody
538
539 for (const auto &smod : submodv) {
540
541 string modname = mod_name_map.find_entry_newn(smod);
542 LLVM_DEBUG(llvm::dbgs() << "generate submodule " << smod->getName()
543 << " renamed " << modname << "\n");
544 hNodep h_submod = new hNode(modname, hNode::hdlopsEnum::hModule);
545 SCmodule2hcode(smod, h_submod, HCodeOut);
546 // }
547 }
548 }
549
550 void HDLMain::GenerateInstanceNames(ModuleInstance *smod, std::vector<std::string> &instnames) {
551 string basevarname = smod->getInstanceInfo().getVarName();
552 std::vector<llvm::APInt> arraysizes = smod->getInstanceInfo().getArraySizes();
553 //instnames = smod->getInstanceInfo().getInstanceNames();
554 int ndim = smod->getInstanceInfo().getArrayDimension();
555
556 if (ndim==0) {
557 instnames.push_back(basevarname);
558 return;
559 }
560
561 // convert the annoying APInt datatype
562 int array_dim[ndim];
563 for (int i = 0; i<ndim; i++) {
564 array_dim[i] = arraysizes[i].getSExtValue();
565 }
566
567 // in order of likelihood
568 // only handle up to 3D (front end restriction)
569 if (ndim==1) {
570 for (int i = 0; i < array_dim[0]; i++) {
571 string varname = basevarname;
572 varname.append("_" + to_string(i));
573 instnames.push_back(varname);
574 }
575 return;
576 }
577
578 if (ndim == 2) {
579 for (int i = 0; i < array_dim[0]; i++)
580 for (int j = 0; j < array_dim[1]; j++) {
581 string varname = basevarname;
582 varname.append("_" + to_string(i)+"_" + to_string(j));
583 instnames.push_back(varname);
584 }
585 return;
586 }
587
588 for (int i = 0; i <= array_dim[0]; i++)
589 for (int j = 0; j < array_dim[1]; j++)
590 for (int k = 0; k < array_dim[2]; k++) {
591 string varname = basevarname;
592 varname.append("_" + to_string(1)+"_" + to_string(j-1)+"_" + to_string(k-1));
593 instnames.push_back(varname);
594 }
595 }
596
597 bool HDLMain::isValidMethod(CXXMethodDecl *method) {
598 if ((method->getNameAsString() != (method->getParent()->getNameAsString() )) && // constructor
599 (method->getNameAsString() != "~"+ (method->getParent()->getNameAsString() )) && // destructor
600 (method->getBody() !=NULL)) // get rid of methods with empty body
601 return true;
602 else return false;
603 }
604
606 hNodep &h_info, hdecl_name_map_t &mod_vname_map) {
607 //clang::DiagnosticsEngine &diag_engine{getContext().getDiagnostics()};
608
609 const unsigned cxx_record_id1 = main_diag_engine.getCustomDiagID(clang::DiagnosticsEngine::Remark, "Pointer type not synthesized, '%0' skipped.");
610 for (ModuleInstance::portMapType::iterator mit = pmap.begin(); mit != pmap.end();
611 mit++) {
612 string objname = get<0>(*mit);
613
614 LLVM_DEBUG(llvm::dbgs() << "object name is " << objname << " and h_op is "
615 << h_op << "\n");
616
617 PortDecl *pd = get<1>(*mit);
618 if (pd->isPointerType()) {
619 NamedDecl * decl = pd->getAsVarDecl();
620 if (decl == NULL) decl = pd->getAsFieldDecl();
621 if (decl !=NULL) {
622 clang::DiagnosticBuilder diag_builder{main_diag_engine.Report(decl->getLocation(), cxx_record_id1)};
623 diag_builder << decl->getName();
624 return;
625 }
626 return;
627 }
628
629 Tree<TemplateType> *template_argtp =
630 (pd->getTemplateType())->getTemplateArgTreePtr();
631
632 std::vector<llvm::APInt> array_sizes = pd->getArraySizes();
633
634 HDLt.SCtype2hcode(objname, template_argtp, &array_sizes, h_op,
635 h_info); // passing the sigvarlist
636
637 // if this is a duplicate name due to inheritance
638 // create a new name and add it to the module level vname map
639 // this map will be passed to all calls to HDLBody to merge into
640 // its vname_map
641
642 NamedDecl * portdecl = pd->getAsVarDecl();
643 if (!portdecl)
644 portdecl = pd->getAsFieldDecl();
645 if (module_vars.count(objname)) {
646 LLVM_DEBUG(llvm::dbgs() << "duplicate object " << objname << "\n");
647 if (portdecl) mod_vname_map.add_entry(portdecl, objname, h_info->child_list.back());
648 }
649 else {
650 module_vars.insert(objname);
651 // don't make new names for ports, will break logic in the modinit hcode processing
652 if ((h_op == hNode::hdlopsEnum::hVardecl) && (portdecl)) mod_vname_map.add_entry(portdecl, objname, h_info->child_list.back());
653 }
654
655 // check for initializer
656 if (h_op == hNode::hdlopsEnum::hVardecl) {
657 VarDecl *vard = pd->getAsVarDecl();
658 if (vard) {
659 LLVM_DEBUG(llvm::dbgs() << "var decl dump follows\n");
660 LLVM_DEBUG(vard->dump(llvm::dbgs()));
661 if (vard->hasInit()) {
662 APValue *apval = vard->getEvaluatedValue();
663 if (apval && apval->isInt()) {
664 hNodep h_lit = new hNode((systemc_clang::utils::apint::toString(apval->getInt())),
665 hNode::hdlopsEnum::hLiteral);
666 hNodep h_varinit = new hNode(hNode::hdlopsEnum::hVarInit);
667 h_varinit->child_list.push_back(h_lit);
668 (h_info->child_list.back())->child_list.push_back(h_varinit);
669 }
670 }
671 } else {
672 FieldDecl *fieldd = pd->getAsFieldDecl();
673 if (fieldd) {
674 LLVM_DEBUG(llvm::dbgs() << "field decl dump follows\n");
675 LLVM_DEBUG(fieldd->dump(llvm::dbgs()));
676 Expr* initializer = fieldd->getInClassInitializer();
677 if (initializer != NULL) {
678 LLVM_DEBUG(llvm::dbgs() << "field initializer dump follows\n");
679 LLVM_DEBUG(initializer->dump(llvm::dbgs(), getContext()));
680 hNodep h_init = new hNode(hNode::hdlopsEnum::hVarInit);
681 if (const CXXConstructExpr *ce = dyn_cast<CXXConstructExpr>(initializer->IgnoreUnlessSpelledInSource())) {
682 if (ce->isListInitialization()) {
683 for (const auto arg : ce->arguments()) {
684 const Expr *ex{arg->IgnoreUnlessSpelledInSource()};
685
686 if (auto il = dyn_cast<IntegerLiteral>(ex)) {
687 llvm::dbgs() << ">> IntegerLiteral value is " << il->getValue() << "\n";
688 h_init->append(new hNode(systemc_clang::utils::apint::toString(il->getValue()), hNode::hdlopsEnum::hLiteral));
689 }
690
691 if (auto booll = dyn_cast<CXXBoolLiteralExpr>(ex)) {
692 bool val = booll->getValue();
693 llvm::dbgs() << ">> CXXBoolLiteralExpr value is " << val << "\n";
694 h_init->append(new hNode(to_string(val), hNode::hdlopsEnum::hLiteral));
695 (h_info->child_list.back())->child_list.push_back(h_init);
696 }
697 }
698 }
699 }
700 else {
701 xbodyp->Run(initializer, h_init, rnomode);
702 (h_info->child_list.back())->child_list.push_back(h_init);
703 }
704 }
705 }
706 }
707 }
708 }
709 }
710
712 hNode::hdlopsEnum h_op, hNodep &h_info, hdecl_name_map_t &mod_vname_map) {
713
714 const unsigned cxx_record_id1 = main_diag_engine.getCustomDiagID(clang::DiagnosticsEngine::Remark, "Pointer type not synthesized, '%0' skipped.");
715 const unsigned cxx_record_id2 = main_diag_engine.getCustomDiagID(clang::DiagnosticsEngine::Remark, "Class Constructor at module level not supported.");
716 for (ModuleInstance::signalMapType::iterator mit = pmap.begin();
717 mit != pmap.end(); mit++) {
718 string objname = get<0>(*mit);
719
720 // Unfortunately due to portdecl and sigdecl having incompatible data structures,
721 // the same code has to be repeated in both.
722 LLVM_DEBUG(llvm::dbgs() << "object name is " << objname << "\n");
723
724 SignalDecl *pd = get<1>(*mit);
725
726 if (pd->isPointerType()) {
727 NamedDecl * decl = pd->getAsVarDecl();
728 if (decl == NULL) decl = pd->getAsFieldDecl();
729 if (decl !=NULL) {
730 clang::DiagnosticBuilder diag_builder{main_diag_engine.Report(decl->getLocation(), cxx_record_id1)};
731 diag_builder << decl->getName();
732 return;
733 }
734 return;
735 }
736
737 Tree<TemplateType> *template_argtp =
738 (pd->getTemplateTypes())->getTemplateArgTreePtr();
739
740 int arr_size = pd->getArraySizes().size() > 0
741 ? pd->getArraySizes()[0].getLimitedValue()
742 : 0;
743 std::vector<llvm::APInt> array_sizes = pd->getArraySizes();
744 HDLt.SCtype2hcode(objname, template_argtp, &array_sizes, h_op,
745 h_info); // passing the sigvarlist
746
747 // if this is a duplicate name due to inheritance
748 // create a new name and add it to the module level vname map
749 // this map will be passed to all calls to HDLBody to merge into
750 // its vname_map
751
752 NamedDecl * portdecl = pd->getAsVarDecl();
753 if (!portdecl)
754 portdecl = pd->getAsFieldDecl();
755 else {
756 if (((VarDecl *)portdecl)->hasInit()) {
757 clang::DiagnosticBuilder diag_builder{main_diag_engine.Report(portdecl->getLocation(), cxx_record_id2)};
758 diag_builder << portdecl->getName();
759 }
760 }
761 // ValueDecl * vd = (ValueDecl *)portdecl;
762 // LLVM_DEBUG(llvm::dbgs() << "Sig type is " << vd->getType().getAsString() << "\n");
763 if (module_vars.count(objname)) {
764 LLVM_DEBUG(llvm::dbgs() << "duplicate object " << objname << "\n");
765 if (portdecl)
766 mod_vname_map.add_entry(portdecl, objname, h_info->child_list.back());
767 //string newn = mod_newn.newname();
768 //objname+="_var"+newn;
769 }
770 else {
771 module_vars.insert(objname);
772 if (portdecl) mod_vname_map.add_entry(portdecl, objname, h_info->child_list.back());
773 }
774 }
775 }
776
778 hdecl_name_map_t &mod_vname_map, overridden_method_map_t &overridden_method_map, resetvar_map_t &threadresetmap) {
779 // typedef std::map<std::string, ProcessDecl *> processMapType;
780 // processMapType getProcessMap();
781 // ProcessDecl::getEntryFunction() returns EntryFunctionContainer*
782
784 //
785 //clang::DiagnosticsEngine &diag_engine{getContext().getDiagnostics()};
786
787 const unsigned cxx_record_id1 = main_diag_engine.getCustomDiagID(
788 clang::DiagnosticsEngine::Remark, "non-SC_METHOD/THREAD '%0' skipped.");
789
790 for (auto const &pm_entry : pm) {
791 ProcessDecl *pd{get<1>(pm_entry)};
792 EntryFunctionContainer *efc{pd->getEntryFunction()};
793 if (efc->getProcessType() == PROCESS_TYPE::METHOD) {
794 hNodep h_process = new hNode(efc->getName(), hNode::hdlopsEnum::hProcess);
795 LLVM_DEBUG(llvm::dbgs() << "process " << efc->getName() << "\n");
796 CXXMethodDecl *emd = efc->getEntryMethod();
797 if (emd->hasBody()) {
798 hNodep h_body = new hNode(efc->getName(), hNode::hdlopsEnum::hMethod);
799 LLVM_DEBUG(llvm::dbgs() << "HDLMain allmethodecls_ size is " << allmethodecls.size() << "\n");
800 //HDLBody xmethod(emd, h_body, main_diag_engine, getContext(), mod_vname_map);
801 xbodyp->Run(emd->getBody(), h_body, rmethod);
803 h_process->child_list.push_back(h_body);
804 h_top->child_list.push_back(h_process);
805 } else {
806 LLVM_DEBUG(llvm::dbgs() << "Entry Method is null\n");
807 }
808 } else {
809 if ((efc->getProcessType() == PROCESS_TYPE::THREAD) ||
810 (efc->getProcessType() == PROCESS_TYPE::CTHREAD)) {
811 hNodep h_thread = new hNode(efc->getName(), hNode::hdlopsEnum::hProcess);
812 LLVM_DEBUG(llvm::dbgs() << "thread " << efc->getName() << "\n");
813 CXXMethodDecl *emd = efc->getEntryMethod();
814 if (emd->hasBody()) {
815
816 // auto got = threadresetmap.find(efc->getName());
817 // // should be an error if there isn't a reset var for this thread
818 // clang::DiagnosticBuilder diag_builder{main_diag_engine.Report(
819 // (efc->getEntryMethod())->getLocation(),
820 // main_diag_engine.getCustomDiagID(
821 // clang::DiagnosticsEngine::Remark, "Reset not found in SC_[C]THREAD."))};
822 // diag_builder << "\n";
823 // auto h_resetvarinfo = (got == threadresetmap.end() ? NULL : got->second);
824
825 // params includes portsigvarlist so thread local vars get promoted to module level
826 // have to pass efc to get the reset info
827
828 HDLThread xthread(efc, h_thread, h_port, main_diag_engine, getContext(), mod_vname_map, allmethodecls, overridden_method_map, NULL);//, h_resetvarinfo );
830 //h_thread->child_list.push_back(h_body);
831 h_top->child_list.push_back(h_thread);
832 } else {
833 LLVM_DEBUG(llvm::dbgs() << "Entry Thread is null\n");
834 }
835 }
836 else {
837 clang::DiagnosticBuilder diag_builder{main_diag_engine.Report((efc->getEntryMethod())->getLocation(), cxx_record_id1)};
838 diag_builder << efc->getName();
839
840 LLVM_DEBUG(llvm::dbgs() << "process " << efc->getName()
841 << " not SC_METHOD, THREAD, or CTHREAD, skipping\n");
842 }
843 }
844 }
845 }
846
847 void HDLMain::MakeResetMap( resetvar_map_t &threadresetmap, hNodep h_allsenslists)
848 {
849 // top node is a noop, then child list has the sensitivity lists:
850 //hNoop NONAME [
851 //hSenslist mc_proc [
852 //hSensvar NONAME [
853 //hVarref s_fp##valid NOLIST
854 //hNoop always NOLIST
855 // ]
856 // hSensvar NONAME [
857 // hVarref s_fp##data NOLIST
858 // hNoop always NOLIST
859 // ]
860 // or
861 //hSenslist break_in_for_wait0 [
862 // hSensvar ASYNC [
863 // hVarref arst NOLIST
864 // hLiteral 0 NOLIST
865 // ]
866 // ]
867
868 if (h_allsenslists != NULL) {
869 for (hNodep h_onesenslist : h_allsenslists->child_list) {
870 string threadname = h_onesenslist->getname();
871 for ( hNodep h_sensvar : h_onesenslist->child_list) {
872 if (h_sensvar->getname() == "NONAME") continue; // non-reset var has null hSensvar name
873 threadresetmap[threadname] = h_sensvar; // only one reset per thread
874 break;
875 }
876 }
877 }
878 }
879
880 // this is obsolete. It has been supeseded by HDLHnode.cpp
881 // due to possibility of for-loops enclosing port bindings
883 //systemc_clang::ModuleInstance::portBindingMapType portbindingmap,
884 hNodep &h_pbs) {
886 for (auto const &pb : portbindingmap) {
887 PortBinding *binding{get<1>(pb)};
888 string port_name{binding->getCallerPortName()};
889 LLVM_DEBUG(llvm::dbgs() << "SC port binding found Caller port name " << port_name
890 << " caller instance name " << binding->getCallerInstanceName()
891 << " <==> callee port name " << binding->getCalleePortName() <<
892 " callee instance name "
893 << binding->getCalleeInstanceName() << "\n");
894 if (binding->getCallerArraySubscripts().size() >0)
895 {
896 LLVM_DEBUG(llvm::dbgs() << "Caller Subscript vector length is " <<
897 binding->getCallerArraySubscripts().size() << "\n");
898 for (auto subscriptex: binding->getCallerArraySubscripts()) {
899 LLVM_DEBUG(subscriptex->dump(llvm::dbgs(), getContext()));
900 }
901 }
902 if (binding->getCalleeArraySubscripts().size()>0) {
903 LLVM_DEBUG(llvm::dbgs() << "Callee Subscript vector length is " <<
904 binding->getCalleeArraySubscripts().size() << "\n");
905 for (auto subscriptex: binding->getCalleeArraySubscripts()) {
906 LLVM_DEBUG(subscriptex->dump(llvm::dbgs(), getContext()));
907 }
908 }
909
910 hNodep hpb = new hNode(binding->getCallerInstanceName(), hNode::hdlopsEnum::hPortbinding);
911 // caller module name
912 hNodep hpb_caller = new hNode(port_name, hNode::hdlopsEnum::hVarref);
913 if (binding->getCallerPortArraySubscripts().size() >0) {
914 hpb_caller->child_list.push_back(new hNode("INDEX", hNode::hdlopsEnum::hLiteral)); //placeholder
915 }
916 hpb->child_list.push_back(hpb_caller);
917 string mapped_name = binding->getCalleeInstanceName();
918
919 // hpb->child_list.push_back(new hNode(binding->getBoundToName(),
920 // hNode::hdlopsEnum::hVarref));
921 hNodep hpb_callee = new hNode(mapped_name, hNode::hdlopsEnum::hVarref);
922 if (binding->getCalleeArraySubscripts().size() >0) {
923 hpb_callee->child_list.push_back(new hNode("INDEX", hNode::hdlopsEnum::hLiteral)); //placeholder
924 }
925 hpb->child_list.push_back(hpb_callee);
926
927 h_pbs->child_list.push_back(hpb);
928 }
929 }
930
931}
std::unordered_map< const clang::Type *, string > userrectype_map_t
Definition HDLType.h:21
hNodep addtype(string typname, QualType qtyp, ASTContext &astcontext)
Definition HDLType.cpp:178
void print(llvm::raw_ostream &modelout=llvm::outs(), unsigned int indnt=2)
Definition HDLType.h:45
usertype_info_t usertype_info
Definition HDLType.h:44
void SCtype2hcode(string prefix, Tree< TemplateType > *template_argtp, std::vector< llvm::APInt > *arr_sizes, hNode::hdlopsEnum h_op, hNodep &h_info)
Definition HDLType.cpp:29
std::unordered_map< string, QualType > usertype_map_t
Definition HDLType.h:20
string getname()
Definition hNode.h:169
void set(hdlopsEnum h, string s="")
Definition hNode.h:148
std::vector< hNodep > child_list
Definition hNode.h:109
void append(hNodep hnew)
Definition hNode.h:157
int size()
Definition hNode.h:161
void print(llvm::raw_ostream &modelout=llvm::outs(), unsigned int indnt=2)
Definition hNode.h:188
void print(llvm::raw_ostream &modelout=llvm::outs(), unsigned int indnt=2)
Definition hNode.h:617
method_object_map_t methodobjtypemap
Definition hNode.h:612
void insertall(hfunc_name_map_t newmap)
Definition hNode.h:613
void add_entry(T declp, string old_name, hNodep hnp)
Definition hNode.h:539
string find_entry_newn(T declp, bool set_ref=false)
Definition hNode.h:552
bool checkNamespace(const FunctionDecl *fd)
Definition hNode.h:267
bool isSCMacro(const std::string &str_in)
Definition hNode.h:430
Tree< TemplateType > * getTemplateArgTreePtr()
void Enumerate(const clang::Type *type)
ModuleInstance * getRootModuleInstance() const
Definition Model.cpp:29
Forward declarations.
const portMapType & getOtherVars()
const clang::CXXRecordDecl * getModuleClassDecl()
std::vector< std::tuple< std::string, PortDecl * > > portMapType
const portMapType & getIOPorts()
const portMapType & getOPorts()
std::map< std::string, PortBinding * > portBindingMapType
const std::vector< ModuleInstance * > & getNestedModuleInstances() const
const portMapType & getOutputStreamPorts()
std::map< std::string, SignalDecl * > signalMapType
const portMapType & getInputStreamPorts()
const portBindingMapType & getPortBindings()
ModuleInstanceType getInstanceInfo()
std::string getInstanceName() const
void dump_base_instances(llvm::raw_ostream &os)
const clang::CXXConstructorDecl * getConstructorDecl() const
const std::vector< ModuleInstance * > & getBaseInstances()
std::map< std::string, ProcessDecl * > processMapType
const processMapType & getProcessMap()
const portMapType & getIPorts()
const signalMapType & getSignals() const
clang::VarDecl * getAsVarDecl() const
Definition PortDecl.cpp:83
clang::FieldDecl * getAsFieldDecl() const
Definition PortDecl.cpp:79
FindTemplateTypes * getTemplateType()
Definition PortDecl.cpp:87
std::vector< llvm::APInt > getArraySizes() const
Definition PortDecl.cpp:73
bool isPointerType() const
Definition PortDecl.cpp:56
FindTemplateTypes * getTemplateTypes()
Return the template types that were found.
clang::SourceManager & getSourceManager() const
clang::ASTContext & getContext() const
hfunc_name_map_t methodecls
Definition HDLBody.h:84
void Run(Stmt *stmt, hNodep &h_top, HDLBodyMode runmode, HDLType *HDLt_userclassesp=NULL)
Definition HDLBody.cpp:75
hNodep ProcessCXXConstructorHcode(hNodep xconstructor)
Definition HDLHnode.cpp:410
void GetSensLists(std::vector< hNodep > &hsens)
Definition HDLHnode.h:84
void SCport2hcode(ModuleInstance::portMapType pmap, hNode::hdlopsEnum h_op, hNodep &h_info, hdecl_name_map_t &mod_vname_map)
Definition HDLMain.cpp:605
clang::DiagnosticsEngine & main_diag_engine
Definition HDLMain.h:58
void SCportbindings2hcode(ModuleInstance *mod, hNodep &h_pb)
Definition HDLMain.cpp:882
hmodinst_name_map_t mod_name_map
Definition HDLMain.h:75
void SCmodule2hcode(ModuleInstance *mod, hNodep &h_module, llvm::raw_fd_ostream &SCout)
Definition HDLMain.cpp:145
void MakeResetMap(resetvar_map_t &threadresetmap, hNodep h_allsenslists)
Definition HDLMain.cpp:847
void SCsig2hcode(ModuleInstance::signalMapType pmap, hNode::hdlopsEnum h_op, hNodep &h_info, hdecl_name_map_t &mod_vname_map)
Definition HDLMain.cpp:711
void SCproc2hcode(ModuleInstance::processMapType pm, hNodep &h_top, hNodep &h_port, hdecl_name_map_t &mod_vname_map, overridden_method_map_t &overridden_method_map, resetvar_map_t &threadresetmap)
Definition HDLMain.cpp:777
HDLBody * xbodyp
Definition HDLMain.h:68
void GenerateInstanceNames(ModuleInstance *smod, std::vector< std::string > &instnames)
Definition HDLMain.cpp:550
resetvar_map_t threadresetmap
Definition HDLMain.h:64
std::unordered_set< string > module_vars
Definition HDLMain.h:62
bool isValidMethod(CXXMethodDecl *method)
Definition HDLMain.cpp:597
hfunc_name_map_t allmethodecls
Definition HDLMain.h:60
std::string hdl_file_out_
Command line options.
Definition HDLMain.h:78
hfunc_name_map_t methodecls
Definition HDLThread.h:32
Clang forward declarations.
Definition FindArgument.h:6
Definition hNode.h:24
std::unordered_map< string, hNodep > resetvar_map_t
Definition hNode.h:631
std::unordered_map< const CXXMethodDecl *, const CXXMethodDecl * > overridden_method_map_t
Definition hNode.h:628
ArraySizesType getConstantArraySizes(const clang::ValueDecl *fd)
std::string toString(const T &i)
Definition APIntUtils.h:14
std::string to_string(T *pointer)
Definition ProcessDecl.h:18
std::unique_ptr< clang::tooling::FrontendActionFactory > newFrontendActionFactory(const std::string &top_module)
Definition HDLMain.cpp:35
@ ruserdefclass
Definition HDLBody.h:32
userrectype_map_t userrectypes
Definition HDLType.h:28
usertype_map_t usertypes
Definition HDLType.h:25
unsigned int getArrayDimension() const
Return the array dimension, if the module instance is an array. 0 means a single instance k means kD ...
std::vector< llvm::APInt > getArraySizes()