54 std::uint8_t constBit = 0;
55 for (constBit = 0; constBit < modifier.
ptrLevel_; ++constBit)
72 return emit(cppObj, stm, indentation,
false);
79 case CppObjType::kHashDefine:
81 case CppObjType::kHashUndef:
83 case CppObjType::kHashInclude:
85 case CppObjType::kHashIf:
87 case CppObjType::kHashPragma:
90 case CppObjType::kVarType:
92 case CppObjType::kVar: {
98 case CppObjType::kVarList:
100 case CppObjType::kEnum:
102 case CppObjType::kDocComment:
104 case CppObjType::kUsingDecl:
106 case CppObjType::kTypedefName:
108 case CppObjType::kTypedefNameList:
110 case CppObjType::kCompound:
112 case CppObjType::kFwdClsDecl:
114 case CppObjType::kFunction:
116 case CppObjType::kConstructor:
118 case CppObjType::kDestructor:
120 case CppObjType::kTypeConverter:
122 case CppObjType::kFunctionPtr:
124 case CppObjType::kIfBlock:
126 case CppObjType::kWhileBlock:
128 case CppObjType::kDoWhileBlock:
130 case CppObjType::kForBlock:
132 case CppObjType::kExpression:
137 case CppObjType::kSwitchBlock:
139 case CppObjType::kMacroCall:
142 case CppObjType::kBlob:
153 if (!defObj->
defn_.empty())
155 const auto firstNonSpaceCharPos =
156 std::find_if(defObj->
defn_.begin(), defObj->
defn_.end(), [](
char c) { return !std::isspace(c); });
157 if (firstNonSpaceCharPos != defObj->
defn_.end())
159 if (*firstNonSpaceCharPos !=
'(')
161 stm << defObj->
defn_;
247 stm << blobObj->
blob_;
253 const auto attr = varTypeObj->
typeAttr() | (
isConst(varTypeObj) ? CppIdentifierAttrib::kConst : 0);
254 emitAttribute(attr, stm);
259 const auto& origTypeModifier = varTypeObj->
typeModifier();
261 origTypeModifier.
refType_, origTypeModifier.ptrLevel_, origTypeModifier.constBits_ & ~1};
262 emitTypeModifier(typeModifier, stm);
271 emitVar(varObj, stm, indentation,
false);
276 if (!skipName && !varDecl.
name().empty())
277 stm << varDecl.
name();
278 for (
const auto& arrSize : varDecl.
arraySizes())
285 if (varDecl.
assignType() == AssignType::kUsingEqual)
290 else if (varDecl.
assignType() == AssignType::kUsingBracket)
297 else if (varDecl.
assignType() == AssignType::kUsingBraces)
314 if (!skipName && !varObj->
name().empty())
323 for (
size_t i = 0; i < varDeclList.size(); ++i)
326 auto& decl = varDeclList[i];
327 emitTypeModifier(decl, stm);
336 stm << indentation <<
"enum";
339 if (!enmObj->
name_.empty())
340 stm <<
' ' << enmObj->
name_;
345 const bool isEnumBodyBlob = !enmObj->
itemList_->empty() && enmObj->
itemList_->front()->val_
351 stm <<
'\n' << indentation <<
'}';
356 stm << indentation++.
toString() <<
"{\n";
357 for (
auto enmItem : *(enmObj->
itemList_))
359 if (enmItem->name_.empty())
361 emit(enmItem->val_.get(), stm, indentation);
365 stm << indentation << enmItem->name_;
366 if (enmItem->val_ &&
isExpr(enmItem->val_.get()))
368 auto* expr =
static_cast<CppExpr*
>(enmItem->val_.get());
372 if (enmItem != enmObj->
itemList_->back())
378 stm << --indentation <<
"}";
389 stm << indentation <<
"typedef ";
400 stm << indentation <<
"using " << usingDecl->
name_;
413 stm << indentation <<
"typedef ";
426 if (fwdDeclObj->
cmpType_ != CppCompoundType::kUnknownCompound)
430 stm << fwdDeclObj->
name_ <<
";\n";
437 stm << indentation << macroCallObj->
macroCall_ <<
'\n';
442 stm << indentation <<
"template <";
445 const char* sep =
"";
446 for (
auto& param : *templSpec)
449 if (param->paramType_)
461 stm << param->paramName_;
462 if (param->defaultArg())
481 stm << indentation << compoundObj->
compoundType() <<
' ';
482 if (!compoundObj->
apidecor().empty())
483 stm << compoundObj->
apidecor() <<
' ';
484 stm << compoundObj->
name();
493 for (CppInheritanceList::const_iterator inhItr = compoundObj->
inheritanceList()->begin();
497 stm << sep <<
' ' << inhItr->inhType <<
' ' << inhItr->baseName;
503 stm <<
'\n' << indentation++.
toString() <<
"{\n";
504 else if (compoundObj->
compoundType() == CppCompoundType::kExternCBlock)
505 stm << indentation++.
toString() <<
"extern \"C\" {\n";
512 stm << --indentation << memObj->accessType_ <<
':' <<
'\n';
513 lastAccessType = memObj->accessType_;
516 emit(memObj, stm, indentation);
525 stm << --indentation;
534 else if (compoundObj->
compoundType() == CppCompoundType::kExternCBlock)
535 stm << indentation <<
"}\n";
545 for (
auto prmItr = paramListObj->begin(); prmItr != paramListObj->end(); ++prmItr)
547 if (prmItr != paramListObj->begin())
549 auto& param = *prmItr;
550 switch (param->objType_)
552 case CppObjType::kVar:
555 case CppObjType::kFunctionPtr:
569 bool emitNewLine)
const
576 if (!funcObj->
decor1().empty())
577 stm << funcObj->
decor1() <<
' ';
596 if (funcObj->
objType_ == CppObjType::kFunctionPtr)
600 if (!funcObj->
decor2().empty())
601 stm << funcObj->
decor2() <<
' ';
602 if (funcObj->
objType_ == CppObjType::kFunctionPtr)
606 stm << funcObj->
name_ <<
") ";
610 stm << funcObj->
name_;
633 const auto defn = funcObj->
defn();
634 if (defn->hasASingleBlobMember())
636 stm <<
'\n' << indentation++.
toString() <<
"{\n";
637 emitBlob((
CppBlob*) defn->members().front().get(), stm,
false, indentation);
638 stm <<
'\n' << --indentation <<
"}\n";
642 stm <<
'\n' << indentation++.
toString() <<
"{\n";
644 stm << --indentation <<
"}\n";
655 return emitFunction(funcObj, stm, indentation,
false,
false, emitNewLine);
664 stm << indentation <<
"typedef ";
671 bool skipParamName)
const
678 if (!ctorObj->
decor1().empty())
679 stm << ctorObj->
decor1() <<
' ';
684 stm << ctorObj->
name_;
696 stm << indentation << sep <<
' ';
704 stm << indentation << sep <<
' ' << memInit.first <<
'(';
712 if (!skipParamName && ctorObj->
defn())
714 stm <<
'\n' << indentation++.
toString() <<
"{\n";
716 stm << --indentation <<
"}\n";
738 if (!dtorObj->
decor1().empty())
739 stm << dtorObj->
decor1() <<
' ';
746 stm << dtorObj->
name_ <<
"()";
750 stm <<
'\n' << indentation++.
toString() <<
"{\n";
752 stm << --indentation <<
"}\n";
764 stm << indentation <<
"operator ";
771 if (typeConverterObj->
defn())
774 stm << indentation <<
"{\n";
778 stm << indentation <<
"}\n";
790 stm << docCommentObj->
doc_ <<
'\n';
928void CppWriter::emitExprAtom(CppExprAtom& exprAtm, std::ostream& stm, CppIndent indentation /*= CppIndent()*/) const
930 switch (exprAtm.type)
932 case CppExprAtom::kAtom:
933 stm << *(exprAtm.atom);
935 case CppExprAtom::kExpr:
936 emitExpr(exprAtm.expr, stm);
938 case CppExprAtom::kVarType:
939 emitVarType(exprAtm.varType, stm);
946void CppWriter::emitExpr(CppExpr* exprObj, std::ostream& stm, CppIndent indentation /*= CppIndent()*/) const
951 if (exprObj->flags_ & CppExpr::kReturn)
953 if (exprObj->flags_ & CppExpr::kThrow)
955 if (exprObj->flags_ & CppExpr::kInitializer)
957 if (exprObj->flags_ & CppExpr::kBracketed)
959 if (exprObj->flags_ & CppExpr::kNew)
961 if (exprObj->flags_ & CppExpr::kSizeOf)
963 else if (exprObj->flags_ & CppExpr::kDelete)
965 else if (exprObj->flags_ & CppExpr::kDeleteArray)
967 if (exprObj->oper_ == kNone)
969 emitExprAtom(exprObj->expr1_, stm);
971 else if (exprObj->oper_ > kUnariPrefixOperatorStart && exprObj->oper_ < kUnariSufixOperatorStart)
973 emitOperator(stm, exprObj->oper_);
974 emitExprAtom(exprObj->expr1_, stm);
976 else if (exprObj->oper_ > kUnariSufixOperatorStart && exprObj->oper_ < kBinaryOperatorStart)
978 emitExprAtom(exprObj->expr1_, stm);
979 emitOperator(stm, exprObj->oper_);
981 else if (exprObj->oper_ > kBinaryOperatorStart && exprObj->oper_ < kDerefOperatorStart)
983 emitExprAtom(exprObj->expr1_, stm);
984 if (exprObj->oper_ != kComma)
986 emitOperator(stm, exprObj->oper_);
988 emitExprAtom(exprObj->expr2_, stm);
990 else if (exprObj->oper_ > kDerefOperatorStart && exprObj->oper_ < kSpecialOperations)
992 emitExprAtom(exprObj->expr1_, stm);
993 emitOperator(stm, exprObj->oper_);
994 emitExprAtom(exprObj->expr2_, stm);
996 else if (exprObj->oper_ == kFunctionCall)
998 emitExprAtom(exprObj->expr1_, stm);
1000 emitExprAtom(exprObj->expr2_, stm);
1003 else if (exprObj->oper_ == kUniformInitCall)
1005 emitExprAtom(exprObj->expr1_, stm);
1007 emitExprAtom(exprObj->expr2_, stm);
1010 else if (exprObj->oper_ == kArrayElem)
1012 emitExprAtom(exprObj->expr1_, stm);
1014 emitExprAtom(exprObj->expr2_, stm);
1017 else if (exprObj->oper_ == kCStyleCast)
1020 emitExprAtom(exprObj->expr1_, stm);
1022 emitExprAtom(exprObj->expr2_, stm);
1024 else if (exprObj->oper_ >= kConstCast && exprObj->oper_ <= kReinterpretCast)
1026 if (exprObj->oper_ == kConstCast)
1027 stm << "const_cast";
1028 else if (exprObj->oper_ == kStaticCast)
1029 stm << "static_cast";
1030 else if (exprObj->oper_ == kDynamicCast)
1031 stm << "dynamic_cast";
1032 else if (exprObj->oper_ == kReinterpretCast)
1033 stm << "reinterpret_cast";
1035 emitExprAtom(exprObj->expr1_, stm);
1037 emitExprAtom(exprObj->expr2_, stm);
1040 else if (exprObj->oper_ == kTertiaryOperator)
1042 emitExprAtom(exprObj->expr1_, stm);
1044 emitExprAtom(exprObj->expr2_, stm);
1046 emitExprAtom(exprObj->expr3_, stm);
1048 else if (exprObj->oper_ == kPlacementNew)
1051 emitExprAtom(exprObj->expr1_, stm);
1053 emitExprAtom(exprObj->expr2_, stm);
1056 if (exprObj->flags_ & CppExpr::kBracketed)
1058 if (exprObj->flags_ & CppExpr::kInitializer)
1060 if (exprObj->flags_ & CppExpr::kSizeOf)
1063 if (exprObj->flags_ & CppExpr::kVariadicPack)
1067void CppWriter::emitIfBlock(CppIfBlock* ifBlock, std::ostream& stm, CppIndent indentation) const
1071 emit(ifBlock->cond_.get(), stm, CppIndent(), true);
1073 stm << indentation << "{\n";
1076 emit(ifBlock->body_.get(), stm, indentation);
1078 stm << indentation << "}\n";
1079 if (ifBlock->elsePart())
1081 stm << indentation << "else \n";
1082 stm << indentation << "{\n";
1084 emit(ifBlock->elsePart(), stm, indentation);
1086 stm << indentation << "}\n";
1090void CppWriter::emitWhileBlock(CppWhileBlock* whileBlock, std::ostream& stm, CppIndent indentation) const
1094 emit(whileBlock->cond_.get(), stm, CppIndent(), true);
1096 stm << indentation << "{\n";
1098 if (whileBlock->body_)
1099 emit(whileBlock->body_.get(), stm, indentation);
1101 stm << indentation << "}\n";
1104void CppWriter::emitDoBlock(CppDoWhileBlock* doBlock, std::ostream& stm, CppIndent indentation) const
1106 stm << indentation << "do\n";
1107 stm << indentation << "{\n";
1110 emit(doBlock->body_.get(), stm, indentation);
1112 stm << indentation << "} while (";
1113 emit(doBlock->cond_.get(), stm, CppIndent(), true);
1117void CppWriter::emitForBlock(CppForBlock* forBlock, std::ostream& stm, CppIndent indentation) const
1119 stm << indentation << "for (";
1120 if (forBlock->start_.get())
1121 emit(forBlock->start_.get(), stm, CppIndent(), true);
1123 if (forBlock->stop_)
1126 emitExpr(forBlock->stop_.get(), stm);
1129 if (forBlock->step_)
1132 emitExpr(forBlock->step_.get(), stm);
1135 stm << indentation << "{\n";
1137 if (forBlock->body_)
1138 emit(forBlock->body_.get(), stm, indentation);
1140 stm << indentation << "}\n";
1143void CppWriter::emitSwitchBlock(CppSwitchBlock* switchBlock, std::ostream& stm, CppIndent indentation) const
1145 stm << indentation << "switch(";
1146 emitExpr(switchBlock->cond_.get(), stm);
1148 stm << indentation++.toString() << "{\n";
1149 for (const auto& caseStmt : *(switchBlock->body_))
1153 stm << indentation++.toString() << "case ";
1154 emitExpr(caseStmt.case_.get(), stm);
1159 stm << "default:\n";
1162 emitCompound(caseStmt.body_.get(), stm, indentation);
1165 stm << --indentation << "}\n";
Helper class to manage indentation while writing C++ file from AST.
std::string toString() const
CppIndent resetted() const
virtual void emitMacroCall(CppMacroCall *macroCallObj, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitEnum(CppEnum *enmObj, std::ostream &stm, bool emitNewLine, CppIndent indentation=CppIndent()) const
virtual void emitFwdDecl(CppFwdClsDecl *fwdClsDeclObj, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitVarType(CppVarType *varTypeObj, std::ostream &stm) const
virtual void emitHashIf(CppHashIf *hashIfObj, std::ostream &stm) const
virtual void emitIfBlock(CppIfBlock *ifBlock, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitParamList(CppParamVector *paramListObj, std::ostream &stm) const
virtual void emitUsingDecl(CppUsingDecl *usingDecl, std::ostream &stm, CppIndent indentation=CppIndent()) const
@ kHeader
No function definition is emitted unless it is explicitly inline.
virtual void emitEndIf(std::ostream &stm) const
virtual void emitConstructor(CppConstructor *ctorObj, std::ostream &stm, CppIndent indentation=CppIndent()) const
EmittingType getEmittingType() const
void emitVarDecl(std::ostream &stm, CppVarDecl &varDecl, bool skipName) const
virtual void emitExpr(CppExpr *exprObj, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitDoBlock(CppDoWhileBlock *doBlock, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitSwitchBlock(CppSwitchBlock *switchBlock, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitInclude(CppInclude *includeObj, std::ostream &stm) const
virtual void emitTypeConverter(CppTypeConverter *typeConverterObj, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitDestructor(CppDestructor *dtorObj, std::ostream &stm, CppIndent indentation=CppIndent()) const
void emitTemplSpec(CppTemplateParamList *templSpec, std::ostream &stm, CppIndent indentation) const
virtual void emitTypedefList(CppTypedefList *typedefList, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitDefine(CppDefine *defineObj, std::ostream &stm) const
virtual void emitBlob(CppBlob *blobObj, std::ostream &stm, bool formatLineStarts, CppIndent indentation) const
virtual void emitDocComment(CppDocComment *docCommentObj, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitTypedef(CppTypedefName *typedefName, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitCompound(CppCompound *compoundObj, std::ostream &stm, CppIndent indentation=CppIndent(), bool emitNewLine=true) const
virtual void emitFunctionPtr(CppFunctionPointer *funcPtrObj, std::ostream &stm, bool emitNewLine, CppIndent indentation=CppIndent()) const
virtual void emitVarList(CppVarList *varListObj, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitPragma(CppPragma *pragmaObj, std::ostream &stm) const
virtual void emitUndef(CppUndef *undefObj, std::ostream &stm) const
virtual void emitForBlock(CppForBlock *forBlock, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitVar(CppVar *varObj, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitWhileBlock(CppWhileBlock *whileBlock, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emit(CppObj *cppObj, std::ostream &stm, CppIndent indentation=CppIndent()) const
virtual void emitFunction(CppFunction *funcObj, std::ostream &stm, bool emitNewLine, CppIndent indentation=CppIndent()) const
std::vector< std::unique_ptr< CppTemplateParam > > CppTemplateParamList
bool forEachMember(CppCompoundEPtr compound, std::function< bool(CppObj *)> visitor)
bool isDeleted(CppFunctionBase *func)
bool isConst(CppFunctionBase *func)
bool isClassLike(CppObj *cppObj)
bool isExpr(CppObj *cppObj)
bool isNamespaceLike(CppObj *cppObj)
std::vector< CppObjPtr > CppParamVector
void emitOperator(std::ostream &stm, CppOperator op)
static void emitAttribute(std::uint32_t attr, std::ostream &stm)
static void emitTypeModifier(CppTypeModifier &modifier, std::ostream &stm)
A stream of text that represents some content in a C++ program.
static constexpr CppObjType kObjectType
Some blocks have common structure like if, while, and do-while.
All classes, structs, unions, and namespaces can be classified as a Compound object.
CppTemplateParamList * templateParamList()
bool hasAttr(std::uint32_t _attr)
CppCompoundType compoundType()
CppInheritanceListPtr & inheritanceList()
std::string defn_
This will contain everything after name.
std::string underlyingType_
CppEnumItemListPtr itemList_
An expression in a C/C++ program.
CppParamVector * params()
bool hasAttr(std::uint32_t _attr)
CppTemplateParamList * templateParamList()
Function pointer type definition using typedef, e.g.
CppTemplateParamList * templateParamList()
Represents all variants of #if preprocessors.
std::list< CppMemInit > * memInitList
An abstract class that is used as base class of all other classes.
CppAccessType accessType_
All objects do not need this.
CppTemplateParamList * templateParamList()
CppArraySizes & arraySizes()
List of variables declared in a line without repeating its type, e.g.
CppVarDeclList & varDeclList()
CppTypeModifier & typeModifier()
static constexpr CppObjType kObjectType
Class to represent C++ variable definition.
CppTemplateParamList * templateParamList()