systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
CallExprUtils.cpp
Go to the documentation of this file.
1#include "CallExprUtils.h"
2
3#include "clang/AST/Type.h"
4#include "clang/AST/DeclCXX.h"
5#include "clang/AST/ExprCXX.h"
6#include "llvm/Support/Debug.h"
7
8namespace sc_ast_matchers {
9namespace utils {
10
11using namespace clang;
12
13void collect_sugar(const Type *type,
14 std::vector<clang::Type *> &unwrapped_types) {
15 const Type *desugared_final{type->getUnqualifiedDesugaredType()};
16 Type *curr_type{const_cast<Type *>(type)};
17 unwrapped_types.push_back(const_cast<Type *>(desugared_final));
18 while (curr_type != desugared_final) {
19 unwrapped_types.push_back(curr_type);
20 curr_type = const_cast<Type *>(
21 curr_type->getLocallyUnqualifiedSingleStepDesugaredType().getTypePtr());
22 }
23}
24
25bool isInNamespace(const clang::ValueDecl *fd,
26 const std::vector<llvm::StringRef> &names) {
27 llvm::dbgs() << "isInNamespace with ValueDecl\n";
28
29 if (!fd) {
30 return false;
31 }
32
33 // llvm::dbgs() << "Value decl dump\n";
34 // fd->dump();
35
36
37 // This handles the DeclRefExpr expressions. Examples include concat.
38 // TODO: Is there some way to make this work with the types?
39 if (auto dc = dyn_cast<DeclContext>(fd)) {
40 // llvm::dbgs() << "DeclContext\n";
41 auto dcc = dc->getLexicalParent();
42
43 if (dcc->isNamespace()) {
44 if (const auto *nd = llvm::dyn_cast<clang::NamespaceDecl>(dcc)) {
45 // llvm::dbgs() << "Namespace\n";
46 std::vector<llvm::StringRef> names{"sc_dt"};
47 auto iinfo = nd->getIdentifier();
48 // llvm::dbgs() << "@@@@ name " << nd->getName() << "\n";
49 for (const auto name : names) {
50 if (iinfo->isStr(name)) {
51 return true;
52 }
53 }
54 return false;
55 }
56 }
57 }
58
59 // llvm::dbgs() << "Type dump\n";
60 // fd->getType().getTypePtr()->dump();
61 return isInNamespace(fd->getType().getTypePtr(), names);
62
63 //return false;
64}
65
66bool isInNamespace(const clang::Type *tp,
67 const std::vector<llvm::StringRef> &names) {
68 if (!tp) {
69 return false;
70 }
71
74 std::vector<clang::Type *> unwrapped_types{};
75 collect_sugar(tp, unwrapped_types);
76
77 for (auto tap : unwrapped_types) {
78 if (tap->isBuiltinType()) {
79 llvm::dbgs() << "isBuiltinType\n";
80 return false;
81 }
82
83 DeclContext *dc{nullptr};
84 if (tap->isArrayType()) {
85 auto cat1 = dyn_cast<ArrayType>(tap);
86 const Type *tp = cat1->getElementType().getTypePtr();
87
88 // Unwrap array element type.
89 Type *unwrap_tp{nullptr};
90 while (tp && tp != unwrap_tp) {
91 if (auto cat2 = dyn_cast<ArrayType>(tp)) {
92 unwrap_tp = const_cast<Type *>(tp);
93 tp = cat2->getElementType().getTypePtr();
94 } else {
95 unwrap_tp = const_cast<Type *>(tp);
96 }
97 }
98
99 tap = unwrap_tp;
100 }
101
102 // tap->dump();
103 if (tap->isRecordType()) {
104 llvm::dbgs() << "isRecordType\n";
105 const RecordDecl *rdecl = tap->getAsRecordDecl();
106 dc = const_cast<clang::DeclContext *>(rdecl->getLexicalParent());
107 }
108
109 if (tap->isFunctionType()) {
110 llvm::dbgs() << "isFunctionType\n";
111 if (auto rdecl = tap->getAsCXXRecordDecl()) {
112 llvm::dbgs() << "Got in as CXX\n";
113 dc = const_cast<clang::DeclContext *>(rdecl->getLexicalParent());
114 }
115 }
116
117 if (dc && dc->isNamespace()) {
118 llvm::dbgs() << "isNamespace \n";
119 if (const auto *nd = llvm::dyn_cast<clang::NamespaceDecl>(dc)) {
120 auto iinfo = nd->getIdentifier();
121 llvm::dbgs() << "@@ name is " << iinfo->getName() << " for ";
122 for (const auto name : names) {
123 if (iinfo->isStr(name)) {
124 return true;
125 }
126 }
127 return false;
128 }
129 }
130 }
131
132 return false;
133}
134
135bool matchNames(StringRef str, const std::vector<llvm::StringRef> &names) {
136 for (const auto name : names) {
137 if (str == name) {
138 return true;
139 }
140 }
141
142 return false;
143}
144
145// llvm::StringRef getClassNameFromDecl(const clang::FunctionDecl *decl) {
146// if (!decl) return StringRef{""};
147
148// const clang::DeclContext* dc{ decl->getLexicalParent() };
149// if (dc && dc->isNamespace() ) {
150// if (const auto *nd = llvm::dyn_cast<clang::NamespaceDecl>(dc)) {
151// IdentifierInfo *iinfo = nd->getIdentifier();
152// llvm::dbgs() << "@@ name is " << iinfo->getName() << " for ";
153// return iinfo->getName();
154// }
155// }
156
157// return StringRef{""};
158// }
159
160// llvm::StringRef getClassNameFromDecl(const clang::CXXRecordDecl *decl) {
161// if (!decl) return StringRef{""};
162
163// const clang::DeclContext* dc{ decl->getLexicalParent() };
164// if (dc && dc->isNamespace() ) {
165// if (const auto *nd = llvm::dyn_cast<clang::NamespaceDecl>(dc)) {
166// IdentifierInfo *iinfo = nd->getIdentifier();
167// llvm::dbgs() << "@@ name is " << iinfo->getName() << " for ";
168// return iinfo->getName();
169// }
170// }
171
172// return StringRef{""};
173// }
174
175void dumpExprName(const Expr *expr) {
176 if (auto cexpr = dyn_cast<CXXOperatorCallExpr>(expr)) {
177 if (const FunctionDecl *fd = cexpr->getDirectCallee()) {
178 auto decl_info{fd->getNameInfo()};
179 llvm::dbgs() << decl_info.getName().getAsString();
180 }
181 }
182
183 if (auto cexpr = dyn_cast<CallExpr>(expr)) {
184 if (const FunctionDecl *fd = cexpr->getDirectCallee()) {
185 auto decl_info{fd->getNameInfo()};
186 if (decl_info.getName().isIdentifier()) {
187 llvm::dbgs() << decl_info.getName().getAsString();
188 }
189 }
190 }
191}
192
193bool isInNamespace(const Expr *expr,
194 const std::vector<llvm::StringRef> &names) {
195 // Get access to the ASTContext from Expr.
196 if (!expr) {
197 return false;
198 }
199 // std::vector<llvm::StringRef> func_names{"range", "or_reduce" };
200 llvm::dbgs() << "2. Expr isNamespace\n";
201
202 // do not handle operator=
203 // if (auto cexpr = dyn_cast <CXXOperatorCallExpr>(expr)) {
204 // return false;
205 // }
206 //
207 if (auto cexpr = dyn_cast<CallExpr>(expr)) {
208 const Decl *decl = cexpr->getCalleeDecl();
209 ASTContext &Context = decl->getASTContext();
210
211 MatchFinder finder{};
212 NamespaceMatcher ns_matcher{};
213 ns_matcher.registerMatchers(finder);
214 finder.match(*expr, Context);
215 llvm::dbgs() << "@@@ MATCHNAMES " << ns_matcher.getNamespaceName() << " "
216 << ns_matcher.getFunctionName() << "\n";
217 return matchNames(ns_matcher.getNamespaceName(), names);
218 }
219
220 /*
221 // wait() call
222// Expr is a MemberExpr ()
223if (auto me_expr = dyn_cast<MemberExpr>(expr) ) {
224 if (auto mdecl = dyn_cast<CXXMethodDecl>(me_expr->getMemberDecl()) ) {
225 auto cxxdecl{ mdecl->getParent() };
226 llvm::dbgs() << "@@@@@@@@@@@@ MemberExpr\n";
227 cxxdecl->dump();
228 StringRef ns_name{ getClassNameFromDecl(cxxdecl) };
229 llvm::dbgs() << "@@@@ name is " << cxxdecl->getNameAsString() << " and ref
230is " << ns_name << "\n"; return matchNames(ns_name, names);
231 }
232}
233*/
234
235 /*
236 if (auto cexpr = dyn_cast<CallExpr>(expr)) {
237 llvm::dbgs() << "Decl for callexpr\n";
238 cexpr->getCallee()->dump();
239 // const Decl *d = cexpr->getCalleeDecl();
240 // const DeclContext* dc = d->getLexicalParent();
241 // d->dump();
242 // StringRef ns_name{ getClassNameFromDecl(d) };
243 // llvm::dbgs() << "NS NAME = " << ns_name << "\n";
244
245 if (const FunctionDecl* fd = cexpr->getDirectCallee()) {
246 StringRef ns_name{ getClassNameFromDecl(fd) };
247 return matchNames(ns_name, names);
248 }
249
250 //return isInNamespace(cexpr->getType().getTypePtr(), names);
251 }
252 */
253
254 // Concat needs this.
255 if (auto dexpr = dyn_cast<DeclRefExpr>(expr)) {
256 llvm::dbgs() << "@@@@ in DeclRefExpr\n";
257 dexpr->dump();
258 dexpr->getDecl()->dump();
259 return isInNamespace(dexpr->getDecl(), names);
260 }
261
262 return false;
263}
264
265//
266// bool isInNamespace(const CallExpr *cexpr,
267// const std::vector<llvm::StringRef> &names) {
268// llvm::dbgs() << "@@@ callexpr version of isNS\n";
269// if (!cexpr) {
270// return false;
271// }
272// return isInNamespace(cexpr->getType().getTypePtr(), names);
273// }
274
275bool isInNamespace(const CallExpr *cexpr, llvm::StringRef name) {
276 if (!cexpr) {
277 return false;
278 }
279 std::vector<llvm::StringRef> names{name};
280 return isInNamespace(cexpr->getType().getTypePtr(), names);
281}
282} // namespace utils
283} // namespace sc_ast_matchers
void registerMatchers(MatchFinder &finder)
Clang forward declarations.
Definition FindArgument.h:6
void dumpExprName(const Expr *expr)
void collect_sugar(const Type *type, std::vector< clang::Type * > &unwrapped_types)
bool matchNames(StringRef str, const std::vector< llvm::StringRef > &names)
bool isInNamespace(const clang::ValueDecl *fd, const std::vector< llvm::StringRef > &names)