systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
CXXRecordDeclUtils.cpp
Go to the documentation of this file.
2#include "ArrayTypeUtils.h"
3
4#include "clang/AST/DeclCXX.h"
5#include "clang/AST/ExprCXX.h"
6#include "llvm/Support/Debug.h"
7#include "llvm/ADT/StringSet.h"
8
9#include <queue>
10#include <iostream>
11
12namespace sc_ast_matchers {
13namespace utils {
14 using namespace clang;
15
16bool isCXXMemberCallExprSystemCCall(const clang::CallExpr *ce,
17 const std::vector<llvm::StringRef> &names) {
18 if (!ce) {
19 return false;
20 }
21 if (auto mce = dyn_cast<CXXMemberCallExpr>(ce)) {
22 const Type* obj_ptr{ mce->getObjectType().getTypePtr()};
23 return isCXXMemberCallExprSystemCCall(obj_ptr, names);
24 }
25 if (auto oce = dyn_cast<CXXOperatorCallExpr>(ce)) {
26 const Decl* decl{ oce->getCalleeDecl()};
27 if (auto cxxdecl = dyn_cast<CXXRecordDecl>(decl)) {
28 return isCXXMemberCallExprSystemCCall(oce->getType().getTypePtr(), names);
29 }
30 }
31
32 return false;
33}
34
35bool isCXXMemberCallExprSystemCCall(const clang::Type *type,
36 const std::vector<llvm::StringRef> &names) {
37 if (!type) {
38 return false;
39 }
40
42 if (type->isBuiltinType()) {
43 return false;
44 }
45
47 if (type->isClassType()) {
48 if (const clang::CXXRecordDecl *rdecl = type->getAsCXXRecordDecl()) {
49 if (rdecl->hasDefinition()) {
50 // rdecl->dump();
51 auto base_names{getAllBaseClassNames(rdecl)};
52
53 for (const auto &decl : base_names) {
54 auto decl_name{decl->getNameAsString()};
55 for (auto &n : names) {
56 if (decl_name == n) {
57// llvm::dbgs() << "@@@ Typep => RecordType\n";
58 return true;
59 }
60 }
61 }
62 }
63 }
64 }
65
66 return false;
67}
68//
69// bool isCXXMemberCallExprSystemCCall(const clang::CXXMemberCallExpr *mce,
70 // const std::vector<llvm::StringRef> &names) {
71 // if (!mce) {
72 // return false;
73 // }
74//
75 // const Type* obj_ptr{ mce->getObjectType().getTypePtr()};
76 // llvm::dbgs() << "@@@@ obj_ptr\n";
77 // obj_ptr->dump();
78//
79 // return isCXXMemberCallExprSystemCCall(obj_ptr, names);
80// }
81//
82bool isCXXMemberCallExprSystemCCall(const clang::CXXMemberCallExpr *mce) {
83 if (!mce) {
84 return false;
85 }
86
87 if (auto mdecl = mce->getMethodDecl()) {
88 if (auto rdecl = mdecl->getParent()) {
89 auto base_names{getAllBaseClassNames(rdecl)};
90
91 for (const auto &decl : base_names) {
92 auto name{decl->getNameAsString()};
93 if (name == "sc_object" || (name == "sc_simcontext")) {
94 return true;
95 }
96 }
97 }
98 }
99
100 return false;
101}
102
103using namespace utils::array_type;
104
105std::vector<const clang::CXXRecordDecl *> getAllBaseClassNames(
106 const clang::CXXRecordDecl *decl) {
109
110 std::queue<const clang::CXXRecordDecl *> decl_queue;
111 std::vector<const clang::CXXRecordDecl *> bases;
112 llvm::StringSet<> bases_set;
113
114 // decl_queue.push(decl);
115 const clang::CXXRecordDecl *top_decl{decl};
116
117 while (top_decl) {
118 auto name{top_decl->getNameAsString()};
119
120 // llvm::dbgs() << "Processing base named: " << name << "\n";
121
122 bases.push_back(top_decl);
123 bases_set.insert(top_decl->getName());
125 for (auto &base : top_decl->bases()) {
126 const clang::CXXRecordDecl *base_decl{
127 base.getType().getTypePtr()->getAsCXXRecordDecl()};
128
129 decl_queue.push(base_decl);
130 }
131
132 if (!decl_queue.empty()) {
133 top_decl = decl_queue.front();
134 decl_queue.pop();
135 } else {
136 top_decl = nullptr;
137 }
138 }
139
141 LLVM_DEBUG(llvm::dbgs() << "Bases collected: ";);
142 for (auto const &base : bases) {
143 LLVM_DEBUG(llvm::dbgs() << base->getNameAsString() << " ";);
144 }
145 LLVM_DEBUG(llvm::dbgs() << "\n";);
146
147 return bases;
148}
149
150std::vector<const clang::CXXRecordDecl *> getAllBaseClasses(
151 const clang::CXXRecordDecl *decl) {
154
155 std::queue<const clang::CXXRecordDecl *> decl_queue;
156 std::vector<const clang::CXXRecordDecl *> bases;
157
158 // decl_queue.push(decl);
159 const clang::CXXRecordDecl *top_decl{decl};
160
161 while (top_decl) {
162 auto name{top_decl->getNameAsString()};
163
164 LLVM_DEBUG(llvm::dbgs() << "Processing base named: " << name << "\n";);
165
167 if ((top_decl != decl) && (name != "sc_object") &&
168 (name != "sc_process_host") && (name != "sc_module")) {
169 LLVM_DEBUG(llvm::dbgs() << "+ Insert into bases\n";);
170 bases.push_back(top_decl);
171 }
172
174 for (auto &base : top_decl->bases()) {
175 const clang::CXXRecordDecl *base_decl{
176 base.getType().getTypePtr()->getAsCXXRecordDecl()};
177
178 decl_queue.push(base_decl);
179 }
180
181 if (!decl_queue.empty()) {
182 top_decl = decl_queue.front();
183 decl_queue.pop();
184 } else {
185 top_decl = nullptr;
186 }
187 }
188
190 LLVM_DEBUG(llvm::dbgs() << "Bases collected: ";);
191 for (auto const &base : bases) {
192 LLVM_DEBUG(llvm::dbgs() << base->getNameAsString() << " ";);
193 }
194 LLVM_DEBUG(llvm::dbgs() << "\n";);
195
196 return bases;
197}
198
199std::vector<ModuleInitializerTupleType> getModuleInitializerNames(
200 const clang::CXXCtorInitializer *init) {
201 // const clang::CXXConstructorDecl *ctor_decl) {
202
203 std::vector<ModuleInitializerTupleType> module_info;
204
206 // for (auto const &init : ctor_decl->inits()) {
207
209 clang::Expr *str_expr{init->getInit()->IgnoreUnlessSpelledInSource()};
210 str_expr->dump();
211
212 clang::StringLiteral *str_lit{llvm::dyn_cast<clang::StringLiteral>(str_expr)};
213 if (str_lit) { // = llvm::dyn_cast<clang::StringLiteral>(str_expr)) {
214 LLVM_DEBUG(llvm::dbgs()
215 << "Get first arg: " << str_lit->getString() << "\n";);
216 }
217
219 clang::FieldDecl *fd{init->getMember()};
220 if (fd) {
221 auto name{fd->getType().getAsString()};
222 LLVM_DEBUG(llvm::dbgs()
223 << "\n *************** Initializer names ****** : " << name
224 << "\n";);
225 fd->dump();
227 auto decl{fd->getType()
228 .getTypePtr()
229 ->getUnqualifiedDesugaredType()
230 ->getAsCXXRecordDecl()};
231
232 if (decl) {
233 LLVM_DEBUG(llvm::dbgs() << "decl: " << decl->getNameAsString() << "\n";);
234 for (const auto &base : decl->bases()) {
235 clang::CXXRecordDecl *base_decl{base.getType()
236 .getTypePtr()
237 ->getUnqualifiedDesugaredType()
238 ->getAsCXXRecordDecl()};
239 if (base_decl) {
240 LLVM_DEBUG(llvm::dbgs() << "base decl: "
241 << base_decl->getNameAsString() << "\n";);
242
243 if (base_decl->getNameAsString() == "sc_module") {
244 LLVM_DEBUG(llvm::dbgs() << "Module class\n";);
245 module_info.push_back(
246 std::make_tuple(fd, str_lit->getString().str(), init));
247 }
248 }
249 }
250 }
251 }
252 return module_info;
253}
254
255} // namespace utils
256} // namespace sc_ast_matchers
Clang forward declarations.
Definition FindArgument.h:6
std::vector< const clang::CXXRecordDecl * > getAllBaseClasses(const clang::CXXRecordDecl *decl)
bool isCXXMemberCallExprSystemCCall(const clang::CallExpr *ce, const std::vector< llvm::StringRef > &names)
std::vector< ModuleInitializerTupleType > getModuleInitializerNames(const clang::CXXCtorInitializer *init)
Get the first constructor argument.
std::vector< const clang::CXXRecordDecl * > getAllBaseClassNames(const clang::CXXRecordDecl *decl)