systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
HDLType.cpp
Go to the documentation of this file.
1#include "HDLType.h"
3#include "SystemCClang.h"
5#include "Tree.h"
6#include "clang/AST/DeclCXX.h"
7#include "llvm/ADT/StringRef.h"
8#include "llvm/Support/raw_ostream.h"
9#include "llvm/Support/Debug.h"
10#include <ctype.h>
11#include <string>
12#include <tuple>
13#include <unordered_set>
14#include <vector>
15
16#include <iostream>
17#include <assert.h>
18
19#undef DEBUG_TYPE
20#define DEBUG_TYPE "HDL"
21
28
29void HDLType::SCtype2hcode(string prefix, Tree<TemplateType> *template_argtp,
30 std::vector<llvm::APInt> *arr_sizes,
31 hNode::hdlopsEnum h_op, hNodep &h_info) {
32
33 LLVM_DEBUG(llvm::dbgs() << "prefix "<< prefix << " HDLtype dump of templatetree args follows\n");
34 LLVM_DEBUG(template_argtp->dump(llvm::dbgs()) ; );
35 LLVM_DEBUG(llvm::dbgs() << "as string: " << template_argtp->dft() << "\n");
36
37 if (!(template_argtp && (template_argtp->getRoot()))) {
38 LLVM_DEBUG(llvm::dbgs() << "HDLtype no root prefix is " << prefix << " "
39 << template_argtp << "\n");
40
41 return;
42 }
43 hNodep hmainp = new hNode(prefix, h_op); // opPort|Sig|Var prefix
44 h_info->child_list.push_back(hmainp);
45 string tmps;
46 if (auto etype = dyn_cast<EnumType>(((template_argtp->getRoot())->getDataPtr())->getTypePtr()) ) {
47 tmps = "int";
48 }
49 else tmps = ((template_argtp->getRoot())->getDataPtr())->getTypeName();
50 if ((((template_argtp->getRoot())->getDataPtr())->getTypePtr())->isBuiltinType())
51 tutil.make_ident(tmps);
52 hNodep h_typeinfo = new hNode(hNode::hdlopsEnum::hTypeinfo);
53 hmainp->child_list.push_back(h_typeinfo);
54
55 hNodep h_typ = new hNode(tmps, hNode::hdlopsEnum::hType);
56 if ((arr_sizes) && (arr_sizes->size() > 0)) {
57 string arr_string = "array";
58 int arr_size = 0;
59 for (int i = 0; i < arr_sizes->size(); i++) {
60 arr_size = arr_sizes->at(i).getLimitedValue();
61 arr_string += "##" + to_string(arr_size);
62 }
63 hNodep h_arr = new hNode(arr_string, hNode::hdlopsEnum::hType);
64 h_arr->child_list.push_back(h_typ);
65 h_typeinfo->child_list.push_back(h_arr);
66 } else {
67 h_typeinfo->child_list.push_back(h_typ);
68 }
69
70 if ((((template_argtp->getRoot())->getDataPtr())->getTypePtr())->isBuiltinType()) return;
71 auto const vectreeptr{template_argtp->getChildren(template_argtp->getRoot())};
72 if ((vectreeptr.size() == 0) && ((template_argtp->getRoot())->getDataPtr())->getTypePtr()->isStructureType())
73 {
74 LLVM_DEBUG(llvm::dbgs() << "root node has no children, is structure type, type dump follows\n");
75 LLVM_DEBUG(((template_argtp->getRoot())->getDataPtr())->getTypePtr()->dump() ; );
76 generatetype(template_argtp->getRoot(), template_argtp, h_typ, false); // skip initial hType, already generated
77 return;
78 }
79
80 if (checkusertype(template_argtp->getRoot(), template_argtp, tmps)) {
81 h_typ->set(tmps);
82 return; // we are not pushing into the template tree parameters for user defined types since template specialization record is saved
83 }
84
85 // template arguments seem to be stored in reverse order
86 for (int i = vectreeptr.size() - 1; i >= 0; i--) {
87 // for (auto const &node : vectreeptr) {
88 // generatetype(node, template_argtp, h_typ);
89 generatetype(vectreeptr[i], template_argtp, h_typ);
90 }
91 return;
92}
93
97 hNodep &h_info, bool generate_initial_htype) {
98
99
100 string tmps = (node->getDataPtr())->getTypeName();
101 if (((node->getDataPtr())->getTypePtr())->isBuiltinType())
102 tutil.make_ident(tmps);
103 // LLVM_DEBUG(llvm::dbgs() << "generatetype node name is " << tmps << " type
104 // follows\n"); (node->getDataPtr())->getTypePtr()->dump(llvm::dbgs());
105
106 LLVM_DEBUG(llvm::dbgs() << "generatetype node name is " << tmps << " as string is " << node->toString() << "\n");
107 hNodep nodetyp;
108 if (generate_initial_htype) {
109 nodetyp =
110 new hNode(tmps, tutil.isposint(tmps) ? hNode::hdlopsEnum::hLiteral
111 : hNode::hdlopsEnum::hType);
112 h_info->child_list.push_back(nodetyp);
113 }
114 else nodetyp = h_info; // the type node was already generated
115 if (((node->getDataPtr())->getTypePtr())->isBuiltinType())
116 return;
117
118 if (checkusertype(node, treehead, tmps)) {
119 nodetyp->set(tmps);
120 return; // we are not pushing into the template tree parameters for user defined types since template specialization record is saved
121 }
122 auto const vectreeptr{treehead->getChildren(node)};
123 // template arguments seem to be stored in reverse order
124 for (int i = vectreeptr.size() - 1; i >= 0; i--) {
125 // for (auto const &chnode : vectreeptr) {
126 // generatetype(chnode, treehead, nodetyp);
127 generatetype(vectreeptr[i], treehead, nodetyp);
128 }
129}
130
132 systemc_clang::Tree<systemc_clang::TemplateType> *const &treehead, string &tmps)
133{
134 bool retval = false;
135 const Type *typ = node->getDataPtr()->getTypePtr();
136 // ========================== CHECK HDLType =====================
137 /*
138 // FIXME: Cleanup
139 bool t1 = tutil.isSCType(tmps) || tutil.isSCBuiltinType(tmps);
140 bool t2 = tutil.isSCByType(typ);
141
142 if (t1 != t2) {
143 llvm::dbgs() << "### CHECK1: old " << t1 << " != new " << t2 << "\n";
144 assert(0); //llvm::dbgs() << t1/0;
145 //std::cin.get();
146 }
147 */
148 // ========================== END CHECK =====================
149 //
150 //if (!(tutil.isSCByType(typ) ||
151 if (!(tutil.isSCType(tmps) || tutil.isSCBuiltinType(tmps) ||
152 tutil.isposint(tmps) || tutil.isTypename(tmps))) {
153 string tmps_full = treehead->dft();
154 size_t type_ix = tmps_full.find(tmps);
155 if (type_ix != string::npos) { // found the name in the template args
156 tmps = tmps_full.substr(type_ix);
157 tutil.make_ident(tmps);
158 retval = true;
159 }
160 LLVM_DEBUG(llvm::dbgs() << "user defined type full " << tmps+ " " + tmps_full << "\n"); // here build specialized type
161 const RecordType *tstp =
162 dyn_cast<RecordType>((node->getDataPtr())->getTypePtr());
163 if (tstp) {
164 LLVM_DEBUG(llvm::dbgs() << "generatetype found record type and type pointer from RecordType is " << tstp << "\n");
165 // RecordDecl * tstdp = (tstp->getDecl())->getDefinition();
166
168 ((tstp->getDecl())->getTypeForDecl())->getCanonicalTypeInternal();
169 usertype_info.userrectypes[tstp] = tmps; // reverse map from RecType * to generated name
170 }
171 else usertype_info.usertypes[tmps] =
172 ((node->getDataPtr())->getTypePtr())->getCanonicalTypeInternal();
173 }
174 return retval;
175
176}
177
178hNodep HDLType::addtype(string typname, QualType qtyp, ASTContext &astcontext) {
179 hNodep h_typdef = new hNode(typname, hNode::hdlopsEnum::hTypedef);
180 LLVM_DEBUG(llvm::dbgs() << "addtype entered with type name " << typname
181 << "\n");
182 const Type *typ = qtyp.getTypePtr();
183 LLVM_DEBUG( typ->dump(llvm::dbgs(), astcontext ); );
184 if (typ->isBuiltinType()) {
185 string tmps = qtyp.getAsString();
186 tutil.make_ident(tmps);
187 hNodep hprim = new hNode(tmps, hNode::hdlopsEnum::hType);
188 LLVM_DEBUG(llvm::dbgs() << "addtype found prim type " << tmps << "\n");
189 h_typdef->child_list.push_back(hprim);
190 return h_typdef;
191 }
192
193 if (const RecordType *rectype = dyn_cast<RecordType>(typ)) {
194 LLVM_DEBUG(llvm::dbgs()
195 << "addtype record type found, name is " << typname << " rectype ptr is " << rectype << "\n");
196 if (isa<ClassTemplateSpecializationDecl>(rectype->getDecl())) {
197 LLVM_DEBUG(llvm::dbgs()
198 << "addtype isa template specialzation decl found, name is "
199 << typname << "\n");
200 ClassTemplateSpecializationDecl *ctsd =
201 dyn_cast<ClassTemplateSpecializationDecl>(rectype->getDecl());
202 ClassTemplateDecl *ctd = ctsd->getSpecializedTemplate();
203 LLVM_DEBUG(ctd->dump(llvm::dbgs()));
204 LLVM_DEBUG(llvm::dbgs() << "####### ============================== "
205 "MATCHER ========================= ##### \n");
206 TemplateParametersMatcher template_matcher{};
207 MatchFinder matchRegistry{};
208 template_matcher.registerMatchers(matchRegistry);
209 matchRegistry.match(*ctsd, astcontext); // ctd for user defined type, ctsd for actual
210 LLVM_DEBUG(llvm::dbgs() << "####### ============================== END "
211 "MATCHER ========================= ##### \n");
212
213 TemplateParameterList *tpl = ctd->getTemplateParameters();
214 LLVM_DEBUG(llvm::dbgs() << "addtype here are template parameters\n");
215 for (auto param : *tpl) {
216 LLVM_DEBUG(llvm::dbgs() << "addtype template param name is "
217 << param->getName() << "\n");
218 param->dump(llvm::dbgs());
219 LLVM_DEBUG(llvm::dbgs() << "end dump of param\n");
220 //h_typdef->child_list.push_back(
221 // new hNode(param->getName().str(), hNode::hdlopsEnum::hTypeTemplateParam));
222 }
223
224 std::vector<const FieldDecl *> fields;
225 template_matcher.getArgFields(fields); // Parm for formal, use getArgFields for actual
226 if (fields.size() > 0) {
227 for (const FieldDecl *fld : fields) {
228 addfieldtype(fld, h_typdef);
229 }
230 }
231 } else if (!rectype->getDecl()->field_empty()) {
232 for (auto const &fld : rectype->getDecl()->fields()) {
233 addfieldtype(fld, h_typdef);
234 }
235 } else { // record type but no fields
236 // get the type name
237 LLVM_DEBUG(llvm::dbgs() << "Found record with no fields, name is "
238 << (rectype->getDecl())->getName() << "\n");
239 h_typdef->child_list.push_back(
240 new hNode(rectype->getDecl()->getName().str(), hNode::hdlopsEnum::hType));
241 }
242 }
243
244 return h_typdef;
245}
246
247void HDLType::addfieldtype(const FieldDecl *fld, hNodep &h_typdef) {
248 LLVM_DEBUG(llvm::dbgs() << "field of record type \n");
249 LLVM_DEBUG(fld->dump(llvm::dbgs()));
250 LLVM_DEBUG(llvm::dbgs() << "field: found name " << fld->getName() << "\n");
251 // Try to get the template type of these fields.
252 const Type *field_type{fld->getType().getTypePtr()};
253 FindTemplateTypes find_tt{};
254 find_tt.Enumerate(field_type);
255
256 // Get the tree.
257 auto template_args{find_tt.getTemplateArgTreePtr()};
258 hNodep hfld =
259 new hNode(fld->getNameAsString(), hNode::hdlopsEnum::hTypeField);
260 h_typdef->child_list.push_back(hfld);
261 LLVM_DEBUG(llvm::dbgs() << "calling generatetype with template args of field\n");
262 if (template_args->getRoot())
263 generatetype(template_args->getRoot(), template_args, hfld);
264 else
265 LLVM_DEBUG(llvm::dbgs() << "FindTemplateTypes returned null root\n");
266}
hNodep addtype(string typname, QualType qtyp, ASTContext &astcontext)
Definition HDLType.cpp:178
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
void addfieldtype(const FieldDecl *fld, hNodep &h_typdef)
Definition HDLType.cpp:247
util tutil
Definition HDLType.h:62
void generatetype(systemc_clang::TreeNode< systemc_clang::TemplateType > *const &node, systemc_clang::Tree< systemc_clang::TemplateType > *const &treehead, hNodep &h_info, bool generate_initial_htype=true)
Definition HDLType.cpp:94
bool checkusertype(systemc_clang::TreeNode< systemc_clang::TemplateType > *const &node, systemc_clang::Tree< systemc_clang::TemplateType > *const &treehead, string &tmps)
Definition HDLType.cpp:131
void registerMatchers(MatchFinder &finder)
void set(hdlopsEnum h, string s="")
Definition hNode.h:148
std::vector< hNodep > child_list
Definition hNode.h:109
bool isTypename(const string &tstring)
Definition hNode.h:423
bool isSCBuiltinType(const string &tstring, const Type *typ=NULL)
Definition hNode.h:389
bool isSCType(const string &tstring, const clang::Type *typ=NULL)
Definition hNode.h:438
static bool isposint(const std::string &str)
Definition hNode.h:473
static void make_ident(string &nm)
Definition hNode.h:254
void Enumerate(const clang::Type *type)
class TreeNode<T>
Definition Tree.h:18
std::string toString() const
Definition Tree.h:40
const T * getDataPtr()
Definition Tree.h:39
void dump(llvm::raw_ostream &outstream=llvm::outs())
Definition Tree.h:105
const TreeNodePtr getRoot() const
Definition Tree.h:121
const VectorTreePtr & getChildren(TreeNodePtr node)
Definition Tree.h:139
std::string dft(TreeNodePtr root=nullptr)
Definition Tree.h:205
#define etype(x)
Definition hNode.h:100
std::string to_string(T *pointer)
Definition ProcessDecl.h:18
userrectype_map_t userrectypes
Definition HDLType.h:28
usertype_map_t usertypes
Definition HDLType.h:25