18 using namespace std::literals;
25 auto dgRef = DeclGroupRef::Create(
const_cast<ASTContext&
>(ctx), decls.data(), decls.size());
27 return new(ctx) DeclStmt(dgRef, {}, {});
31 BinaryOperator*
Assign(
const VarDecl* var, Expr* assignExpr)
37 static BinaryOperator*
mkBinaryOperator(Expr* lhs, Expr* rhs, BinaryOperator::Opcode opc, QualType resType)
39 return BinaryOperator::Create(
40 GetGlobalAST(), lhs, rhs, opc, resType.getNonReferenceType(), VK_LValue, OK_Ordinary, {}, {});
44 BinaryOperator*
Assign(UnaryOperator* var, Expr* assignExpr)
50 BinaryOperator*
Assign(MemberExpr* me, ValueDecl* field, Expr* assignExpr)
56 BinaryOperator*
Assign(DeclRefExpr* declRef, ValueDecl* field, Expr* assignExpr)
62 BinaryOperator*
Assign(DeclRefExpr* declRef, Expr* assignExpr)
68 BinaryOperator*
Assign(Expr* var, Expr* assignExpr)
74 static UnaryOperator*
mkUnaryOperator(
const Expr* stmt, UnaryOperatorKind kind, QualType type)
76 return UnaryOperator::Create(
77 GetGlobalAST(),
const_cast<Expr*
>(stmt), kind, type, VK_PRValue, OK_Ordinary, {},
false, {});
81 UnaryOperator*
Not(
const Expr* stmt)
93 UnaryOperator*
Ref(
const Expr* e)
95 return mkReference(
const_cast<Expr*
>(e), e->getType());
99 UnaryOperator*
Ref(
const ValueDecl* d)
105 UnaryOperator*
Dref(
const Expr* stmt)
117 CallExpr*
Call(
const FunctionDecl* fd, ArrayRef<Expr*> params)
123 CallExpr*
Call(MemberExpr* fd, ArrayRef<Expr*> params)
125 return CallExpr::Create(
GetGlobalAST(), fd, params, fd->getType(), VK_LValue, {}, {});
129 CallExpr*
Call(std::string_view name, ArrayRef<Expr*> args)
132 params.reserve(args.size());
134 for(
const auto& param : args) {
135 params.emplace_back(
"dummy"sv, param->getType());
140 return Call(freeFd, args);
144 CXXTryStmt*
Try(
const Stmt* tryBody, CXXCatchStmt* catchAllBody)
146 return CXXTryStmt::Create(
147 GetGlobalAST(), {},
const_cast<CompoundStmt*
>(dyn_cast_or_null<CompoundStmt>(tryBody)), {catchAllBody});
151 CXXCatchStmt*
Catch(ArrayRef<Stmt*> body)
155 return new(
GetGlobalAST()) CXXCatchStmt({},
nullptr, compStmt);
161 return Catch(ArrayRef<Stmt*>{body});
165 CXXThrowExpr*
Throw(
const Expr* expr)
167 return new(
GetGlobalAST()) CXXThrowExpr(
const_cast<Expr*
>(expr),
VoidTy(), {},
false);
171 UnaryExprOrTypeTraitExpr*
Sizeof(QualType toType)
174 return new(ctx) UnaryExprOrTypeTraitExpr(UETT_SizeOf, ctx.getTrivialTypeSourceInfo(toType), toType, {}, {});
178 CXXStaticCastExpr*
Cast(
const Expr* toExpr, QualType toType)
180 return StaticCast(toType,
const_cast<Expr*
>(toExpr),
false);
184 QualType
Ptr(QualType srcType)
205 llvm::APInt(32, size,
false),
207 ArraySizeModifier::Normal,
234 CXXReinterpretCastExpr*
ReinterpretCast(QualType toType,
const Expr* toExpr,
bool makePointer)
238 QualType sourceInfoToType = makePointer ?
Ptr(toType) : toType;
240 return CXXReinterpretCastExpr::Create(ctx,
244 const_cast<Expr*
>(toExpr),
246 ctx.getTrivialTypeSourceInfo(sourceInfoToType),
253 CXXStaticCastExpr*
StaticCast(QualType toType,
const Expr* toExpr,
bool makePointer)
257 QualType sourceInfoToType = makePointer ?
Ptr(toType) : toType;
259 return CXXStaticCastExpr::Create(ctx,
263 const_cast<Expr*
>(toExpr),
265 ctx.getTrivialTypeSourceInfo(sourceInfoToType),
277 return LabelDecl::Create(
const_cast<ASTContext&
>(ctx), ctx.getTranslationUnitDecl(), {}, &ctx.Idents.get(name));
281 LabelStmt*
Label(std::string_view name)
287 CompoundStmt*
mkCompoundStmt(ArrayRef<Stmt*> bodyStmts, SourceLocation beginLoc, SourceLocation endLoc)
289 return CompoundStmt::Create(
GetGlobalAST(), bodyStmts, FPOptionsOverride{}, beginLoc, endLoc);
293 IfStmt*
If(
const Expr* condition, ArrayRef<Stmt*> bodyStmts)
297 IfStatementKind::Ordinary,
300 const_cast<Expr*
>(condition),
309 IntegerLiteral*
Int32(uint64_t value)
312 llvm::APInt v{32, value,
true};
314 return IntegerLiteral::Create(ctx, v, ctx.IntTy, {});
318 MemberExpr*
AccessMember(
const Expr* expr,
const ValueDecl* vd,
bool isArrow)
321 const_cast<Expr*
>(expr),
323 const_cast<ValueDecl*
>(vd),
324 vd->getType().getNonReferenceType(),
330 BinaryOperator*
Equal(Expr* var, Expr* assignExpr)
336 BinaryOperator*
Plus(Expr* var, Expr* assignExpr)
342 GotoStmt*
Goto(std::string_view labelName)
348 ParmVarDecl*
Parameter(
const FunctionDecl* fd, std::string_view name, QualType type)
352 return ParmVarDecl::Create(
const_cast<ASTContext&
>(ctx),
353 const_cast<FunctionDecl*
>(fd),
356 &ctx.Idents.get(name),
368 SmallVector<QualType, 8> argTypes{};
370 for(
const auto& [_, type] : parameters) {
371 argTypes.push_back(type);
374 FunctionDecl* fdd = FunctionDecl::Create(
375 const_cast<ASTContext&
>(ctx),
379 &ctx.Idents.get(name),
380 ctx.getFunctionType(returnType, ArrayRef<QualType>{argTypes}, FunctionProtoType::ExtProtoInfo{}),
386 ConstexprSpecKind::Unspecified,
388 fdd->setImplicit(
true);
390 SmallVector<ParmVarDecl*, 8> paramVarDecls{};
392 for(
const auto& [name, type] : parameters) {
393 ParmVarDecl* param =
Parameter(fdd, name, type);
394 param->setScopeInfo(0, 0);
395 paramVarDecls.push_back(param);
398 fdd->setParams(paramVarDecls);
412 NamespaceDecl* stdNs = NamespaceDecl::Create(
const_cast<ASTContext&
>(ctx),
413 ctx.getTranslationUnitDecl(),
417 &ctx.Idents.get(
"std"),
421 return FunctionBase(name, returnType, parameters, stdNs);
428 NestedNameSpecifierLoc{},
430 const_cast<ValueDecl*
>(vd),
443 return ImplicitCastExpr::Create(
450 return CXXMemberCallExpr::Create(
GetGlobalAST(), memExpr, {}, retType, VK_LValue, {}, {});
456 return ReturnStmt::Create(
GetGlobalAST(), {}, stmt,
nullptr);
460 ReturnStmt*
Return(
const ValueDecl* stmt)
468 return SwitchStmt::Create(
GetGlobalAST(),
nullptr,
nullptr, stmt, {}, {});
480 auto* caseStmt = CaseStmt::Create(
GetGlobalAST(),
Int32(value),
nullptr, {}, {}, {});
481 caseStmt->setSubStmt(stmt);
487 VarDecl*
Variable(std::string_view name, QualType type, DeclContext* dc)
495 return VarDecl::Create(
const_cast<ASTContext&
>(ctx), dc, {}, {}, &ctx.Idents.get(name), type,
nullptr, SC_None);
501 static auto* nstmt =
new(
GetGlobalAST()) NullStmt({},
false);
512 CXXRecordDecl*
Struct(std::string_view name)
514 auto getRecord = [&] {
517 return CXXRecordDecl::Create(
518 ctx,
TagTypeKind::Struct, ctx.getTranslationUnitDecl(), {}, {}, &ctx.Idents.get(name),
nullptr,
false);
521 auto* rd = getRecord();
522 rd->startDefinition();
525 auto* selfDecl = getRecord();
526 selfDecl->setAccess(AS_public);
527 rd->addDecl(selfDecl);
533 FieldDecl*
mkFieldDecl(DeclContext* dc, std::string_view name, QualType type)
537 FieldDecl::Create(ctx, dc, {}, {}, &ctx.Idents.get(name), type,
nullptr,
nullptr,
false, ICIS_NoInit);
538 fieldDecl->setAccess(AS_public);
544 InitListExpr*
InitList(ArrayRef<Expr*> initExprs, QualType t)
547 initList->setType(t);
553 ArraySubscriptExpr*
ArraySubscript(
const Expr* lhs, uint64_t index, QualType type)
556 const_cast<Expr*
>(lhs),
Int32(index), type, ExprValueKind::VK_LValue, ExprObjectKind::OK_Ordinary, {});
563 ret.reserve(params.size());
565 for(
const auto& [name, type] : params) {
566 ret.emplace_back(name, type);
575 auto* internalThisVar =
Variable(name, type);
583 DeclRefExpr* lhsDeclRef,
585 ArrayRef<Expr*> callParams,
587 AsReference asReference)
589 if(
nullptr == lhsMemberExpr) {
590 lhsMemberExpr = lhsDeclRef;
596 SmallVector<Expr*, 8> modCallParams{};
598 if(DoCast::Yes == doCast) {
599 modCallParams.push_back(
StaticCast(lhsDeclRef->getType(), lhsDeclRef,
false));
602 if(AsReference::Yes == asReference) {
603 modCallParams.push_back(
Ref(lhsMemberExpr));
605 modCallParams.push_back(lhsMemberExpr);
609 modCallParams.append(callParams.begin(), callParams.end());
611 return Call(callCtor, modCallParams);
617 const FieldDecl* fieldDecl,
618 ArrayRef<Expr*> callParams,
620 AsReference asReference)
623 Expr* lhsMemberExpr{};
625 if(DoCast::No == doCast) {
629 return CallConstructor(ctorType, lhsDeclRef, lhsMemberExpr, callParams, doCast, asReference);
634 const VarDecl* varDecl,
635 ArrayRef<Expr*> callParams,
637 AsReference asReference)
641 return CallConstructor(ctorType, lhsDeclRef,
nullptr, callParams, doCast, asReference);
645 CXXBoolLiteralExpr*
Bool(
bool b)
648 return new(ctx) CXXBoolLiteralExpr(b, ctx.BoolTy, {});
657 {{kwInternalThis, lhsDeclRef->getType()}});
659 return Call(callDtor, {
Ref(lhsDeclRef)});
663 QualType
Typedef(std::string_view name, QualType underlayingType)
666 auto* type = TypedefDecl::Create(
const_cast<ASTContext&
>(ctx),
667 ctx.getTranslationUnitDecl(),
670 &ctx.Idents.get(name),
671 ctx.getTrivialTypeSourceInfo(underlayingType));
673 return ctx.getTypeDeclType(type);
679 return QualType(md->getParent()->getTypeForDecl(), 0);
685 return QualType(rd->getTypeForDecl(), 0);
689 CXXNewExpr*
New(ArrayRef<Expr*> placementArgs,
const Expr* expr, QualType t)
693 return CXXNewExpr::Create(ctx,
701 std::optional<Expr*>{},
702 CXXNewInitializationStyle::Parens,
703 const_cast<Expr*
>(expr),
705 ctx.getTrivialTypeSourceInfo(t),
711 BinaryOperator*
Mul(Expr* lhs, Expr* rhs)
713 return mkBinaryOperator(lhs, rhs, BinaryOperator::Opcode::BO_Mul, lhs->getType());
717 BinaryOperator*
And(VarDecl* lhs, Expr* rhs)
723 void StmtsContainer::AddBodyStmts(
Stmt* body)
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);
736 std::replace(parent->child_begin(), parent->child_end(), oldNode, newNode);
742 if(
const auto* ctorExpr = dyn_cast_or_null<CXXConstructExpr>(expr)) {
743 auto mutableCtorExpr =
const_cast<CXXConstructExpr*
>(ctorExpr);
745 return {mutableCtorExpr->arg_begin(), mutableCtorExpr->arg_end()};
const ASTContext & GetGlobalAST()
Get access to the ASTContext.
constexpr std::string_view kwInternalThis
BinaryOperator * Equal(Expr *var, Expr *assignExpr)
UnaryOperator * AddrOf(const Expr *stmt)
BinaryOperator * Plus(Expr *var, Expr *assignExpr)
CXXReinterpretCastExpr * ReinterpretCast(QualType toType, const Expr *toExpr, bool makePointer)
CXXRecordDecl * Struct(std::string_view name)
FieldDecl * mkFieldDecl(DeclContext *dc, std::string_view name, QualType type)
auto * mkStdFunctionDecl(std::string_view name, QualType returnType, const params_vector ¶meters)
static QualType mkAnonVoidFunctionPointer()
BinaryOperator * Assign(Expr *var, Expr *assignExpr)
params_vector to_params_view(params_store ¶ms)
DeclRefExpr * mkDeclRefExpr(const ValueDecl *vd)
QualType Typedef(std::string_view name, QualType underlayingType)
CXXNewExpr * New(ArrayRef< Expr * > placementArgs, const Expr *expr, QualType t)
UnaryOperator * Ref(const ValueDecl *d)
std::vector< std::pair< std::string_view, QualType > > params_vector
CallExpr * CallConstructor(QualType ctorType, const VarDecl *varDecl, ArrayRef< Expr * > callParams, DoCast doCast, AsReference asReference)
QualType GetRecordDeclType(const RecordDecl *rd)
static FunctionDecl * CreateFunctionDecl(std::string_view funcName, params_vector params)
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)
SmallVector< Expr *, 5 > ArgsToExprVector(const Expr *expr)
ArraySubscriptExpr * ArraySubscript(const Expr *lhs, uint64_t index, QualType type)
CXXStaticCastExpr * Cast(const Expr *toExpr, QualType toType)
CXXStaticCastExpr * CastToVoidFunPtr(std::string_view name)
CaseStmt * Case(int value, Stmt *stmt)
CXXCatchStmt * Catch(Stmt *body)
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)
GotoStmt * Goto(std::string_view labelName)
InitListExpr * InitList(ArrayRef< Expr * > initExprs, QualType t)
CXXThrowExpr * Throw(const Expr *expr)
void ReplaceNode(Stmt *parent, Stmt *oldNode, Stmt *newNode)
UnaryExprOrTypeTraitExpr * Sizeof(QualType toType)
static BinaryOperator * mkBinaryOperator(Expr *lhs, Expr *rhs, BinaryOperator::Opcode opc, QualType resType)
ReturnStmt * Return(const ValueDecl *stmt)
CallExpr * Call(std::string_view name, ArrayRef< Expr * > args)
auto * mkLabelDecl(std::string_view name)
LabelStmt * Label(std::string_view name)
std::vector< std::pair< std::string, QualType > > params_store
DeclStmt * _mkDeclStmt(std::span< Decl * > decls)
UnaryOperator * Not(const Expr *stmt)
CXXBoolLiteralExpr * Bool(bool b)
FunctionDecl * Function(std::string_view name, QualType returnType, const params_vector ¶meters)
CompoundStmt * mkCompoundStmt(ArrayRef< Stmt * > bodyStmts, SourceLocation beginLoc, SourceLocation endLoc)
static UnaryOperator * mkUnaryOperator(const Expr *stmt, UnaryOperatorKind kind, QualType type)
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 auto * FunctionBase(std::string_view name, QualType returnType, const params_vector ¶meters, DeclContext *declCtx)
CXXStaticCastExpr * StaticCast(QualType toType, const Expr *toExpr, bool makePointer)
static UnaryOperator * mkReference(Expr *e, QualType t)
CXXMemberCallExpr * CallMemberFun(Expr *memExpr, QualType retType)
CXXTryStmt * Try(const Stmt *tryBody, CXXCatchStmt *catchAllBody)
CallExpr * CallDestructor(const VarDecl *varDecl)
void StrCat(std::string &ret, const auto &... args)
static std::string GetName(QualType t, const Unqualified unqualified=Unqualified::No, const InsightsSuppressScope supressScope=InsightsSuppressScope::No)