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