8#ifndef INSIGHTS_CODE_GENERATOR_H
9#define INSIGHTS_CODE_GENERATOR_H
11#include "clang/AST/ASTContext.h"
12#include "clang/Rewrite/Core/Rewriter.h"
13#include "llvm/ADT/APInt.h"
27void PushVtableEntry(
const CXXRecordDecl*,
const CXXRecordDecl*, VarDecl* decl);
32 std::string mComment{};
41 std::string_view
Comment()
const {
return mComment; }
43 static bool classof(
const Stmt* T) {
return T->getStmtClass() == NoStmtClass; }
47 static child_iterator iter{};
52 static const_child_iterator iter{};
68 inline static int scopeCounter{};
70 SmallVector<LifetimeEntry, 10> objects{};
75 void Add(
const VarDecl* decl);
76 void AddExtended(
const VarDecl* decl,
const ValueDecl* extending);
124 : mLambdaCallerType{lambdaCallerType}
125 , mCurrentDeclPos{outputFormatHelper.CurrentPos()}
126 , mOutputFormatHelper{outputFormatHelper}
128 mLambdaOutputFormatHelper.
SetIndent(mOutputFormatHelper);
133 if(not mLambdaOutputFormatHelper.
empty()) {
134 mOutputFormatHelper.
InsertAt(mCurrentDeclPos, mLambdaOutputFormatHelper);
149 const size_t mCurrentDeclPos{};
150 OutputFormatHelper& mOutputFormatHelper;
151 OutputFormatHelper mLambdaOutputFormatHelper{};
158 ProcessingPrimaryTemplate);
168 ProcessingPrimaryTemplate processingPrimaryTemplate)
177#define IGNORED_DECL(type) \
178 virtual void InsertArg(const type*) {}
179#define IGNORED_STMT(type) \
180 virtual void InsertArg(const type*) {}
181#define SUPPORTED_DECL(type) virtual void InsertArg(const type* stmt);
182#define SUPPORTED_STMT(type) virtual void InsertArg(const type* stmt);
186 virtual void InsertArg(
const Decl* stmt);
192 if constexpr(std::is_same_v<T, FunctionDecl>) {
193 if(
const auto* tmplArgs = t.getTemplateSpecializationArgs()) {
196 }
else if constexpr(std::is_same_v<T, VarTemplateSpecializationDecl>) {
199 }
else if constexpr(
requires { t.template_arguments(); }) {
200 if constexpr(std::is_same_v<DeclRefExpr, T>) {
201 if(0 == t.getNumTemplateArgs()) {
208 }
else if constexpr(
requires { t.asArray(); }) {
224 const CXXConstructorDecl* cxxInheritedCtorDecl =
nullptr);
249 const TemplateParamsOnly templateParamsOnly = TemplateParamsOnly::No);
277 virtual void FormatCast(
const std::string_view castName,
278 const QualType& CastDestType,
280 const CastKind& castKind);
293 const InsertInline insertInline);
304 if(stmt->getNumTemplateArgs()) {
306 }
else if(stmt->hasExplicitTemplateArgs()) {
313 const NestedNameSpecifier* qualifier,
314 const bool hasTemplateKeyword);
334 void InsertMethodBody(
const FunctionDecl* stmt,
const size_t posBeforeFunc);
363 const AddSpaceAtTheEnd addSpaceAtTheEnd = AddSpaceAtTheEnd::No);
367 const AddSpaceAtTheEnd addSpaceAtTheEnd = AddSpaceAtTheEnd::No);
373 const AddSpaceAtTheEnd addSpaceAtTheEnd = AddSpaceAtTheEnd::No);
395 static std::string
FillConstantArray(
const ConstantArrayType* ct,
const std::string& value,
const uint64_t startAt);
412 NoEmptyInitList::No};
449 :
CodeGenerator{_outputFormatHelper, lambdaStack, ProcessingPrimaryTemplate::No}
498 const size_t posBeforeFunc,
499 std::string_view fsmName,
500 size_t suspendsCount,
503 , mPosBeforeFunc{posBeforeFunc}
504 , mSuspendsCount{suspendsCount}
514 void InsertArg(
const ImplicitCastExpr* stmt)
override;
515 void InsertArg(
const CallExpr* stmt)
override;
516 void InsertArg(
const CXXRecordDecl* stmt)
override;
517 void InsertArg(
const OpaqueValueExpr* stmt)
override;
519 void InsertArg(
const CoroutineBodyStmt* stmt)
override;
520 void InsertArg(
const CoroutineSuspendExpr* stmt)
override;
521 void InsertArg(
const CoreturnStmt* stmt)
override;
523 void InsertCoroutine(
const FunctionDecl& fd,
const CoroutineBodyStmt* body);
528 bool InsertVarDecl(
const VarDecl* vd)
override {
return mInsertVarDecl or (vd and vd->isStaticLocal()); }
541 const size_t mPosBeforeFunc;
542 size_t mPosBeforeSuspendExpr{};
543 size_t mSuspendsCount{};
544 size_t mSuspendsCounter{};
545 bool mInsertVarDecl{
true};
546 bool mSupressCasts{};
547 bool mSupressRecordDecls{};
548 std::string mFrameName{};
549 std::string mFSMName{};
550 CoroutineASTData mASTData{};
551 llvm::DenseMap<const Stmt*, bool> mBinaryExprs{};
552 static inline llvm::DenseMap<const Expr*, std::pair<const DeclRefExpr*, std::string>>
555 QualType GetFrameType()
const {
return QualType(mASTData.mFrameType->getTypeForDecl(), 0); }
556 QualType GetFramePointerType()
const;
558 std::string BuildResumeLabelName(
int)
const;
559 FieldDecl*
AddField(std::string_view name, QualType type);
561 void InsertArgWithNull(
const Stmt* stmt);
571 static inline llvm::DenseMap<std::pair<const Decl*, std::pair<const CXXRecordDecl*, const CXXRecordDecl*>>,
int>
573 bool mInsertSemi{
true};
576 using CodeGenerator::CodeGenerator;
578 using CodeGenerator::InsertArg;
580 void InsertArg(
const CXXThisExpr*)
override;
581 void InsertArg(
const CXXDeleteExpr*)
override;
582 void InsertArg(
const CXXNewExpr*)
override;
583 void InsertArg(
const CXXOperatorCallExpr*)
override;
584 void InsertArg(
const CXXNullPtrLiteralExpr*)
override;
585 void InsertArg(
const StaticAssertDecl*)
override;
586 void InsertArg(
const CXXRecordDecl*)
override;
587 void InsertArg(
const CXXMemberCallExpr*)
override;
588 void InsertArg(
const CXXConstructExpr*)
override;
589 void InsertArg(
const FunctionDecl* stmt)
override;
590 void InsertArg(
const TypedefDecl* stmt)
override;
592 void InsertCXXMethodDecl(
const CXXMethodDecl*, CodeGenerator::SkipBody)
override;
594 void FormatCast(
const std::string_view,
const QualType&,
const Expr*,
const CastKind&)
override;
601 VarDecl* VtblArrayVar(
int size);
602 FieldDecl* VtblPtrField(
const CXXRecordDecl* parent);
623 bool InsertSemi()
override {
return std::exchange(mInsertSemi,
true); }
639 CodeGenerator::ProcessingPrimaryTemplate processingPrimaryTemplate);
653 CodeGenerator::ProcessingPrimaryTemplate processingPrimaryTemplate)
654 : cgs{_outputFormatHelper, lambdaStack, processingPrimaryTemplate}
655 , ofm{_outputFormatHelper}
662 : cgs{_outputFormatHelper}
663 , ofm{_outputFormatHelper}
llvm::function_ref< void()> void_func_ref
A special generator for coroutines. It is only activated, if -show-coroutines-transformation is given...
bool InsertSemi() override
LambdaCallerType callerType() const
LambdaHelper(const LambdaCallerType lambdaCallerType, OutputFormatHelper &outputFormatHelper)
OutputFormatHelper & buffer()
void setCallerType(LambdaCallerType lambdaCallerType)
More or less the heart of C++ Insights.
void InsertFunctionNameWithReturnType(const FunctionDecl &decl, const CXXConstructorDecl *cxxInheritedCtorDecl=nullptr)
Insert the code for a FunctionDecl.
void WrapInParensIfNeeded(bool needsParens, void_func_ref lambda, const AddSpaceAtTheEnd addSpaceAtTheEnd=AddSpaceAtTheEnd::No)
void WrapInCompoundIfNeeded(const Stmt *stmt, const AddNewLineAfter addNewLineAfter)
static std::map< std::string, bool > mSeenDecls
void HandleCompoundStmt(const CompoundStmt *stmt)
void InsertQualifierAndNameWithTemplateArgs(const DeclarationName &declName, const auto *stmt)
void WrapInParens(void_func_ref lambda, const AddSpaceAtTheEnd addSpaceAtTheEnd=AddSpaceAtTheEnd::No)
LambdaStackType mLambdaStackThis
static std::string FillConstantArray(const ConstantArrayType *ct, const std::string &value, const uint64_t startAt)
void InsertTemplateArg(const TemplateArgumentLoc &arg)
virtual void InsertArg(const Decl *stmt)
void InsertTemplateSpecializationHeader(const Decl &)
Insert template<> to introduce a template specialization.
void WrapInCurlys(void_func_ref lambda, const AddSpaceAtTheEnd addSpaceAtTheEnd=AddSpaceAtTheEnd::No)
virtual bool InsertVarDecl(const VarDecl *)
constexpr CodeGenerator(OutputFormatHelper &_outputFormatHelper, LambdaStackType &lambdaStack, ProcessingPrimaryTemplate processingPrimaryTemplate)
const LambdaExpr * mLambdaExpr
void InsertInstantiationPoint(const SourceManager &sm, const SourceLocation &instLoc, std::string_view text={})
Inserts the instantiation point of a template.
ProcessingPrimaryTemplate mProcessingPrimaryTemplate
void InsertTemplateArgs(const T &t)
std::optional< size_t > mCurrentVarDeclPos
STRONG_BOOL(InsertInline)
void InsertAttribute(const Attr &)
OutputFormatHelper * mOutputFormatHelperOutside
Helper output buffer for std::initializer_list expansion.
void WrapInCurliesIfNeeded(bool needsParens, void_func_ref lambda, const AddSpaceAtTheEnd addSpaceAtTheEnd=AddSpaceAtTheEnd::No)
STRONG_BOOL(AddNewLineAfter)
void InsertTemplateGuardEnd(const FunctionDecl *stmt)
static std::string GetValueOfValueInit(const QualType &t)
STRONG_BOOL(TemplateParamsOnly)
void LifetimeAddExtended(const VarDecl *, const ValueDecl *)
STRONG_BOOL(ProcessingPrimaryTemplate)
void HandleLocalStaticNonTrivialClass(const VarDecl *stmt)
Show what is behind a local static variable.
virtual void FormatCast(const std::string_view castName, const QualType &CastDestType, const Expr *SubExpr, const CastKind &castKind)
std::optional< size_t > mCurrentCallExprPos
virtual void InsertCXXMethodDecl(const CXXMethodDecl *stmt, SkipBody skipBody)
void InsertTemplateParameters(const TemplateParameterList &list, const TemplateParamsOnly templateParamsOnly=TemplateParamsOnly::No)
! Skip template, type constraints and class/typename.
void HandleTemplateParameterPack(const ArrayRef< TemplateArgument > &args)
void InsertIfOrSwitchInitVariables(same_as_any_of< const IfStmt, const SwitchStmt > auto *stmt)
STRONG_BOOL(NoEmptyInitList)
STRONG_BOOL(UseCommaInsteadOfSemi)
virtual bool InsertSemi()
void UpdateCurrentPos(std::optional< size_t > &pos)
bool InsertLambdaStaticInvoker(const CXXMethodDecl *cxxMethodDecl)
virtual ~CodeGenerator()=default
void InsertTemplateGuardBegin(const FunctionDecl *stmt)
LambdaStackType & mLambdaStack
void InsertConceptConstraint(const llvm::SmallVectorImpl< const Expr * > &constraints, const InsertInline insertInline)
virtual bool InsertComma()
virtual bool InsertNamespace() const
void ForEachArg(const auto &arguments, auto &&lambda)
void InsertQualifierAndName(const DeclarationName &declName, const NestedNameSpecifier *qualifier, const bool hasTemplateKeyword)
NoEmptyInitList mNoEmptyInitList
At least in case if a requires-clause containing T{} we don't want to get T{{}}.
std::optional< size_t > mCurrentReturnPos
void InsertMethodBody(const FunctionDecl *stmt, const size_t posBeforeFunc)
bool mRequiresImplicitReturnZero
Track whether this is a function with an imlpicit return 0.
void InsertConstructorExpr(const T *stmt)
Generalized function to insert either a CXXConstructExpr or CXXUnresolvedConstructExpr.
void InsertArgWithParensIfNeeded(const Stmt *stmt)
static constexpr auto MAX_FILL_VALUES_FOR_ARRAYS
void WrapInParensOrCurlys(const BraceKind curlys, void_func_ref lambda, const AddSpaceAtTheEnd addSpaceAtTheEnd=AddSpaceAtTheEnd::No)
UseCommaInsteadOfSemi mUseCommaInsteadOfSemi
std::optional< size_t > mCurrentFieldPos
void InsertTemplateArg(const TemplateArgument &arg)
void InsertSuffix(const QualType &type)
STRONG_BOOL(ShowConstantExprValue)
void InsertAttributes(const Decl *)
void StartLifetimeScope()
virtual bool SkipSpaceAfterVarDecl()
void InsertCurlysIfRequired(const Stmt *stmt)
Check whether or not this statement will add curlys or parentheses and add them only if required.
OutputFormatHelper & mOutputFormatHelper
void InsertTemplate(const FunctionTemplateDecl *, bool withSpec)
bool InsideDecltype() const
constexpr CodeGenerator(OutputFormatHelper &_outputFormatHelper)
! We do not want to transform a primary template which contains a Coroutine.
void InsertCXXMethodHeader(const CXXMethodDecl *stmt, OutputFormatHelper &initOutputFormatHelper)
void InsertTemplateArgs(const ArrayRef< T > &array)
STRONG_BOOL(AddSpaceAtTheEnd)
LifetimeTracker mLifeTimeTracker
void InsertTemplateArgsObjectParam(const ArrayRef< TemplateArgument > &array)
virtual bool ShowXValueCasts() const
Show casts to xvalues independent from the show all casts option.
static std::string_view GetBuiltinTypeSuffix(const BuiltinType::Kind &kind)
ShowConstantExprValue mShowConstantExprValue
void ParseDeclContext(const DeclContext *Ctx)
A special container which creates either a CodeGenerator or a CfrontCodeGenerator depending on the co...
CodeGeneratorVariant(OutputFormatHelper &_outputFormatHelper, CodeGenerator::LambdaStackType &lambdaStack, CodeGenerator::ProcessingPrimaryTemplate processingPrimaryTemplate)
CodeGeneratorVariant(OutputFormatHelper &_outputFormatHelper)
CodeGenerator * operator->()
A special generator for coroutines. It is only activated, if -show-coroutines-transformation is given...
bool InsertVarDecl(const VarDecl *vd) override
CoroutinesCodeGenerator(OutputFormatHelper &_outputFormatHelper, const size_t posBeforeFunc)
std::string GetFrameName() const
CoroutinesCodeGenerator(OutputFormatHelper &_outputFormatHelper, const size_t posBeforeFunc, std::string_view fsmName, size_t suspendsCount, CoroutineASTData data)
bool SkipSpaceAfterVarDecl() override
bool EndScope(OutputFormatHelper &ofm, bool clear)
void Add(const VarDecl *decl)
bool Return(OutputFormatHelper &ofm)
void AddExtended(const VarDecl *decl, const ValueDecl *extending)
void StartScope(bool funcStart)
bool InsertSemi() override
OnceFalse mInsertComma
Insert the VarDecl only once.
MultiStmtDeclCodeGenerator(OutputFormatHelper &_outputFormatHelper, LambdaStackType &lambdaStack, bool insertVarDecl)
bool InsertVarDecl(const VarDecl *) override
bool InsertComma() override
~MultiStmtDeclCodeGenerator()
void PushVtableEntry(const CXXRecordDecl *record, const CXXRecordDecl *recordB, VarDecl *decl)
int GetGlobalVtablePos(const CXXRecordDecl *record, const CXXRecordDecl *recordB)
static FieldDecl * AddField(CoroutineASTData &astData, std::string_view name, QualType type)
Base class for StackList.
QualType vtableRecordType
CXXRecordDecl * vtableRecorDecl
FieldDecl * mInitialAwaitResumeCalledField
std::vector< const CXXThisExpr * > mThisExprs
FieldDecl * mPromiseField
FieldDecl * mResumeFnField
FieldDecl * mSuspendIndexField
MemberExpr * mSuspendIndexAccess
DeclRefExpr * mFrameAccessDeclRef
CXXRecordDecl * mFrameType
FieldDecl * mDestroyFnField
MemberExpr * mInitialAwaitResumeCalledAccess