systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
Matchers.h
Go to the documentation of this file.
1#ifndef _MATCHERS_H_
2#define _MATCHERS_H_
3
4#include <map>
5#include <vector>
6
7#include "InstanceMatcher.h"
9#include "ModuleInstance.h"
10#include "PortMatcher.h"
11
12#include "FindConstructor.h"
13#include "FindEntryFunctions.h"
14#include "FindEvents.h"
15#include "FindGlobalEvents.h"
16#include "FindNetlist.h"
17#include "FindNotify.h"
18#include "FindSimTime.h"
19#include "FindTLMInterfaces.h"
21#include "FindWait.h"
22
23#include "clang/ASTMatchers/ASTMatchers.h"
24//#include "matchers/ResetMatcher.h"
25
26using namespace systemc_clang;
27
29#undef DEBUG_TYPE
30#define DEBUG_TYPE "Matchers"
31
32namespace sc_ast_matchers {
33
34using namespace utils;
36//
38//
40class ModuleDeclarationMatcher : public MatchFinder::MatchCallback {
41 public:
42 typedef std::vector<InstanceMatcher::InstanceDeclType> InstanceListType;
43
45 typedef std::pair<clang::CXXRecordDecl *, ModuleInstance *> ModulePairType;
46 typedef std::multimap<clang::CXXRecordDecl *, ModuleInstance *> ModuleMapType;
47
48 private:
53
54 // Match nested instances
56
57 public:
59
61 void registerMatchers(MatchFinder &finder) {
62 // Add instance matcher
64 }
65
66 virtual void run(const MatchFinder::MatchResult &result) {}
67
69
70 void runPortMatcher(ASTContext &context, const clang::CXXRecordDecl *decl,
71 ModuleInstance *add_module) {
72 MatchFinder port_registry{};
73 PortMatcher port_matcher{};
74 port_matcher.registerMatchers(port_registry);
75 port_registry.match(*decl, context);
76 // decl->dump();
77 LLVM_DEBUG(llvm::dbgs() << "========== Port Matcher =============\n";
78 port_matcher.dump();
79 );
80
81 // All the ports for the CXXRecordDecl should be matched.
82 // We can populate the ModuleInstance with that information.
83 add_module->addPorts(port_matcher.getInputPorts(), "sc_in");
84 // Clock ports are also sc_in
85 add_module->addPorts(port_matcher.getClockPorts(), "sc_in");
86 add_module->addPorts(port_matcher.getOutputPorts(), "sc_out");
87 add_module->addPorts(port_matcher.getInOutPorts(), "sc_inout");
88 add_module->addPorts(port_matcher.getOtherVars(), "others");
89 add_module->addPorts(port_matcher.getSignals(), "sc_signal");
90 add_module->addPorts(port_matcher.getInputStreamPorts(), "sc_stream_in");
91 add_module->addPorts(port_matcher.getOutputStreamPorts(), "sc_stream_out");
92 add_module->addPorts(port_matcher.getSubmodules(), "submodules");
93 }
94
95 void runModuleDeclarationMatchers(ASTContext &context,
96 clang::CXXRecordDecl *cxx_decl,
97 ModuleInstance *add_module_decl) {
98 // setInstanceInfo done in pruneMatches
99 //
100 FindTemplateParameters tparms{cxx_decl};
101 add_module_decl->setTemplateParameters(tparms.getTemplateParameters());
102 add_module_decl->setTemplateArgs(tparms.getTemplateArgs());
103
105 //
106 //
107 LLVM_DEBUG(llvm::dbgs() << "4. Set the constructor.\n";);
108 std::vector<EntryFunctionContainer *> _entryFunctionContainerVector;
109 FindConstructor constructor{add_module_decl->getModuleClassDecl(),
110 llvm::dbgs()};
111 add_module_decl->addConstructor(&constructor);
112
115 //
116 //
117 // 5. Find entry functions within one sc_module.
118 LLVM_DEBUG(llvm::dbgs() << "5. Set the entry functions\n";);
119 FindEntryFunctions findEntries{add_module_decl->getModuleClassDecl(),
120 llvm::dbgs(), context};
121
123 findEntries.getEntryFunctions()};
124
125 LLVM_DEBUG(llvm::dbgs() << "6. Set the process\n";);
126 add_module_decl->addProcess(entryFunctions);
127
128 SensitivityMatcher sens_matcher{};
129 MatchFinder matchRegistry{};
130 sens_matcher.registerMatchers(matchRegistry);
131 if (constructor.getConstructorDecl()) {
132 matchRegistry.match(*constructor.getConstructorDecl(), context);
133 }
134
135 for (size_t i{0}; i < entryFunctions->size(); i++) {
136 EntryFunctionContainer *ef{(*entryFunctions)[i]};
137
140 sens_matcher.getSensitivityMap()};
141 ef->addSensitivityInfo(sensitivity_info);
142
143 if (ef->getEntryMethod() == nullptr) {
144 LLVM_DEBUG(llvm::dbgs() << "ERROR";);
145 continue;
146 }
147
148 FindWait findWaits{ef->getEntryMethod(), llvm::dbgs()};
149 ef->addWaits(findWaits);
150
151 FindNotify findNotify{ef->getEntryMethod(), llvm::dbgs()};
152 ef->addNotifys(findNotify);
153
154 _entryFunctionContainerVector.push_back(ef);
155 }
156 }
157
158 void matchInstancesInBaseClasses(ASTContext &context) {
159 auto instance_map{instance_matcher_.getInstanceMap()};
160 for (const auto &inst : instance_map) {
161 ModuleInstanceType instance{inst.second};
162 clang::CXXRecordDecl *decl{
163 dyn_cast<clang::CXXRecordDecl>(inst.second.getInstanceTypeDecl())};
164 clang::ValueDecl *vd{
165 dyn_cast<clang::ValueDecl>(inst.second.getInstanceDecl())};
166
167 auto base_decls{getAllBaseClasses(decl)};
168 for (const auto &base_decl : base_decls) {
169 LLVM_DEBUG(llvm::dbgs() << "=============================== BASES "
170 << decl->getNameAsString()
171 << " =======================\n";
172 llvm::dbgs() << "Run base instance matcher: "
173 << base_decl->getNameAsString() << " \n";);
174
175 InstanceMatcher base_instance_matcher;
176 MatchFinder base_instance_reg{};
177 base_instance_matcher.registerMatchers(base_instance_reg);
178 base_instance_matcher.setParentFieldDecl(vd);
179 base_instance_reg.match(*base_decl, context);
180 LLVM_DEBUG(llvm::dbgs() << "+ Dump base instance matcher\n";
181 base_instance_matcher.dump();
182 llvm::dbgs() << "+ End dump base instance matcher\n";);
183
185 instance_matcher_ = base_instance_matcher;
186 }
187 }
188 }
189
190 void processInstanceCXXDecls(ASTContext &context) {
191 // Must have found instances.
192 // 1. For every module found, check if there is an instance.
193 // 2. If there is an instance, then add it into the list.
194
195 LLVM_DEBUG(
196 llvm::dbgs() << "###### DUMP Instance Matches \n";
198 );
199
200 auto instance_map{instance_matcher_.getInstanceMap()};
201
208
210 instance_map = instance_matcher_.getInstanceMap();
211
213 for (const auto &inst : instance_map) {
214 clang::CXXRecordDecl *decl{
215 dyn_cast<clang::CXXRecordDecl>(inst.second.getInstanceTypeDecl())};
216 auto name{decl->getNameAsString()};
217 LLVM_DEBUG(llvm::dbgs() << "class: " << name << "\n";);
218 }
220
224 for (const auto &inst : instance_map) {
225 ModuleInstanceType instance{inst.second};
226
227 clang::CXXRecordDecl *decl{
228 dyn_cast<clang::CXXRecordDecl>(inst.second.getInstanceTypeDecl())};
229 auto name{decl->getNameAsString()};
230 LLVM_DEBUG(llvm::dbgs() << "############### ====> INST: " << inst.first
231 << ", name: " << name << ", instance_name: "
232 << inst.second.instance_name << "\n";);
233
234 auto add_module{new ModuleInstance(name, decl)};
235 add_module->setInstanceInfo(instance);
236
239 modules_.insert(std::pair<clang::CXXRecordDecl *, ModuleInstance *>(
240 decl, add_module));
241
242 LLVM_DEBUG(llvm::dbgs() << "[Running module declaration matchers]\n";);
243 runModuleDeclarationMatchers(context, decl, add_module);
244 LLVM_DEBUG(llvm::dbgs() << "[Running port matcher]\n";);
245 runPortMatcher(context, decl, add_module);
246
247 LLVM_DEBUG(llvm::dbgs() << "[Running Base class logic]\n";);
251 auto base_decls{getAllBaseClasses(decl)};
252 for (const auto &base_decl : base_decls) {
253 auto name{base_decl->getNameAsString()};
254 ModuleInstance *base_module_instance{
255 new ModuleInstance{name, base_decl}};
256 LLVM_DEBUG(base_decl->dump();
257 llvm::dbgs()
258 << "Base class: " << base_decl->getNameAsString() << "\n";);
259
261 context, const_cast<clang::CXXRecordDecl *>(base_decl),
262 base_module_instance);
263 runPortMatcher(context, base_decl, base_module_instance);
264 add_module->addBaseInstance(base_module_instance);
265 LLVM_DEBUG(llvm::dbgs() << "End base logic loop\n";);
266 }
267 }
268 }
269
270 void dump() {
271 llvm::outs() << "[DBG] Module instances: " << modules_.size() << "\n";
272 for (const auto &i : modules_) {
273 auto cxx_decl{i.first};
274 // TODO: really awkward
275 auto module_decl{i.second};
276 auto decl_name{module_decl->getName()};
277
278 LLVM_DEBUG(llvm::outs() << "CXXRecordDecl* " << cxx_decl
279 << ", module name: " << decl_name << "\n";);
280 }
281
282 // Print the instances.
284 }
285};
286
287}; // namespace sc_ast_matchers
288
289#endif
void setParentFieldDecl(clang::ValueDecl *parent_fd)
void registerMatchers(MatchFinder &finder)
const InstanceDeclarations & getInstanceMap()
Class ModuleDeclarationMatcher.
Definition Matchers.h:40
const ModuleMapType & getFoundModuleDeclarations() const
Definition Matchers.h:68
void registerMatchers(MatchFinder &finder)
Register the matchers.
Definition Matchers.h:61
void processInstanceCXXDecls(ASTContext &context)
Definition Matchers.h:190
const InstanceMatcher & getInstanceMatcher()
Definition Matchers.h:58
void runPortMatcher(ASTContext &context, const clang::CXXRecordDecl *decl, ModuleInstance *add_module)
Definition Matchers.h:70
void matchInstancesInBaseClasses(ASTContext &context)
Definition Matchers.h:158
virtual void run(const MatchFinder::MatchResult &result)
Definition Matchers.h:66
void runModuleDeclarationMatchers(ASTContext &context, clang::CXXRecordDecl *cxx_decl, ModuleInstance *add_module_decl)
Definition Matchers.h:95
std::pair< clang::CXXRecordDecl *, ModuleInstance * > ModulePairType
This will store all the modules as ModuleDecl.
Definition Matchers.h:45
std::multimap< clang::CXXRecordDecl *, ModuleInstance * > ModuleMapType
Definition Matchers.h:46
std::vector< InstanceMatcher::InstanceDeclType > InstanceListType
Definition Matchers.h:42
void registerMatchers(MatchFinder &finder)
void registerMatchers(MatchFinder &finder)
Defines the matcher, and setup the matcher.
std::map< std::string, std::vector< SensitivityTupleType > > SenseMapType
std::vector< EntryFunctionContainer * > entryFunctionVectorType
Typedefs.
Forward declarations.
void addConstructor(FindConstructor *)
const clang::CXXRecordDecl * getModuleClassDecl()
void setTemplateArgs(const vector< std::string > &)
void setTemplateParameters(const vector< std::string > &)
void addProcess(FindEntryFunctions::entryFunctionVectorType *)
void addPorts(const PortType &found_ports, const std::string &port_type)
std::vector< const clang::CXXRecordDecl * > getAllBaseClasses(const clang::CXXRecordDecl *decl)