ASTHelpers.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * C++ Insights, copyright (C) by Andreas Fertig
4  * Distributed under an MIT license. See LICENSE for details
5  *
6  ****************************************************************************/
7 
8 #include <algorithm>
9 
10 #include "ASTHelpers.h"
11 #include "CodeGenerator.h"
12 #include "Insights.h"
13 #include "InsightsHelpers.h"
14 #include "InsightsStaticStrings.h"
15 #include "InsightsStrCat.h"
16 //-----------------------------------------------------------------------------
17 
18 using namespace std::literals;
19 
21 DeclStmt* _mkDeclStmt(std::span<Decl*> decls)
22 {
23  const auto& ctx = GetGlobalAST();
24 
25  auto dgRef = DeclGroupRef::Create(const_cast<ASTContext&>(ctx), decls.data(), decls.size());
26 
27  return new(ctx) DeclStmt(dgRef, {}, {});
28 }
29 //-----------------------------------------------------------------------------
30 
31 BinaryOperator* Assign(const VarDecl* var, Expr* assignExpr)
32 {
33  return Assign(mkDeclRefExpr(var), assignExpr);
34 }
35 //-----------------------------------------------------------------------------
36 
37 static BinaryOperator* mkBinaryOperator(Expr* lhs, Expr* rhs, BinaryOperator::Opcode opc, QualType resType)
38 {
39  return BinaryOperator::Create(
40  GetGlobalAST(), lhs, rhs, opc, resType.getNonReferenceType(), VK_LValue, OK_Ordinary, {}, {});
41 }
42 //-----------------------------------------------------------------------------
43 
44 BinaryOperator* Assign(UnaryOperator* var, Expr* assignExpr)
45 {
46  return mkBinaryOperator(var, assignExpr, BO_Assign, assignExpr->getType());
47 }
48 //-----------------------------------------------------------------------------
49 
50 BinaryOperator* Assign(MemberExpr* me, ValueDecl* field, Expr* assignExpr)
51 {
52  return mkBinaryOperator(me, assignExpr, BO_Assign, field->getType());
53 }
54 //-----------------------------------------------------------------------------
55 
56 BinaryOperator* Assign(DeclRefExpr* declRef, ValueDecl* field, Expr* assignExpr)
57 {
58  return Assign(AccessMember(declRef, field), field, assignExpr);
59 }
60 //-----------------------------------------------------------------------------
61 
62 BinaryOperator* Assign(DeclRefExpr* declRef, Expr* assignExpr)
63 {
64  return mkBinaryOperator(declRef, assignExpr, BO_Assign, declRef->getType());
65 }
66 //-----------------------------------------------------------------------------
67 
68 BinaryOperator* Assign(Expr* var, Expr* assignExpr)
69 {
70  return mkBinaryOperator(var, assignExpr, BO_Assign, assignExpr->getType());
71 }
72 //-----------------------------------------------------------------------------
73 
74 static UnaryOperator* mkUnaryOperator(const Expr* stmt, UnaryOperatorKind kind, QualType type)
75 {
76  return UnaryOperator::Create(
77  GetGlobalAST(), const_cast<Expr*>(stmt), kind, type, VK_PRValue, OK_Ordinary, {}, false, {});
78 }
79 //-----------------------------------------------------------------------------
80 
81 UnaryOperator* Not(const Expr* stmt)
82 {
83  return mkUnaryOperator(stmt, UO_LNot, stmt->getType());
84 }
85 //-----------------------------------------------------------------------------
86 
87 static UnaryOperator* mkReference(Expr* e, QualType t)
88 {
89  return mkUnaryOperator(e, UO_AddrOf, t);
90 }
91 //-----------------------------------------------------------------------------
92 
93 UnaryOperator* Ref(const Expr* e)
94 {
95  return mkReference(const_cast<Expr*>(e), e->getType());
96 }
97 //-----------------------------------------------------------------------------
98 
99 UnaryOperator* Ref(const ValueDecl* d)
100 {
101  return Ref(mkDeclRefExpr(d));
102 }
103 //-----------------------------------------------------------------------------
104 
105 UnaryOperator* Dref(const Expr* stmt)
106 {
107  return mkUnaryOperator(stmt, UO_Deref, stmt->getType());
108 }
109 //-----------------------------------------------------------------------------
110 
111 UnaryOperator* AddrOf(const Expr* stmt)
112 {
113  return mkUnaryOperator(stmt, UO_AddrOf, stmt->getType());
114 }
115 //-----------------------------------------------------------------------------
116 
117 CallExpr* Call(const FunctionDecl* fd, ArrayRef<Expr*> params)
118 {
119  return CallExpr::Create(GetGlobalAST(), mkDeclRefExpr(fd), params, fd->getType(), VK_LValue, {}, {});
120 }
121 //-----------------------------------------------------------------------------
122 
123 CallExpr* Call(MemberExpr* fd, ArrayRef<Expr*> params)
124 {
125  return CallExpr::Create(GetGlobalAST(), fd, params, fd->getType(), VK_LValue, {}, {});
126 }
127 //-----------------------------------------------------------------------------
128 
129 CallExpr* Call(std::string_view name, ArrayRef<Expr*> args)
130 {
131  params_vector params{};
132  params.reserve(args.size());
133 
134  for(const auto& param : args) {
135  params.emplace_back("dummy"sv, param->getType());
136  }
137 
138  auto* freeFd = Function(name, VoidTy(), params);
139 
140  return Call(freeFd, args);
141 }
142 //-----------------------------------------------------------------------------
143 
144 CXXTryStmt* Try(const Stmt* tryBody, CXXCatchStmt* catchAllBody)
145 {
146  return CXXTryStmt::Create(
147  GetGlobalAST(), {}, const_cast<CompoundStmt*>(dyn_cast_or_null<CompoundStmt>(tryBody)), {catchAllBody});
148 }
149 //-----------------------------------------------------------------------------
150 
151 CXXCatchStmt* Catch(ArrayRef<Stmt*> body)
152 {
153  CompoundStmt* compStmt = mkCompoundStmt(body);
154 
155  return new(GetGlobalAST()) CXXCatchStmt({}, nullptr, compStmt);
156 }
157 //-----------------------------------------------------------------------------
158 
159 CXXCatchStmt* Catch(Stmt* body)
160 {
161  return Catch(ArrayRef<Stmt*>{body});
162 }
163 //-----------------------------------------------------------------------------
164 
165 CXXThrowExpr* Throw(const Expr* expr)
166 {
167  return new(GetGlobalAST()) CXXThrowExpr(const_cast<Expr*>(expr), VoidTy(), {}, false);
168 }
169 //-----------------------------------------------------------------------------
170 
171 UnaryExprOrTypeTraitExpr* Sizeof(QualType toType)
172 {
173  const auto& ctx = GetGlobalAST();
174  return new(ctx) UnaryExprOrTypeTraitExpr(UETT_SizeOf, ctx.getTrivialTypeSourceInfo(toType), toType, {}, {});
175 }
176 //-----------------------------------------------------------------------------
177 
178 CXXStaticCastExpr* Cast(const Expr* toExpr, QualType toType)
179 {
180  return StaticCast(toType, const_cast<Expr*>(toExpr), false);
181 }
182 //-----------------------------------------------------------------------------
183 
184 QualType Ptr(QualType srcType)
185 {
186  return GetGlobalAST().getPointerType(srcType);
187 }
188 //-----------------------------------------------------------------------------
189 
190 CanQualType VoidTy()
191 {
192  return GetGlobalAST().VoidTy;
193 }
194 //-----------------------------------------------------------------------------
195 
196 ParenExpr* Paren(Expr* expr)
197 {
198  return new(GetGlobalAST()) ParenExpr({}, {}, expr);
199 }
200 //-----------------------------------------------------------------------------
201 
202 QualType ContantArrayTy(QualType t, int size)
203 {
204  return GetGlobalAST().getConstantArrayType(t,
205  llvm::APInt(32, size, false),
206  /*const Expr* SizeExpr*/ nullptr,
207  ArraySizeModifier::Normal,
208  0u);
209 }
210 //-----------------------------------------------------------------------------
211 
212 static QualType mkAnonVoidFunctionPointer()
213 {
214  auto voidPtr = Ptr(VoidTy());
215 
216  params_store params{{""s, voidPtr}};
217 
218  return Ptr(Function(""sv, voidPtr, to_params_view(params))->getType());
219 }
220 //-----------------------------------------------------------------------------
221 
222 static FunctionDecl* CreateFunctionDecl(std::string_view funcName, params_vector params)
223 {
224  return Function(funcName, VoidTy(), params);
225 }
226 //-----------------------------------------------------------------------------
227 
228 CXXStaticCastExpr* CastToVoidFunPtr(std::string_view name)
229 {
231 }
232 //-----------------------------------------------------------------------------
233 
234 CXXReinterpretCastExpr* ReinterpretCast(QualType toType, const Expr* toExpr, bool makePointer)
235 {
236  auto& ctx = GetGlobalAST();
237 
238  QualType sourceInfoToType = makePointer ? Ptr(toType) : toType;
239 
240  return CXXReinterpretCastExpr::Create(ctx,
241  toType,
242  VK_LValue,
243  CK_BitCast,
244  const_cast<Expr*>(toExpr),
245  nullptr,
246  ctx.getTrivialTypeSourceInfo(sourceInfoToType),
247  {},
248  {},
249  {});
250 }
251 //-----------------------------------------------------------------------------
252 
253 CXXStaticCastExpr* StaticCast(QualType toType, const Expr* toExpr, bool makePointer)
254 {
255  auto& ctx = GetGlobalAST();
256 
257  QualType sourceInfoToType = makePointer ? Ptr(toType) : toType;
258 
259  return CXXStaticCastExpr::Create(ctx,
260  toType,
261  VK_LValue,
262  CK_DerivedToBase,
263  const_cast<Expr*>(toExpr),
264  nullptr,
265  ctx.getTrivialTypeSourceInfo(sourceInfoToType),
266  {},
267  {},
268  {},
269  {});
270 }
271 //-----------------------------------------------------------------------------
272 
273 auto* mkLabelDecl(std::string_view name)
274 {
275  auto& ctx = GetGlobalAST();
276 
277  return LabelDecl::Create(const_cast<ASTContext&>(ctx), ctx.getTranslationUnitDecl(), {}, &ctx.Idents.get(name));
278 }
279 //-----------------------------------------------------------------------------
280 
281 LabelStmt* Label(std::string_view name)
282 {
283  return new(GetGlobalAST()) LabelStmt({}, mkLabelDecl(name), nullptr);
284 }
285 //-----------------------------------------------------------------------------
286 
287 CompoundStmt* mkCompoundStmt(ArrayRef<Stmt*> bodyStmts, SourceLocation beginLoc, SourceLocation endLoc)
288 {
289  return CompoundStmt::Create(GetGlobalAST(), bodyStmts, FPOptionsOverride{}, beginLoc, endLoc);
290 }
291 //-----------------------------------------------------------------------------
292 
293 IfStmt* If(const Expr* condition, ArrayRef<Stmt*> bodyStmts)
294 {
295  return IfStmt::Create(GetGlobalAST(),
296  {},
297  IfStatementKind::Ordinary,
298  nullptr,
299  nullptr,
300  const_cast<Expr*>(condition),
301  {},
302  {},
303  mkCompoundStmt(bodyStmts),
304  {},
305  /*else*/ nullptr);
306 }
307 //-----------------------------------------------------------------------------
308 
309 IntegerLiteral* Int32(uint64_t value)
310 {
311  auto& ctx = GetGlobalAST();
312  llvm::APInt v{32, value, true};
313 
314  return IntegerLiteral::Create(ctx, v, ctx.IntTy, {});
315 }
316 //-----------------------------------------------------------------------------
317 
318 MemberExpr* AccessMember(const Expr* expr, const ValueDecl* vd, bool isArrow)
319 {
320  return MemberExpr::CreateImplicit(GetGlobalAST(),
321  const_cast<Expr*>(expr),
322  isArrow,
323  const_cast<ValueDecl*>(vd),
324  vd->getType().getNonReferenceType(),
325  VK_LValue,
326  OK_Ordinary);
327 }
328 //-----------------------------------------------------------------------------
329 
330 BinaryOperator* Equal(Expr* var, Expr* assignExpr)
331 {
332  return mkBinaryOperator(var, assignExpr, BO_EQ, GetGlobalAST().BoolTy);
333 }
334 //-----------------------------------------------------------------------------
335 
336 BinaryOperator* Plus(Expr* var, Expr* assignExpr)
337 {
338  return mkBinaryOperator(var, assignExpr, BO_Add, var->getType());
339 }
340 //-----------------------------------------------------------------------------
341 
342 GotoStmt* Goto(std::string_view labelName)
343 {
344  return new(GetGlobalAST()) GotoStmt(mkLabelDecl(labelName), {}, {});
345 }
346 //-----------------------------------------------------------------------------
347 
348 ParmVarDecl* Parameter(const FunctionDecl* fd, std::string_view name, QualType type)
349 {
350  auto& ctx = GetGlobalAST();
351 
352  return ParmVarDecl::Create(const_cast<ASTContext&>(ctx),
353  const_cast<FunctionDecl*>(fd),
354  {},
355  {},
356  &ctx.Idents.get(name),
357  type,
358  nullptr,
359  SC_None,
360  nullptr);
361 }
362 //-----------------------------------------------------------------------------
363 
364 static auto*
365 FunctionBase(std::string_view name, QualType returnType, const params_vector& parameters, DeclContext* declCtx)
366 {
367  auto& ctx = GetGlobalAST();
368  SmallVector<QualType, 8> argTypes{};
369 
370  for(const auto& [_, type] : parameters) {
371  argTypes.push_back(type);
372  }
373 
374  FunctionDecl* fdd = FunctionDecl::Create(
375  const_cast<ASTContext&>(ctx),
376  declCtx,
377  {},
378  {},
379  &ctx.Idents.get(name),
380  ctx.getFunctionType(returnType, ArrayRef<QualType>{argTypes}, FunctionProtoType::ExtProtoInfo{}),
381  nullptr,
382  SC_None, // SC_Static,
383  false,
384  false,
385  false,
386  ConstexprSpecKind::Unspecified,
387  nullptr);
388  fdd->setImplicit(true);
389 
390  SmallVector<ParmVarDecl*, 8> paramVarDecls{};
391 
392  for(const auto& [name, type] : parameters) {
393  ParmVarDecl* param = Parameter(fdd, name, type);
394  param->setScopeInfo(0, 0);
395  paramVarDecls.push_back(param);
396  }
397 
398  fdd->setParams(paramVarDecls);
399 
400  return fdd;
401 }
402 
403 FunctionDecl* Function(std::string_view name, QualType returnType, const params_vector& parameters)
404 {
405  return FunctionBase(name, returnType, parameters, GetGlobalAST().getTranslationUnitDecl());
406 }
407 //-----------------------------------------------------------------------------
408 
409 auto* mkStdFunctionDecl(std::string_view name, QualType returnType, const params_vector& parameters)
410 {
411  auto& ctx = GetGlobalAST();
412  NamespaceDecl* stdNs = NamespaceDecl::Create(const_cast<ASTContext&>(ctx),
413  ctx.getTranslationUnitDecl(),
414  false,
415  {},
416  {},
417  &ctx.Idents.get("std"),
418  nullptr,
419  false);
420 
421  return FunctionBase(name, returnType, parameters, stdNs);
422 }
423 //-----------------------------------------------------------------------------
424 
425 DeclRefExpr* mkDeclRefExpr(const ValueDecl* vd)
426 {
427  return DeclRefExpr::Create(GetGlobalAST(),
428  NestedNameSpecifierLoc{},
429  SourceLocation{},
430  const_cast<ValueDecl*>(vd),
431  false,
432  SourceLocation{},
433  vd->getType(),
434  VK_LValue,
435  nullptr,
436  nullptr,
437  NOUR_None);
438 }
439 //-----------------------------------------------------------------------------
440 
441 ImplicitCastExpr* CastLToRValue(const VarDecl* vd)
442 {
443  return ImplicitCastExpr::Create(
444  GetGlobalAST(), vd->getType(), CK_LValueToRValue, mkDeclRefExpr(vd), {}, VK_LValue, {});
445 }
446 //-----------------------------------------------------------------------------
447 
448 CXXMemberCallExpr* CallMemberFun(Expr* memExpr, QualType retType /*, const std::vector<Expr*>& params*/)
449 {
450  return CXXMemberCallExpr::Create(GetGlobalAST(), memExpr, /*params*/ {}, retType, VK_LValue, {}, {});
451 }
452 //-----------------------------------------------------------------------------
453 
454 ReturnStmt* Return(Expr* stmt)
455 {
456  return ReturnStmt::Create(GetGlobalAST(), {}, stmt, nullptr);
457 }
458 //-----------------------------------------------------------------------------
459 
460 ReturnStmt* Return(const ValueDecl* stmt)
461 {
462  return Return(mkDeclRefExpr(stmt));
463 }
464 //-----------------------------------------------------------------------------
465 
466 SwitchStmt* Switch(Expr* stmt)
467 {
468  return SwitchStmt::Create(GetGlobalAST(), nullptr, nullptr, stmt, {}, {});
469 }
470 //-----------------------------------------------------------------------------
471 
472 BreakStmt* Break()
473 {
474  return new(GetGlobalAST()) BreakStmt(SourceLocation{});
475 }
476 //-----------------------------------------------------------------------------
477 
478 CaseStmt* Case(int value, Stmt* stmt)
479 {
480  auto* caseStmt = CaseStmt::Create(GetGlobalAST(), Int32(value), nullptr, {}, {}, {});
481  caseStmt->setSubStmt(stmt);
482 
483  return caseStmt;
484 }
485 //-----------------------------------------------------------------------------
486 
487 VarDecl* Variable(std::string_view name, QualType type, DeclContext* dc)
488 {
489  auto& ctx = GetGlobalAST();
490 
491  if(nullptr == dc) {
492  dc = GetGlobalAST().getTranslationUnitDecl();
493  }
494 
495  return VarDecl::Create(const_cast<ASTContext&>(ctx), dc, {}, {}, &ctx.Idents.get(name), type, nullptr, SC_None);
496 }
497 //-----------------------------------------------------------------------------
498 
499 NullStmt* mkNullStmt()
500 {
501  static auto* nstmt = new(GetGlobalAST()) NullStmt({}, false);
502  return nstmt;
503 }
504 //-----------------------------------------------------------------------------
505 
506 Stmt* Comment(std::string_view comment)
507 {
508  return new(GetGlobalAST()) CppInsightsCommentStmt{comment};
509 }
510 //-----------------------------------------------------------------------------
511 
512 CXXRecordDecl* Struct(std::string_view name)
513 {
514  auto getRecord = [&] {
515  auto& ctx = GetGlobalAST();
516 
517  return CXXRecordDecl::Create(
518  ctx, TagTypeKind::Struct, ctx.getTranslationUnitDecl(), {}, {}, &ctx.Idents.get(name), nullptr, false);
519  };
520 
521  auto* rd = getRecord();
522  rd->startDefinition();
523 
524  // A "normal" struct has itself attached as a Decl. To make everything work do the same thing here
525  auto* selfDecl = getRecord();
526  selfDecl->setAccess(AS_public);
527  rd->addDecl(selfDecl);
528 
529  return rd;
530 }
531 //-----------------------------------------------------------------------------
532 
533 FieldDecl* mkFieldDecl(DeclContext* dc, std::string_view name, QualType type)
534 {
535  auto& ctx = GetGlobalAST();
536  auto* fieldDecl =
537  FieldDecl::Create(ctx, dc, {}, {}, &ctx.Idents.get(name), type, nullptr, nullptr, false, ICIS_NoInit);
538  fieldDecl->setAccess(AS_public);
539 
540  return fieldDecl;
541 }
542 //-----------------------------------------------------------------------------
543 
544 InitListExpr* InitList(ArrayRef<Expr*> initExprs, QualType t)
545 {
546  auto* initList = new(GetGlobalAST()) InitListExpr(GetGlobalAST(), SourceLocation{}, initExprs, SourceLocation{});
547  initList->setType(t);
548 
549  return initList;
550 }
551 //-----------------------------------------------------------------------------
552 
553 ArraySubscriptExpr* ArraySubscript(const Expr* lhs, uint64_t index, QualType type)
554 {
555  return new(GetGlobalAST()) ArraySubscriptExpr(
556  const_cast<Expr*>(lhs), Int32(index), type, ExprValueKind::VK_LValue, ExprObjectKind::OK_Ordinary, {});
557 }
558 //-----------------------------------------------------------------------------
559 
561 {
562  params_vector ret{};
563  ret.reserve(params.size());
564 
565  for(const auto& [name, type] : params) {
566  ret.emplace_back(name, type);
567  }
568 
569  return ret;
570 }
571 //-----------------------------------------------------------------------------
572 
573 DeclRefExpr* mkVarDeclRefExpr(std::string_view name, QualType type)
574 {
575  auto* internalThisVar = Variable(name, type);
576  auto* declRef = mkDeclRefExpr(internalThisVar);
577 
578  return declRef;
579 }
580 //-----------------------------------------------------------------------------
581 
582 static CallExpr* CallConstructor(QualType ctorType,
583  DeclRefExpr* lhsDeclRef,
584  Expr* lhsMemberExpr,
585  ArrayRef<Expr*> callParams,
586  DoCast doCast,
587  AsReference asReference)
588 {
589  if(nullptr == lhsMemberExpr) {
590  lhsMemberExpr = lhsDeclRef;
591  }
592 
593  auto* callCtor =
594  CreateFunctionDecl(StrCat("Constructor_"sv, GetName(ctorType)), {{kwInternalThis, lhsDeclRef->getType()}});
595 
596  SmallVector<Expr*, 8> modCallParams{};
597 
598  if(DoCast::Yes == doCast) {
599  modCallParams.push_back(StaticCast(lhsDeclRef->getType(), lhsDeclRef, false));
600 
601  } else {
602  if(AsReference::Yes == asReference) {
603  modCallParams.push_back(Ref(lhsMemberExpr));
604  } else {
605  modCallParams.push_back(lhsMemberExpr);
606  }
607  }
608 
609  modCallParams.append(callParams.begin(), callParams.end());
610 
611  return Call(callCtor, modCallParams);
612 }
613 //-----------------------------------------------------------------------------
614 
615 CallExpr* CallConstructor(QualType ctorType,
616  QualType lhsType,
617  const FieldDecl* fieldDecl,
618  ArrayRef<Expr*> callParams,
619  DoCast doCast,
620  AsReference asReference)
621 {
622  auto* lhsDeclRef = mkVarDeclRefExpr(kwInternalThis, lhsType);
623  Expr* lhsMemberExpr{};
624 
625  if(DoCast::No == doCast) {
626  lhsMemberExpr = AccessMember(lhsDeclRef, fieldDecl);
627  }
628 
629  return CallConstructor(ctorType, lhsDeclRef, lhsMemberExpr, callParams, doCast, asReference);
630 }
631 //-----------------------------------------------------------------------------
632 
633 CallExpr* CallConstructor(QualType ctorType,
634  const VarDecl* varDecl,
635  ArrayRef<Expr*> callParams,
636  DoCast doCast,
637  AsReference asReference)
638 {
639  auto* lhsDeclRef = mkDeclRefExpr(varDecl);
640 
641  return CallConstructor(ctorType, lhsDeclRef, nullptr, callParams, doCast, asReference);
642 }
643 //-----------------------------------------------------------------------------
644 
645 CXXBoolLiteralExpr* Bool(bool b)
646 {
647  auto& ctx = GetGlobalAST();
648  return new(ctx) CXXBoolLiteralExpr(b, ctx.BoolTy, {});
649 }
650 //-----------------------------------------------------------------------------
651 
652 CallExpr* CallDestructor(const VarDecl* varDecl)
653 {
654  auto* lhsDeclRef = mkDeclRefExpr(varDecl);
655 
656  auto* callDtor = CreateFunctionDecl(StrCat("Destructor_"sv, GetName(varDecl->getType())),
657  {{kwInternalThis, lhsDeclRef->getType()}});
658 
659  return Call(callDtor, {Ref(lhsDeclRef)});
660 }
661 //-----------------------------------------------------------------------------
662 
663 QualType Typedef(std::string_view name, QualType underlayingType)
664 {
665  auto& ctx = GetGlobalAST();
666  auto* type = TypedefDecl::Create(const_cast<ASTContext&>(ctx),
667  ctx.getTranslationUnitDecl(),
668  {},
669  {},
670  &ctx.Idents.get(name),
671  ctx.getTrivialTypeSourceInfo(underlayingType));
672 
673  return ctx.getTypeDeclType(type);
674 }
675 //-----------------------------------------------------------------------------
676 
677 QualType GetRecordDeclType(const CXXMethodDecl* md)
678 {
679  return QualType(md->getParent()->getTypeForDecl(), 0);
680 }
681 //-----------------------------------------------------------------------------
682 
683 QualType GetRecordDeclType(const RecordDecl* rd)
684 {
685  return QualType(rd->getTypeForDecl(), 0);
686 }
687 //-----------------------------------------------------------------------------
688 
689 CXXNewExpr* New(ArrayRef<Expr*> placementArgs, const Expr* expr, QualType t)
690 {
691  auto& ctx = GetGlobalAST();
692 
693  return CXXNewExpr::Create(ctx,
694  false,
695  nullptr,
696  nullptr,
697  true,
698  false,
699  placementArgs,
700  SourceRange{},
701  std::optional<Expr*>{},
702  CXXNewInitializationStyle::Parens,
703  const_cast<Expr*>(expr),
704  Ptr(t),
705  ctx.getTrivialTypeSourceInfo(t),
706  SourceRange{},
707  SourceRange{});
708 }
709 //-----------------------------------------------------------------------------
710 
711 BinaryOperator* Mul(Expr* lhs, Expr* rhs)
712 {
713  return mkBinaryOperator(lhs, rhs, BinaryOperator::Opcode::BO_Mul, lhs->getType());
714 }
715 //-----------------------------------------------------------------------------
716 
717 BinaryOperator* And(VarDecl* lhs, Expr* rhs)
718 {
719  return mkBinaryOperator(mkDeclRefExpr(lhs), rhs, BinaryOperator::Opcode::BO_And, lhs->getType());
720 }
721 //-----------------------------------------------------------------------------
722 
723 void StmtsContainer::AddBodyStmts(Stmt* body)
724 {
725  if(auto* b = dyn_cast_or_null<CompoundStmt>(body)) {
726  auto children = b->children();
727  mStmts.append(children.begin(), children.end());
728  } else if(not isa<NullStmt>(body)) {
729  mStmts.push_back(body);
730  }
731 }
732 //-----------------------------------------------------------------------------
733 
734 void ReplaceNode(Stmt* parent, Stmt* oldNode, Stmt* newNode)
735 {
736  std::replace(parent->child_begin(), parent->child_end(), oldNode, newNode);
737 }
738 //-----------------------------------------------------------------------------
739 
740 SmallVector<Expr*, 5> ArgsToExprVector(const Expr* expr)
741 {
742  if(const auto* ctorExpr = dyn_cast_or_null<CXXConstructExpr>(expr)) {
743  auto mutableCtorExpr = const_cast<CXXConstructExpr*>(ctorExpr);
744 
745  return {mutableCtorExpr->arg_begin(), mutableCtorExpr->arg_end()};
746  }
747 
748  return {};
749 }
750 //-----------------------------------------------------------------------------
751 
752 } // namespace clang::insights::asthelpers
const ASTContext & GetGlobalAST()
Get access to the ASTContext.
Definition: Insights.cpp:81
constexpr std::string_view kwInternalThis
BinaryOperator * Equal(Expr *var, Expr *assignExpr)
Definition: ASTHelpers.cpp:330
UnaryOperator * AddrOf(const Expr *stmt)
Definition: ASTHelpers.cpp:111
BinaryOperator * Plus(Expr *var, Expr *assignExpr)
Definition: ASTHelpers.cpp:336
CXXReinterpretCastExpr * ReinterpretCast(QualType toType, const Expr *toExpr, bool makePointer)
Definition: ASTHelpers.cpp:234
CXXRecordDecl * Struct(std::string_view name)
Definition: ASTHelpers.cpp:512
FieldDecl * mkFieldDecl(DeclContext *dc, std::string_view name, QualType type)
Definition: ASTHelpers.cpp:533
auto * mkStdFunctionDecl(std::string_view name, QualType returnType, const params_vector &parameters)
Definition: ASTHelpers.cpp:409
static QualType mkAnonVoidFunctionPointer()
Definition: ASTHelpers.cpp:212
BinaryOperator * Assign(Expr *var, Expr *assignExpr)
Definition: ASTHelpers.cpp:68
params_vector to_params_view(params_store &params)
Definition: ASTHelpers.cpp:560
DeclRefExpr * mkDeclRefExpr(const ValueDecl *vd)
Definition: ASTHelpers.cpp:425
QualType Typedef(std::string_view name, QualType underlayingType)
Definition: ASTHelpers.cpp:663
CXXNewExpr * New(ArrayRef< Expr * > placementArgs, const Expr *expr, QualType t)
Definition: ASTHelpers.cpp:689
UnaryOperator * Ref(const ValueDecl *d)
Definition: ASTHelpers.cpp:99
std::vector< std::pair< std::string_view, QualType > > params_vector
Definition: ASTHelpers.h:27
CallExpr * CallConstructor(QualType ctorType, const VarDecl *varDecl, ArrayRef< Expr * > callParams, DoCast doCast, AsReference asReference)
Definition: ASTHelpers.cpp:633
QualType GetRecordDeclType(const RecordDecl *rd)
Definition: ASTHelpers.cpp:683
static FunctionDecl * CreateFunctionDecl(std::string_view funcName, params_vector params)
Definition: ASTHelpers.cpp:222
VarDecl * Variable(std::string_view name, QualType type, DeclContext *dc)
Definition: ASTHelpers.cpp:487
MemberExpr * AccessMember(const Expr *expr, const ValueDecl *vd, bool isArrow)
Definition: ASTHelpers.cpp:318
DeclRefExpr * mkVarDeclRefExpr(std::string_view name, QualType type)
Definition: ASTHelpers.cpp:573
SmallVector< Expr *, 5 > ArgsToExprVector(const Expr *expr)
Definition: ASTHelpers.cpp:740
ArraySubscriptExpr * ArraySubscript(const Expr *lhs, uint64_t index, QualType type)
Definition: ASTHelpers.cpp:553
CXXStaticCastExpr * Cast(const Expr *toExpr, QualType toType)
Definition: ASTHelpers.cpp:178
CXXStaticCastExpr * CastToVoidFunPtr(std::string_view name)
Definition: ASTHelpers.cpp:228
CaseStmt * Case(int value, Stmt *stmt)
Definition: ASTHelpers.cpp:478
CXXCatchStmt * Catch(Stmt *body)
Definition: ASTHelpers.cpp:159
Stmt * Comment(std::string_view comment)
Definition: ASTHelpers.cpp:506
ParenExpr * Paren(Expr *expr)
Definition: ASTHelpers.cpp:196
IfStmt * If(const Expr *condition, ArrayRef< Stmt * > bodyStmts)
Definition: ASTHelpers.cpp:293
BinaryOperator * And(VarDecl *lhs, Expr *rhs)
Definition: ASTHelpers.cpp:717
BinaryOperator * Mul(Expr *lhs, Expr *rhs)
Definition: ASTHelpers.cpp:711
GotoStmt * Goto(std::string_view labelName)
Definition: ASTHelpers.cpp:342
InitListExpr * InitList(ArrayRef< Expr * > initExprs, QualType t)
Definition: ASTHelpers.cpp:544
CXXThrowExpr * Throw(const Expr *expr)
Definition: ASTHelpers.cpp:165
void ReplaceNode(Stmt *parent, Stmt *oldNode, Stmt *newNode)
Definition: ASTHelpers.cpp:734
UnaryExprOrTypeTraitExpr * Sizeof(QualType toType)
Definition: ASTHelpers.cpp:171
static BinaryOperator * mkBinaryOperator(Expr *lhs, Expr *rhs, BinaryOperator::Opcode opc, QualType resType)
Definition: ASTHelpers.cpp:37
ReturnStmt * Return(const ValueDecl *stmt)
Definition: ASTHelpers.cpp:460
CallExpr * Call(std::string_view name, ArrayRef< Expr * > args)
Definition: ASTHelpers.cpp:129
auto * mkLabelDecl(std::string_view name)
Definition: ASTHelpers.cpp:273
LabelStmt * Label(std::string_view name)
Definition: ASTHelpers.cpp:281
std::vector< std::pair< std::string, QualType > > params_store
Definition: ASTHelpers.h:28
DeclStmt * _mkDeclStmt(std::span< Decl * > decls)
Definition: ASTHelpers.cpp:21
UnaryOperator * Not(const Expr *stmt)
Definition: ASTHelpers.cpp:81
CXXBoolLiteralExpr * Bool(bool b)
Definition: ASTHelpers.cpp:645
FunctionDecl * Function(std::string_view name, QualType returnType, const params_vector &parameters)
Definition: ASTHelpers.cpp:403
CompoundStmt * mkCompoundStmt(ArrayRef< Stmt * > bodyStmts, SourceLocation beginLoc, SourceLocation endLoc)
Definition: ASTHelpers.cpp:287
static UnaryOperator * mkUnaryOperator(const Expr *stmt, UnaryOperatorKind kind, QualType type)
Definition: ASTHelpers.cpp:74
SwitchStmt * Switch(Expr *stmt)
Definition: ASTHelpers.cpp:466
IntegerLiteral * Int32(uint64_t value)
Definition: ASTHelpers.cpp:309
QualType ContantArrayTy(QualType t, int size)
Definition: ASTHelpers.cpp:202
ImplicitCastExpr * CastLToRValue(const VarDecl *vd)
Definition: ASTHelpers.cpp:441
ParmVarDecl * Parameter(const FunctionDecl *fd, std::string_view name, QualType type)
Definition: ASTHelpers.cpp:348
UnaryOperator * Dref(const Expr *stmt)
Definition: ASTHelpers.cpp:105
QualType Ptr(QualType srcType)
Definition: ASTHelpers.cpp:184
static auto * FunctionBase(std::string_view name, QualType returnType, const params_vector &parameters, DeclContext *declCtx)
Definition: ASTHelpers.cpp:365
CXXStaticCastExpr * StaticCast(QualType toType, const Expr *toExpr, bool makePointer)
Definition: ASTHelpers.cpp:253
static UnaryOperator * mkReference(Expr *e, QualType t)
Definition: ASTHelpers.cpp:87
CXXMemberCallExpr * CallMemberFun(Expr *memExpr, QualType retType)
Definition: ASTHelpers.cpp:448
CXXTryStmt * Try(const Stmt *tryBody, CXXCatchStmt *catchAllBody)
Definition: ASTHelpers.cpp:144
CallExpr * CallDestructor(const VarDecl *varDecl)
Definition: ASTHelpers.cpp:652
void StrCat(std::string &ret, const auto &... args)
static std::string GetName(QualType t, const Unqualified unqualified=Unqualified::No, const InsightsSuppressScope supressScope=InsightsSuppressScope::No)