systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
NetlistMatcher.h
Go to the documentation of this file.
1#ifndef _NETLIST_MATCHER_H_
2#define _NETLIST_MATCHER_H_
3
4#include "clang/ASTMatchers/ASTMatchers.h"
5
6#include "Matchers.h"
7#include "ArrayTypeUtils.h"
8
9#include "PortBinding.h"
10#include "SensitivityMatcher.h"
11
12using namespace clang::ast_matchers;
13
14#undef DEBUG_TYPE
15#define DEBUG_TYPE "NetlistMatcher"
16
17namespace sc_ast_matchers {
18
26class NetlistMatcher : public MatchFinder::MatchCallback {
27 private:
31 std::string top_;
32
34 auto instances{model_->getInstances()};
35 auto found_inst_it = std::find_if(
36 instances.begin(), instances.end(), [decl](const auto &instance) {
37 const clang::Decl *i{instance->getInstanceDecl()};
38 return (instance->getInstanceDecl() == decl);
39 });
40
41 if (found_inst_it != instances.end()) {
42 return *found_inst_it;
43 }
44 return nullptr;
45 }
46
47 public:
48 void registerMatchers(MatchFinder &finder, systemc_clang::Model *model,
49 ModuleDeclarationMatcher *module_matcher) {
50 model_ = model;
51 module_matcher_ = module_matcher;
52 instance_matcher_ = &(module_matcher_->getInstanceMatcher());
53
54 /* clang-format off */
55
56 auto match_sc_main_callexpr = functionDecl(
57 forEachDescendant(
58 cxxOperatorCallExpr(
59 hasDescendant(
60 declRefExpr(
61 hasDeclaration(varDecl().bind("bound_variable")), // Match the sig1
62 hasParent(implicitCastExpr()) // There must be (.)
63 ).bind("declrefexpr")
64 )
65 ,
66 hasDescendant(memberExpr(
67 forEach(declRefExpr().bind("declrefexpr_in_memberexpr"))
68 ).bind("memberexpr")
69 ) //hasDescendant
70 ).bind("callexpr")
71 )
72 ).bind("functiondecl");
73
76 const auto not_sc_sensitive = unless(hasType(cxxRecordDecl(isDerivedFrom("sc_core::sc_sensitive"))));
77 const auto not_sc_event_finder = unless(hasType(cxxRecordDecl(isDerivedFrom("sc_core::sc_event_finder"))));
78
79 const auto has_allowed_types =
80 anyOf(
81 hasType(cxxRecordDecl(isDerivedFrom(hasName("sc_core::sc_module")))),
82 hasType(cxxRecordDecl(isDerivedFrom(hasName("sc_core::sc_port")))),
83 hasType(cxxRecordDecl(isDerivedFrom(hasName("sc_core::sc_signal"))))
84 );
85
86 const auto caller_array_subscript =
87 arraySubscriptExpr(
88 has_allowed_types,
89 hasParent(
90 memberExpr().bind("caller_port_me_expr")
91 )
92 ).bind("caller_expr") ;
93
94
96 const auto match_callers =
97 anyOf(
98 hasDescendant(caller_array_subscript) //hasDescendant
99 ,
106 hasDescendant(
107 memberExpr(
108 hasDescendant(
109 memberExpr(has_allowed_types).bind("caller_expr")
110 ) //hasDescendant
111 ,
112 // The port could be an array as well.
113 hasAncestor(arraySubscriptExpr().bind("caller_array_port_expr"))
114 ).bind("caller_port_me_expr"))
115
116 ,
117 hasDescendant(
118 memberExpr(
119 hasDescendant(
120 memberExpr(has_allowed_types).bind("caller_expr")
121 ) //hasDescendant
122 //,
123 // The port could be an array as well.
124 //optionally(hasAncestor(arraySubscriptExpr().bind("caller_array_port_expr")))
125 ).bind("caller_port_me_expr"))
126 );
127
128 const auto callee_array_subscript =
129 arraySubscriptExpr(
130 has_allowed_types,
131 hasParent(
132 memberExpr().bind("callee_port_me_expr")
133 )
134 ).bind("callee_expr") ;
135
136
137
139 const auto match_callees =
140 anyOf(
141 ignoringImplicit(has(callee_array_subscript))
142 ,
143 ignoringImplicit(expr().bind("callee_expr") ) //hasDescendant
144 );
145
146
147 auto not_operator_less_than = unless(callee(cxxMethodDecl(hasName("operator<<"))));
148
149 auto test_match_ctor_decl =
150 namedDecl(
151 has(compoundStmt(
152 forEachDescendant(
153 cxxOperatorCallExpr(
154 not_operator_less_than,
157 match_callers
158 ,
159 hasArgument(1,
160 match_callees
161 )
162
163 ).bind("opcall")))
164 .bind("compoundstmt"))
165 ).bind("named_decl");
166
167 /* clang-format on */
168
169 // Add the two matchers.
170 // finder.addMatcher(match_sc_main_callexpr, this);
171 // finder.addMatcher(match_ctor_decl, this);
172 finder.addMatcher(test_match_ctor_decl, this);
173 }
174
175 // This is the callback function whenever there is a match.
176 //
177 // To save:
178 // 1. port_name
179 // 2. port_parameter
180 // 3. Instance variable name
181 // 4. Instance variable type
182 //
183 virtual void run(const MatchFinder::MatchResult &result) {
184 LLVM_DEBUG(
185 llvm::dbgs()
186 << "#### ============ NETLIST HAD A MATCH ============ ####\n";);
187
189
190 auto named_decl{const_cast<clang::NamedDecl *>(
191 result.Nodes.getNodeAs<clang::NamedDecl>("named_decl"))};
192 auto opcall{const_cast<clang::CXXOperatorCallExpr *>(
193 result.Nodes.getNodeAs<clang::CXXOperatorCallExpr>("opcall"))};
194
195 auto caller_expr{const_cast<clang::Expr *>(
196 result.Nodes.getNodeAs<clang::Expr>("caller_expr"))};
197 auto callee_expr{const_cast<clang::Expr *>(
198 result.Nodes.getNodeAs<clang::Expr>("callee_expr"))};
199
200 auto caller_array_expr{const_cast<clang::ArraySubscriptExpr *>(
201 result.Nodes.getNodeAs<clang::ArraySubscriptExpr>("caller_expr"))};
202 auto callee_array_expr{const_cast<clang::ArraySubscriptExpr *>(
203 result.Nodes.getNodeAs<clang::ArraySubscriptExpr>("callee_expr"))};
204
205 auto caller_array_port_expr{const_cast<clang::ArraySubscriptExpr *>(
206 result.Nodes.getNodeAs<clang::ArraySubscriptExpr>(
207 "caller_array_port_expr"))};
208
210 auto caller_port_me_expr{const_cast<clang::MemberExpr *>(
211 result.Nodes.getNodeAs<clang::MemberExpr>("caller_port_me_expr"))};
212 auto callee_port_me_expr{const_cast<clang::MemberExpr *>(
213 result.Nodes.getNodeAs<clang::MemberExpr>("callee_port_me_expr"))};
214
215 // if (caller_array_expr) {
216 // llvm::outs() << "=========== @@@@@@@@@@@@@@@@@@@@@ CALLER ARRAY EXPR\n";
217 // }
218 // if (caller_expr) {
219 // llvm::outs() << "=========== @@@@@@@@@@@@@@@@@@@@@ CALLER EXPR\n";
220 // caller_expr->dump();
221 // }
222 // if (caller_array_port_expr) {
223 // llvm::outs()
224 // << "=========== @@@@@@@@@@@@@@@@@@@@@ CALLER ARRAY PORT EXPR\n";
225 // caller_array_port_expr->dump();
226 // }
227 //
228 // if (callee_array_expr) {
229 // llvm::outs()
230 // << "=========== @@@@@@@@@@@@@@@@@@@@@ CALLEEEEE ARRAAY EXPR\n";
231 // callee_expr->dump();
232 //
233 // } else if (callee_expr) {
234 // llvm::outs() << "=========== @@@@@@@@@@@@@@@@@@@@@ CALLEEEE EXPR\n";
235 // callee_expr->dump();
236 // }
237
238 if (caller_expr && callee_expr) {
239 PortBinding *pb{new PortBinding(caller_expr, caller_array_port_expr,
240 caller_port_me_expr, callee_expr,
241 callee_port_me_expr)};
242
243 LLVM_DEBUG(
244 pb->dump();
245 llvm::dbgs() << "Try to add it into the module\n";
246 caller_expr->dump();
247 );
248
249 // Have to add the port binding into the appropriate module instance.
250 //
251 // Get the appropriate MemberExpr for either array or non-array.
252 const clang::MemberExpr *caller_me_expr{nullptr};
253 if (caller_array_expr) {
254 caller_me_expr = getArrayMemberExprName(caller_array_expr);
255 } else if (caller_expr) {
256 caller_me_expr = clang::dyn_cast<clang::MemberExpr>(caller_expr);
257 }
258
259 if (caller_me_expr) {
260 auto caller_instance_decl{caller_me_expr->getMemberDecl()};
261 auto caller_instance_type{caller_instance_decl->getType().getTypePtr()};
262 ModuleInstance *instance_module_decl{
263 findModuleDeclInstance(caller_instance_decl)};
264 if (instance_module_decl) {
265 LLVM_DEBUG(
266 llvm::dbgs() << "INSTANCE MODULE :"
267 << instance_module_decl->getInstanceName() << "\n";
268 llvm::dbgs() << " port name : " << pb->getCallerPortName() << "\n";
269 llvm::dbgs() << " PARENT@@@@ : "
270 << instance_module_decl->getInstanceInfo()
271 .getParentDecl()
272 ->getName()
273 << "\n";
274 );
275 // Get the parent ModuleInstance and insert the port binding into that one.
276
277 ModuleInstance *parent_decl{findModuleDeclInstance(
278 instance_module_decl->getInstanceInfo().getParentDecl())};
279 LLVM_DEBUG(llvm::dbgs() << " PARENT@@@@ INST NAME: "
280 << parent_decl->getInstanceName() << "\n";
281 );
282
285 std::string binding_name{pb->getCallerInstanceName() +
286 pb->getCallerPortName()};
287 parent_decl->addPortBinding(binding_name, pb);
288 pb->setInstanceConstructorName(instance_module_decl->getInstanceName());
289 }
290 }
291 }
292 }
293
294 void dump() {
295 // Dump out all the module instances.
296 //
297 auto instances{model_->getInstances()};
298
299 for (auto const &inst : instances) {
300 auto port_bindings{inst->getPortBindings()};
301
302 for (auto const &p : port_bindings) {
303 p.second->dump();
304 }
305 }
306 }
307};
308}; // namespace sc_ast_matchers
309
310#endif
Class ModuleDeclarationMatcher.
Definition Matchers.h:40
const InstanceMatcher & getInstanceMatcher()
Definition Matchers.h:58
void registerMatchers(MatchFinder &finder, systemc_clang::Model *model, ModuleDeclarationMatcher *module_matcher)
ModuleInstance * findModuleDeclInstance(clang::Decl *decl)
ModuleDeclarationMatcher * module_matcher_
const InstanceMatcher * instance_matcher_
virtual void run(const MatchFinder::MatchResult &result)
std::vector< ModuleInstance * > & getInstances()
Definition Model.cpp:133
Forward declarations.
void addPortBinding(const std::string &port_name, PortBinding *pb)
const clang::MemberExpr * getArrayMemberExprName(const clang::Expr *expr)