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 AssociatedConstraint {}
394 fdd->setImplicit(
true);
396 SmallVector<ParmVarDecl*, 8> paramVarDecls{};
398 for(
const auto& [name, type] : parameters) {
399 ParmVarDecl* param =
Parameter(fdd, name, type);
400 param->setScopeInfo(0, 0);
401 paramVarDecls.push_back(param);
404 fdd->setParams(paramVarDecls);
418 NamespaceDecl* stdNs = NamespaceDecl::Create(
const_cast<ASTContext&
>(ctx),
419 ctx.getTranslationUnitDecl(),
423 &ctx.Idents.get(
"std"),
427 return FunctionBase(name, returnType, parameters, stdNs);
434 NestedNameSpecifierLoc{},
436 const_cast<ValueDecl*
>(vd),
449 return ImplicitCastExpr::Create(
456 return CXXMemberCallExpr::Create(
GetGlobalAST(), memExpr, {}, retType, VK_LValue, {}, {});
462 return ReturnStmt::Create(
GetGlobalAST(), {}, stmt,
nullptr);
474 return SwitchStmt::Create(
GetGlobalAST(),
nullptr,
nullptr, stmt, {}, {});
486 auto* caseStmt = CaseStmt::Create(
GetGlobalAST(),
Int32(value),
nullptr, {}, {}, {});
487 caseStmt->setSubStmt(stmt);
493VarDecl*
Variable(std::string_view name, QualType type, DeclContext* dc)
501 return VarDecl::Create(
const_cast<ASTContext&
>(ctx), dc, {}, {}, &ctx.Idents.get(name), type,
nullptr, SC_None);
507 static auto* nstmt =
new(
GetGlobalAST()) NullStmt({},
false);
518CXXRecordDecl*
Struct(std::string_view name)
520 auto getRecord = [&] {
523 return CXXRecordDecl::Create(
524 ctx, TagTypeKind::Struct, ctx.getTranslationUnitDecl(), {}, {}, &ctx.Idents.get(name),
nullptr,
false);
527 auto* rd = getRecord();
528 rd->startDefinition();
531 auto* selfDecl = getRecord();
532 selfDecl->setAccess(AS_public);
533 rd->addDecl(selfDecl);
539FieldDecl*
mkFieldDecl(DeclContext* dc, std::string_view name, QualType type)
543 FieldDecl::Create(ctx, dc, {}, {}, &ctx.Idents.get(name), type,
nullptr,
nullptr,
false, ICIS_NoInit);
544 fieldDecl->setAccess(AS_public);
550InitListExpr*
InitList(ArrayRef<Expr*> initExprs, QualType t)
553 initList->setType(t);
559ArraySubscriptExpr*
ArraySubscript(
const Expr* lhs, uint64_t index, QualType type)
562 const_cast<Expr*
>(lhs),
Int32(index), type, ExprValueKind::VK_LValue, ExprObjectKind::OK_Ordinary, {});
569 ret.reserve(params.size());
571 for(
const auto& [name, type] : params) {
572 ret.emplace_back(name, type);
581 auto* internalThisVar =
Variable(name, type);
589 DeclRefExpr* lhsDeclRef,
591 ArrayRef<Expr*> callParams,
593 AsReference asReference)
595 if(
nullptr == lhsMemberExpr) {
596 lhsMemberExpr = lhsDeclRef;
602 SmallVector<Expr*, 8> modCallParams{};
604 if(DoCast::Yes == doCast) {
605 modCallParams.push_back(
StaticCast(lhsDeclRef->getType(), lhsDeclRef,
false));
608 if(AsReference::Yes == asReference) {
609 modCallParams.push_back(
Ref(lhsMemberExpr));
611 modCallParams.push_back(lhsMemberExpr);
615 modCallParams.append(callParams.begin(), callParams.end());
617 return Call(callCtor, modCallParams);
623 const FieldDecl* fieldDecl,
624 ArrayRef<Expr*> callParams,
626 AsReference asReference)
629 Expr* lhsMemberExpr{};
631 if(DoCast::No == doCast) {
635 return CallConstructor(ctorType, lhsDeclRef, lhsMemberExpr, callParams, doCast, asReference);
640 const VarDecl* varDecl,
641 ArrayRef<Expr*> callParams,
643 AsReference asReference)
647 return CallConstructor(ctorType, lhsDeclRef,
nullptr, callParams, doCast, asReference);
651CXXBoolLiteralExpr*
Bool(
bool b)
654 return new(ctx) CXXBoolLiteralExpr(b, ctx.BoolTy, {});
663 {{kwInternalThis, lhsDeclRef->getType()}});
665 return Call(callDtor, {
Ref(lhsDeclRef)});
669QualType
Typedef(std::string_view name, QualType underlayingType)
672 auto* type = TypedefDecl::Create(
const_cast<ASTContext&
>(ctx),
673 ctx.getTranslationUnitDecl(),
676 &ctx.Idents.get(name),
677 ctx.getTrivialTypeSourceInfo(underlayingType));
679 return ctx.getTypeDeclType(type);
685 return QualType(md->getParent()->getTypeForDecl(), 0);
691 return QualType(rd->getTypeForDecl(), 0);
695CXXNewExpr*
New(ArrayRef<Expr*> placementArgs,
const Expr* expr, QualType t)
699 return CXXNewExpr::Create(ctx,
704 ImplicitAllocationParameters{AlignedAllocationMode::Yes},
711 std::optional<Expr*>{},
712 CXXNewInitializationStyle::Parens,
713 const_cast<Expr*
>(expr),
715 ctx.getTrivialTypeSourceInfo(t),
721BinaryOperator*
Mul(Expr* lhs, Expr* rhs)
723 return mkBinaryOperator(lhs, rhs, BinaryOperator::Opcode::BO_Mul, lhs->getType());
727BinaryOperator*
And(VarDecl* lhs, Expr* rhs)
733void StmtsContainer::AddBodyStmts(
Stmt* body)
735 if(
auto* b = dyn_cast_or_null<CompoundStmt>(body)) {
736 auto children = b->children();
737 mStmts.append(children.begin(), children.end());
738 }
else if(not isa<NullStmt>(body)) {
739 mStmts.push_back(body);
746 std::replace(parent->child_begin(), parent->child_end(), oldNode, newNode);
752 if(
const auto* ctorExpr = dyn_cast_or_null<CXXConstructExpr>(expr)) {
753 auto mutableCtorExpr =
const_cast<CXXConstructExpr*
>(ctorExpr);
755 return {mutableCtorExpr->arg_begin(), mutableCtorExpr->arg_end()};
#define IS_CLANG_NEWER_THAN(major)
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)