18using namespace std::literals;
25 auto dgRef = DeclGroupRef::Create(
const_cast<ASTContext&
>(ctx), decls.data(), decls.size());
27 return new(ctx) DeclStmt(dgRef, {}, {});
31BinaryOperator*
Assign(
const VarDecl* var, Expr* assignExpr)
37static 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, {}, {});
44BinaryOperator*
Assign(UnaryOperator* var, Expr* assignExpr)
50BinaryOperator*
Assign(MemberExpr* me, ValueDecl* field, Expr* assignExpr)
56BinaryOperator*
Assign(DeclRefExpr* declRef, ValueDecl* field, Expr* assignExpr)
62BinaryOperator*
Assign(DeclRefExpr* declRef, Expr* assignExpr)
68BinaryOperator*
Assign(Expr* var, Expr* assignExpr)
74static 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, {});
81UnaryOperator*
Not(
const Expr* stmt)
93UnaryOperator*
Ref(
const Expr* e)
95 return mkReference(
const_cast<Expr*
>(e), e->getType());
99UnaryOperator*
Ref(
const ValueDecl* d)
105UnaryOperator*
Dref(
const Expr* stmt)
117CallExpr*
Call(
const FunctionDecl* fd, ArrayRef<Expr*> params)
123CallExpr*
Call(MemberExpr* fd, ArrayRef<Expr*> params)
125 return CallExpr::Create(
GetGlobalAST(), fd, params, fd->getType(), VK_LValue, {}, {});
129CallExpr*
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);
144CXXTryStmt*
Try(
const Stmt* tryBody, CXXCatchStmt* catchAllBody)
146 return CXXTryStmt::Create(
147 GetGlobalAST(), {},
const_cast<CompoundStmt*
>(dyn_cast_or_null<CompoundStmt>(tryBody)), {catchAllBody});
151CXXCatchStmt*
Catch(ArrayRef<Stmt*> body)
155 return new(
GetGlobalAST()) CXXCatchStmt({},
nullptr, compStmt);
161 return Catch(ArrayRef<Stmt*>{body});
165CXXThrowExpr*
Throw(
const Expr* expr)
167 return new(
GetGlobalAST()) CXXThrowExpr(
const_cast<Expr*
>(expr),
VoidTy(), {},
false);
171UnaryExprOrTypeTraitExpr*
Sizeof(QualType toType)
174 return new(ctx) UnaryExprOrTypeTraitExpr(UETT_SizeOf, ctx.getTrivialTypeSourceInfo(toType), toType, {}, {});
178CXXStaticCastExpr*
Cast(
const Expr* toExpr, QualType toType)
180 return StaticCast(toType,
const_cast<Expr*
>(toExpr),
false);
184QualType
Ptr(QualType srcType)
205 llvm::APInt(32, size,
false),
207 ArraySizeModifier::Normal,
234CXXReinterpretCastExpr*
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),
253CXXStaticCastExpr*
StaticCast(QualType toType,
const Expr* toExpr,
bool makePointer)
257 QualType sourceInfoToType = makePointer ?
Ptr(toType) : toType;
258 toType = toType.getNonReferenceType();
260 return CXXStaticCastExpr::Create(ctx,
264 const_cast<Expr*
>(toExpr),
266 ctx.getTrivialTypeSourceInfo(sourceInfoToType),
278 return LabelDecl::Create(
const_cast<ASTContext&
>(ctx), ctx.getTranslationUnitDecl(), {}, &ctx.Idents.get(name));
282LabelStmt*
Label(std::string_view name)
288CompoundStmt*
mkCompoundStmt(ArrayRef<Stmt*> bodyStmts, SourceLocation beginLoc, SourceLocation endLoc)
290 return CompoundStmt::Create(
GetGlobalAST(), bodyStmts, FPOptionsOverride{}, beginLoc, endLoc);
294IfStmt*
If(
const Expr* condition, ArrayRef<Stmt*> bodyStmts)
298 IfStatementKind::Ordinary,
301 const_cast<Expr*
>(condition),
310IntegerLiteral*
Int32(uint64_t value)
313 llvm::APInt v{32, value,
true};
315 return IntegerLiteral::Create(ctx, v, ctx.IntTy, {});
319MemberExpr*
AccessMember(
const Expr* expr,
const ValueDecl* vd,
bool isArrow)
322 const_cast<Expr*
>(expr),
324 const_cast<ValueDecl*
>(vd),
325 vd->getType().getNonReferenceType(),
331BinaryOperator*
Equal(Expr* var, Expr* assignExpr)
337BinaryOperator*
Plus(Expr* var, Expr* assignExpr)
343GotoStmt*
Goto(std::string_view labelName)
349ParmVarDecl*
Parameter(
const FunctionDecl* fd, std::string_view name, QualType type)
353 return ParmVarDecl::Create(
const_cast<ASTContext&
>(ctx),
354 const_cast<FunctionDecl*
>(fd),
357 &ctx.Idents.get(name),
369 SmallVector<QualType, 8> argTypes{};
371 for(
const auto& [_, type] : parameters) {
372 argTypes.push_back(type);
375 FunctionDecl* fdd = FunctionDecl::Create(
376 const_cast<ASTContext&
>(ctx),
380 &ctx.Idents.get(name),
381 ctx.getFunctionType(returnType, ArrayRef<QualType>{argTypes}, FunctionProtoType::ExtProtoInfo{}),
387 ConstexprSpecKind::Unspecified,
389 fdd->setImplicit(
true);
391 SmallVector<ParmVarDecl*, 8> paramVarDecls{};
393 for(
const auto& [name, type] : parameters) {
394 ParmVarDecl* param =
Parameter(fdd, name, type);
395 param->setScopeInfo(0, 0);
396 paramVarDecls.push_back(param);
399 fdd->setParams(paramVarDecls);
413 NamespaceDecl* stdNs = NamespaceDecl::Create(
const_cast<ASTContext&
>(ctx),
414 ctx.getTranslationUnitDecl(),
418 &ctx.Idents.get(
"std"),
422 return FunctionBase(name, returnType, parameters, stdNs);
429 NestedNameSpecifierLoc{},
431 const_cast<ValueDecl*
>(vd),
444 return ImplicitCastExpr::Create(
451 return CXXMemberCallExpr::Create(
GetGlobalAST(), memExpr, {}, retType, VK_LValue, {}, {});
457 return ReturnStmt::Create(
GetGlobalAST(), {}, stmt,
nullptr);
469 return SwitchStmt::Create(
GetGlobalAST(),
nullptr,
nullptr, stmt, {}, {});
481 auto* caseStmt = CaseStmt::Create(
GetGlobalAST(),
Int32(value),
nullptr, {}, {}, {});
482 caseStmt->setSubStmt(stmt);
488VarDecl*
Variable(std::string_view name, QualType type, DeclContext* dc)
496 return VarDecl::Create(
const_cast<ASTContext&
>(ctx), dc, {}, {}, &ctx.Idents.get(name), type,
nullptr, SC_None);
502 static auto* nstmt =
new(
GetGlobalAST()) NullStmt({},
false);
513CXXRecordDecl*
Struct(std::string_view name)
515 auto getRecord = [&] {
518 return CXXRecordDecl::Create(
519 ctx, TagTypeKind::Struct, ctx.getTranslationUnitDecl(), {}, {}, &ctx.Idents.get(name),
nullptr,
false);
522 auto* rd = getRecord();
523 rd->startDefinition();
526 auto* selfDecl = getRecord();
527 selfDecl->setAccess(AS_public);
528 rd->addDecl(selfDecl);
534FieldDecl*
mkFieldDecl(DeclContext* dc, std::string_view name, QualType type)
538 FieldDecl::Create(ctx, dc, {}, {}, &ctx.Idents.get(name), type,
nullptr,
nullptr,
false, ICIS_NoInit);
539 fieldDecl->setAccess(AS_public);
545InitListExpr*
InitList(ArrayRef<Expr*> initExprs, QualType t)
548 initList->setType(t);
554ArraySubscriptExpr*
ArraySubscript(
const Expr* lhs, uint64_t index, QualType type)
557 const_cast<Expr*
>(lhs),
Int32(index), type, ExprValueKind::VK_LValue, ExprObjectKind::OK_Ordinary, {});
564 ret.reserve(params.size());
566 for(
const auto& [name, type] : params) {
567 ret.emplace_back(name, type);
576 auto* internalThisVar =
Variable(name, type);
584 DeclRefExpr* lhsDeclRef,
586 ArrayRef<Expr*> callParams,
588 AsReference asReference)
590 if(
nullptr == lhsMemberExpr) {
591 lhsMemberExpr = lhsDeclRef;
597 SmallVector<Expr*, 8> modCallParams{};
599 if(DoCast::Yes == doCast) {
600 modCallParams.push_back(
StaticCast(lhsDeclRef->getType(), lhsDeclRef,
false));
603 if(AsReference::Yes == asReference) {
604 modCallParams.push_back(
Ref(lhsMemberExpr));
606 modCallParams.push_back(lhsMemberExpr);
610 modCallParams.append(callParams.begin(), callParams.end());
612 return Call(callCtor, modCallParams);
618 const FieldDecl* fieldDecl,
619 ArrayRef<Expr*> callParams,
621 AsReference asReference)
624 Expr* lhsMemberExpr{};
626 if(DoCast::No == doCast) {
630 return CallConstructor(ctorType, lhsDeclRef, lhsMemberExpr, callParams, doCast, asReference);
635 const VarDecl* varDecl,
636 ArrayRef<Expr*> callParams,
638 AsReference asReference)
642 return CallConstructor(ctorType, lhsDeclRef,
nullptr, callParams, doCast, asReference);
646CXXBoolLiteralExpr*
Bool(
bool b)
649 return new(ctx) CXXBoolLiteralExpr(b, ctx.BoolTy, {});
658 {{kwInternalThis, lhsDeclRef->getType()}});
660 return Call(callDtor, {
Ref(lhsDeclRef)});
664QualType
Typedef(std::string_view name, QualType underlayingType)
667 auto* type = TypedefDecl::Create(
const_cast<ASTContext&
>(ctx),
668 ctx.getTranslationUnitDecl(),
671 &ctx.Idents.get(name),
672 ctx.getTrivialTypeSourceInfo(underlayingType));
674 return ctx.getTypeDeclType(type);
680 return QualType(md->getParent()->getTypeForDecl(), 0);
686 return QualType(rd->getTypeForDecl(), 0);
690CXXNewExpr*
New(ArrayRef<Expr*> placementArgs,
const Expr* expr, QualType t)
694 return CXXNewExpr::Create(ctx,
702 std::optional<Expr*>{},
703 CXXNewInitializationStyle::Parens,
704 const_cast<Expr*
>(expr),
706 ctx.getTrivialTypeSourceInfo(t),
712BinaryOperator*
Mul(Expr* lhs, Expr* rhs)
714 return mkBinaryOperator(lhs, rhs, BinaryOperator::Opcode::BO_Mul, lhs->getType());
718BinaryOperator*
And(VarDecl* lhs, Expr* rhs)
724void StmtsContainer::AddBodyStmts(
Stmt* body)
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);
737 std::replace(parent->child_begin(), parent->child_end(), oldNode, newNode);
743 if(
const auto* ctorExpr = dyn_cast_or_null<CXXConstructExpr>(expr)) {
744 auto mutableCtorExpr =
const_cast<CXXConstructExpr*
>(ctorExpr);
746 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)
auto * mkStdFunctionDecl(std::string_view name, QualType returnType, const params_vector ¶meters)
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 ¶ms)
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
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 ¶meters, 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
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)
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)