diff --git a/CodeGenerator.cpp b/CodeGenerator.cpp index 4c1964a5..14a10b47 100644 --- a/CodeGenerator.cpp +++ b/CodeGenerator.cpp @@ -7,8 +7,10 @@ #include "CodeGenerator.h" #include "DPrint.h" +#include "InsightsBase.h" #include "InsightsMatchers.h" #include "InsightsStrCat.h" +#include "NumberIterator.h" //----------------------------------------------------------------------------- /// \brief Convenience macro to create a \ref LambdaScopeHandler on the stack. @@ -18,6 +20,29 @@ namespace clang::insights { +static const char* AccessToString(const AccessSpecifier& access) +{ + switch(access) { + case AS_public: return "public"; + case AS_protected: return "protected"; + case AS_private: return "private"; + default: return ""; + } +} +//----------------------------------------------------------------------------- + +static std::string AccessToStringWithColon(const AccessSpecifier& access) +{ + return StrCat(AccessToString(access), ": "); +} +//----------------------------------------------------------------------------- + +static std::string AccessToStringWithColon(const CXXMethodDecl& decl) +{ + return AccessToStringWithColon(decl.getAccess()); +} +//----------------------------------------------------------------------------- + class ArrayInitCodeGenerator final : public CodeGenerator { const uint64_t mIndex; @@ -122,7 +147,7 @@ void CodeGenerator::InsertArg(const CXXForRangeStmt* rangeForStmt) } if(!isBodyBraced && !isa(body)) { - mOutputFormatHelper.AppendNewLine(";"); + mOutputFormatHelper.AppendNewLine(';'); } // close range-for scope in for @@ -156,12 +181,11 @@ void CodeGenerator::InsertArg(const DoStmt* stmt) InsertArg(body); if(isa(body)) { - mOutputFormatHelper.Append(" "); + mOutputFormatHelper.Append(' '); } - mOutputFormatHelper.Append("while( "); - InsertArg(stmt->getCond()); - mOutputFormatHelper.Append(" )"); + mOutputFormatHelper.Append("while"); + WrapInParensOrCurlys(BraceKind::Parens, [&]() { InsertArg(stmt->getCond()); }, AddSpaceAtTheEnd::Yes); } //----------------------------------------------------------------------------- @@ -204,11 +228,9 @@ void CodeGenerator::InsertArg(const SwitchStmt* stmt) } } - mOutputFormatHelper.Append("switch("); - - InsertArg(stmt->getCond()); + mOutputFormatHelper.Append("switch"); - mOutputFormatHelper.Append(") "); + WrapInParensOrCurlys(BraceKind::Parens, [&]() { InsertArg(stmt->getCond()); }, AddSpaceAtTheEnd::Yes); InsertArg(stmt->getBody()); @@ -220,9 +242,8 @@ void CodeGenerator::InsertArg(const SwitchStmt* stmt) void CodeGenerator::InsertArg(const WhileStmt* stmt) { - mOutputFormatHelper.Append("while("); - InsertArg(stmt->getCond()); - mOutputFormatHelper.Append(") "); + mOutputFormatHelper.Append("while"); + WrapInParensOrCurlys(BraceKind::Parens, [&]() { InsertArg(stmt->getCond()); }, AddSpaceAtTheEnd::Yes); InsertArg(stmt->getBody()); } @@ -291,9 +312,14 @@ void CodeGenerator::InsertArg(const FloatingLiteral* stmt) void CodeGenerator::InsertArg(const CXXTypeidExpr* stmt) { - mOutputFormatHelper.Append("typeid("); - InsertArg(stmt->getExprOperand()); - mOutputFormatHelper.Append(")"); + mOutputFormatHelper.Append("typeid"); + WrapInParensOrCurlys(BraceKind::Parens, [&]() { + if(stmt->isTypeOperand()) { + mOutputFormatHelper.Append(GetName(stmt->getType())); + } else { + InsertArg(stmt->getExprOperand()); + } + }); } //----------------------------------------------------------------------------- @@ -375,7 +401,7 @@ void CodeGenerator::InsertArg(const DecompositionDecl* decompositionDeclStmt) InsertArg(decompositionDeclStmt->getInit()); - mOutputFormatHelper.AppendNewLine(";"); + mOutputFormatHelper.AppendNewLine(';'); const bool isRefToObject = IsReference(*decompositionDeclStmt); @@ -422,12 +448,36 @@ void CodeGenerator::InsertArg(const DecompositionDecl* decompositionDeclStmt) TODO(bindingDecl, mOutputFormatHelper); } - mOutputFormatHelper.AppendNewLine(";"); + mOutputFormatHelper.AppendNewLine(';'); } } } //----------------------------------------------------------------------------- +static std::string GetQualifiers(const VarDecl& vd) +{ + std::string qualifiers{}; + + if(vd.isInline()) { + qualifiers += "inline "; + } + + if(SC_Extern == vd.getStorageClass()) { + qualifiers += "extern "; + } + + if(SC_Static == vd.getStorageClass()) { + qualifiers += "static "; + } + + if(vd.isConstexpr()) { + qualifiers += "constexpr "; + } + + return qualifiers; +} +//----------------------------------------------------------------------------- + void CodeGenerator::InsertArg(const VarDecl* stmt) { LAMBDA_SCOPE_HELPER(VarDecl); @@ -438,12 +488,14 @@ void CodeGenerator::InsertArg(const VarDecl* stmt) HandleLocalStaticNonTrivialClass(stmt); } else { + mOutputFormatHelper.Append(GetQualifiers(*stmt)); + if(const auto type = stmt->getType(); type->isFunctionPointerType()) { const auto lineNo = GetSM(*stmt).getSpellingLineNumber(stmt->getSourceRange().getBegin()); const std::string funcPtrName{StrCat("FuncPtr_", std::to_string(lineNo), " ")}; mOutputFormatHelper.AppendNewLine("using ", funcPtrName, "= ", GetName(type), ";"); - mOutputFormatHelper.Append((stmt->isConstexpr() ? kwConstExprSpace : ""), funcPtrName, GetName(*stmt)); + mOutputFormatHelper.Append(funcPtrName, GetName(*stmt)); } else { mOutputFormatHelper.Append(GetTypeNameAsParameter(stmt->getType(), GetName(*stmt))); } @@ -465,25 +517,52 @@ void CodeGenerator::InsertArg(const VarDecl* stmt) void CodeGenerator::InsertArg(const InitListExpr* stmt) { - mOutputFormatHelper.Append("{ "); - mOutputFormatHelper.IncreaseIndent(); + WrapInParensOrCurlys(BraceKind::Curlys, [&]() { + mOutputFormatHelper.IncreaseIndent(); - ForEachArg(stmt->inits(), [&](const auto& init) { InsertArg(init); }); + ForEachArg(stmt->inits(), [&](const auto& init) { InsertArg(init); }); + }); - mOutputFormatHelper.Append(" }"); mOutputFormatHelper.DecreaseIndent(); } //----------------------------------------------------------------------------- -void CodeGenerator::InsertArg(const CXXConstructExpr* stmt) +void CodeGenerator::InsertArg(const CXXDefaultInitExpr* stmt) +{ + InsertArg(stmt->getExpr()); +} +//----------------------------------------------------------------------------- + +void CodeGenerator::InsertArg(const CXXDeleteExpr* stmt) { - mOutputFormatHelper.Append(GetName(GetDesugarType(stmt->getType()), Unqualified::Yes), "("); + mOutputFormatHelper.Append("delete"); - if(stmt->getNumArgs()) { - ForEachArg(stmt->arguments(), [&](const auto& arg) { InsertArg(arg); }); + if(stmt->isArrayForm()) { + mOutputFormatHelper.Append("[]"); } - mOutputFormatHelper.Append(')'); + mOutputFormatHelper.Append(' '); + + InsertArg(stmt->getArgument()); +} +//----------------------------------------------------------------------------- + +void CodeGenerator::InsertArg(const CXXConstructExpr* stmt) +{ + mOutputFormatHelper.Append(GetName(GetDesugarType(stmt->getType()), Unqualified::Yes)); + + const BraceKind braceKind = [&]() { + if(stmt->isListInitialization()) { + return BraceKind::Curlys; + } + return BraceKind::Parens; + }(); + + WrapInParensOrCurlys(braceKind, [&]() { + if(stmt->getNumArgs()) { + ForEachArg(stmt->arguments(), [&](const auto& arg) { InsertArg(arg); }); + } + }); } //----------------------------------------------------------------------------- @@ -492,21 +571,15 @@ void CodeGenerator::InsertArg(const CXXMemberCallExpr* stmt) LAMBDA_SCOPE_HELPER(MemberCallExpr); InsertArg(stmt->getCallee()); - mOutputFormatHelper.Append('('); - - ForEachArg(stmt->arguments(), [&](const auto& arg) { InsertArg(arg); }); - mOutputFormatHelper.Append(')'); + WrapInParensOrCurlys(BraceKind::Parens, + [&]() { ForEachArg(stmt->arguments(), [&](const auto& arg) { InsertArg(arg); }); }); } //----------------------------------------------------------------------------- void CodeGenerator::InsertArg(const ParenExpr* stmt) { - mOutputFormatHelper.Append('('); - - InsertArg(stmt->getSubExpr()); - - mOutputFormatHelper.Append(')'); + WrapInParensOrCurlys(BraceKind::Parens, [&]() { InsertArg(stmt->getSubExpr()); }); } //----------------------------------------------------------------------------- @@ -547,31 +620,22 @@ void CodeGenerator::InsertArg(const ArraySubscriptExpr* stmt) { InsertArg(stmt->getLHS()); - mOutputFormatHelper.Append("["); + mOutputFormatHelper.Append('['); InsertArg(stmt->getRHS()); - mOutputFormatHelper.Append("]"); + mOutputFormatHelper.Append(']'); } //----------------------------------------------------------------------------- void CodeGenerator::InsertArg(const ArrayInitLoopExpr* stmt) { - mOutputFormatHelper.Append("{ "); - - const uint64_t size = stmt->getArraySize().getZExtValue(); - bool first{true}; - - for(uint64_t i = 0; i < size; ++i) { - if(!first) { - mOutputFormatHelper.Append(", "); - } else { - first = false; - } - - ArrayInitCodeGenerator codeGenerator{mOutputFormatHelper, i}; - codeGenerator.InsertArg(stmt->getSubExpr()); - } + WrapInParensOrCurlys(BraceKind::Curlys, [&]() { + const uint64_t size = stmt->getArraySize().getZExtValue(); - mOutputFormatHelper.Append(" }"); + ForEachArg(NumberIterator(size), [&](const auto& i) { + ArrayInitCodeGenerator codeGenerator{mOutputFormatHelper, i}; + codeGenerator.InsertArg(stmt->getSubExpr()); + }); + }); } //----------------------------------------------------------------------------- @@ -608,11 +672,8 @@ void CodeGenerator::InsertArg(const CallExpr* stmt) } } - mOutputFormatHelper.Append('('); - - ForEachArg(stmt->arguments(), [&](const auto& arg) { InsertArg(arg); }); - - mOutputFormatHelper.Append(')'); + WrapInParensOrCurlys(BraceKind::Parens, + [&]() { ForEachArg(stmt->arguments(), [&](const auto& arg) { InsertArg(arg); }); }); } //----------------------------------------------------------------------------- @@ -672,7 +733,7 @@ void CodeGenerator::HandleCompoundStmt(const CompoundStmt* stmt) InsertArg(item); if(!isa(item) && !isa(item) && !isa(item)) { - mOutputFormatHelper.AppendNewLine(";"); + mOutputFormatHelper.AppendNewLine(';'); } } } @@ -695,11 +756,9 @@ void CodeGenerator::InsertArg(const IfStmt* stmt) } } - mOutputFormatHelper.Append("if", cexpr, "( "); - - InsertArg(stmt->getCond()); + mOutputFormatHelper.Append("if", cexpr); - mOutputFormatHelper.Append(" ) "); + WrapInParensOrCurlys(BraceKind::Parens, [&]() { InsertArg(stmt->getCond()); }, AddSpaceAtTheEnd::Yes); const auto* body = stmt->getThen(); @@ -744,21 +803,25 @@ void CodeGenerator::InsertArg(const IfStmt* stmt) void CodeGenerator::InsertArg(const ForStmt* stmt) { - mOutputFormatHelper.Append("for("); + mOutputFormatHelper.Append("for"); - if(const auto* init = stmt->getInit()) { - // the init-stmt carries a ; at the end - InsertArg(init); - } else { - mOutputFormatHelper.Append("; "); - } + WrapInParensOrCurlys(BraceKind::Parens, + [&]() { + if(const auto* init = stmt->getInit()) { + // the init-stmt carries a ; at the end + InsertArg(init); + } else { + mOutputFormatHelper.Append("; "); + } - InsertArg(stmt->getCond()); - mOutputFormatHelper.Append("; "); + InsertArg(stmt->getCond()); + mOutputFormatHelper.Append("; "); - InsertArg(stmt->getInc()); + InsertArg(stmt->getInc()); + }, + AddSpaceAtTheEnd::Yes); - mOutputFormatHelper.AppendNewLine(')'); + mOutputFormatHelper.AppendNewLine(); InsertArg(stmt->getBody()); mOutputFormatHelper.AppendNewLine(); @@ -781,11 +844,9 @@ void CodeGenerator::InsertArg(const CXXNewExpr* stmt) if(stmt->getNumPlacementArgs()) { /* we have a placement new */ - mOutputFormatHelper.Append('('); - - ForEachArg(stmt->placement_arguments(), [&](const auto& placementArg) { InsertArg(placementArg); }); - - mOutputFormatHelper.Append(')'); + WrapInParensOrCurlys(BraceKind::Parens, [&]() { + ForEachArg(stmt->placement_arguments(), [&](const auto& placementArg) { InsertArg(placementArg); }); + }); } Dump(stmt); @@ -794,14 +855,17 @@ void CodeGenerator::InsertArg(const CXXNewExpr* stmt) if(const auto* ctorExpr = stmt->getConstructExpr()) { InsertArg(ctorExpr); - } else if(stmt->isArray()) { - mOutputFormatHelper.Append(GetName(stmt->getAllocatedType()), "["); + } else { + mOutputFormatHelper.Append(GetName(stmt->getAllocatedType())); - InsertArg(stmt->getArraySize()); - mOutputFormatHelper.Append(']'); + if(stmt->isArray()) { + mOutputFormatHelper.Append('['); + InsertArg(stmt->getArraySize()); + mOutputFormatHelper.Append(']'); + } if(stmt->hasInitializer()) { - InsertArg(stmt->getInitializer()); + InsertCurlysIfRequired(stmt->getInitializer()); } } } @@ -998,6 +1062,201 @@ void CodeGenerator::InsertArg(const TypedefDecl* stmt) } //----------------------------------------------------------------------------- +void CodeGenerator::InsertArg(const CXXMethodDecl* stmt) +{ + InsertAccessModifierAndNameWithReturnType(mOutputFormatHelper, *stmt, SkipConstexpr::No, SkipAccess::Yes); + + if(stmt->isDefaulted()) { + mOutputFormatHelper.AppendNewLine(" = default;"); + } else if(stmt->isDeleted()) { + mOutputFormatHelper.AppendNewLine(" = delete;"); + } + + if(!stmt->isUserProvided()) { + return; + } + + if(const auto* ctor = dyn_cast_or_null(stmt)) { + bool first = true; + + for(const auto* init : ctor->inits()) { + mOutputFormatHelper.AppendNewLine(); + if(first) { + first = false; + mOutputFormatHelper.Append(": "); + } else { + mOutputFormatHelper.Append(", "); + } + + // in case of delegating or base initializer there is no member. + if(const auto* member = init->getMember()) { + mOutputFormatHelper.Append(member->getNameAsString()); + InsertCurlysIfRequired(init->getInit()); + } else { + InsertArg(init->getInit()); + } + } + } + + if(stmt->hasBody()) { + mOutputFormatHelper.AppendNewLine(); + InsertArg(stmt->getBody()); + mOutputFormatHelper.AppendNewLine(); + } else { + mOutputFormatHelper.AppendNewLine(';'); + } + + mOutputFormatHelper.AppendNewLine(); +} +//----------------------------------------------------------------------------- + +void CodeGenerator::InsertArg(const FieldDecl* stmt) +{ + mOutputFormatHelper.AppendNewLine(GetName(stmt->getType()), " ", GetName(*stmt), ";"); +} +//----------------------------------------------------------------------------- + +void CodeGenerator::InsertArg(const AccessSpecDecl* stmt) +{ + mOutputFormatHelper.AppendNewLine(); + mOutputFormatHelper.AppendNewLine(AccessToStringWithColon(stmt->getAccess())); +} +//----------------------------------------------------------------------------- + +void CodeGenerator::InsertArg(const StaticAssertDecl* stmt) +{ + if(!stmt->isFailed()) { + mOutputFormatHelper.Append("/* PASSED: "); + } else { + mOutputFormatHelper.Append("/* FAILED: "); + } + + mOutputFormatHelper.Append("static_assert("); + + InsertArg(stmt->getAssertExpr()); + + if(stmt->getMessage()) { + mOutputFormatHelper.Append(", "); + InsertArg(stmt->getMessage()); + } + + mOutputFormatHelper.AppendNewLine("); */"); +} +//----------------------------------------------------------------------------- + +void CodeGenerator::InsertArg(const UsingDecl* stmt) +{ + mOutputFormatHelper.Append("using "); + + if(const DeclContext* Ctx = stmt->getDeclContext()) { + bool isFunctionOrMethod{false}; + + if(!Ctx->isFunctionOrMethod()) { + + using ContextsTy = SmallVector; + ContextsTy Contexts; + + while(Ctx) { + if(isa(Ctx)) { + Contexts.push_back(Ctx); + } + Ctx = Ctx->getParent(); + } + + for(const auto* DC : llvm::reverse(Contexts)) { + if(const auto* Spec = dyn_cast(DC)) { + mOutputFormatHelper.Append(Spec->getName()); + InsertTemplateArgs(*Spec); + + } else if(const auto* ND = dyn_cast(DC)) { + if(ND->isAnonymousNamespace() || ND->isInline()) { + continue; + } + + mOutputFormatHelper.Append(ND->getNameAsString()); + + } else if(const auto* RD = dyn_cast(DC)) { + if(RD->getIdentifier()) { + mOutputFormatHelper.Append(RD->getNameAsString()); + } + + } else if(const auto* FD = dyn_cast(DC)) { + InsightsBase::GenerateFunctionPrototype(mOutputFormatHelper, *FD); + + } else if(const auto* ED = dyn_cast(DC)) { + if(!ED->isScoped()) { + continue; + } + + mOutputFormatHelper.Append(ED->getNameAsString()); + + } else { + mOutputFormatHelper.Append(cast(DC)->getNameAsString()); + } + + mOutputFormatHelper.Append("::"); + } + } else { + isFunctionOrMethod = true; + } + + if(isFunctionOrMethod || stmt->getDeclName() || isa(stmt)) { + mOutputFormatHelper.Append(stmt->getNameAsString()); + } + } + + mOutputFormatHelper.AppendNewLine(';'); +} +//----------------------------------------------------------------------------- + +void CodeGenerator::InsertArg(const CXXRecordDecl* stmt) +{ + // skip classes/struct's without a definition + if(!stmt->hasDefinition()) { + return; + } + + if(stmt->isClass()) { + mOutputFormatHelper.Append(kwClassSpace); + + } else { + mOutputFormatHelper.Append("struct "); + } + + mOutputFormatHelper.Append(GetName(*stmt)); + + if(const auto* clsTmpl = dyn_cast_or_null(stmt)) { + InsertTemplateArgs(*clsTmpl); + } + + if(stmt->getNumBases()) { + mOutputFormatHelper.Append(" : "); + + ForEachArg(stmt->bases(), [&](const auto& base) { + mOutputFormatHelper.Append(AccessToString(base.getAccessSpecifier()), " ", GetName(base.getType())); + }); + } + + mOutputFormatHelper.AppendNewLine(); + + mOutputFormatHelper.OpenScope(); + + bool firstRecordDecl{true}; + for(const auto* d : stmt->decls()) { + if(isa(d) && firstRecordDecl) { + firstRecordDecl = false; + continue; + } + + InsertArg(d); + } + + mOutputFormatHelper.CloseScopeWithSemi(); + mOutputFormatHelper.AppendNewLine(); + mOutputFormatHelper.AppendNewLine(); +} +//----------------------------------------------------------------------------- + void CodeGenerator::InsertArg(const DeclStmt* stmt) { for(const auto* decl : stmt->decls()) { @@ -1022,7 +1281,7 @@ void CodeGenerator::InsertArg(const ReturnStmt* stmt) mOutputFormatHelper.Append(' '); InsertArg(retVal); } -} // namespace clang::insights +} //----------------------------------------------------------------------------- void CodeGenerator::InsertArg(const NullStmt* /*stmt*/) @@ -1066,6 +1325,8 @@ void CodeGenerator::InsertArg(const Decl* stmt) return; \ } +#define IGNORED_DECL SUPPORTED_DECL + #include "CodeGeneratorTypes.h" TODO(stmt, mOutputFormatHelper); @@ -1085,9 +1346,9 @@ void CodeGenerator::InsertArg(const Stmt* stmt) return; \ } -#include "CodeGeneratorTypes.h" +#define IGNORED_STMT SUPPORTED_STMT - // PackExpansionExpr +#include "CodeGeneratorTypes.h" TODO(stmt, mOutputFormatHelper); } @@ -1567,7 +1828,7 @@ void CodeGenerator::HandleLambdaExpr(const LambdaExpr* lambda, LambdaHelper& lam ctor.append(StrCat(" _", varName)); outputFormatHelper.AppendNewLine(" ", varName, ";"); } else { - outputFormatHelper.AppendNewLine(";"); + outputFormatHelper.AppendNewLine(';'); } ctorInits.append(StrCat(varName, "{_", varName, "}")); @@ -1592,27 +1853,19 @@ void CodeGenerator::HandleLambdaExpr(const LambdaExpr* lambda, LambdaHelper& lam mLambdaStack.back().inits().append(inits); } - outputFormatHelper.AppendNewLine(";"); + outputFormatHelper.AppendNewLine(';'); outputFormatHelper.AppendNewLine(); } //----------------------------------------------------------------------------- -static const char* AccessToString(const CXXMethodDecl& decl) -{ - switch(decl.getAccess()) { - case AS_public: return "public"; - case AS_protected: return "protected"; - case AS_private: return "private"; - default: return ""; - } -} -//----------------------------------------------------------------------------- - void CodeGenerator::InsertAccessModifierAndNameWithReturnType(OutputFormatHelper& outputFormatHelper, const CXXMethodDecl& decl, - SkipConstexpr skipConstexpr) + const SkipConstexpr skipConstexpr, + const SkipAccess skipAccess) { - outputFormatHelper.Append(AccessToString(decl), ": "); + if(SkipAccess::No == skipAccess) { + outputFormatHelper.Append(AccessToStringWithColon(decl)); + } // types of conversion decls can be invalid to type at this place. So introduce a using if(isa(decl)) { @@ -1664,6 +1917,45 @@ void CodeGenerator::InsertAccessModifierAndNameWithReturnType(OutputFormatHelper } //----------------------------------------------------------------------------- +void CodeGenerator::InsertCurlysIfRequired(const Stmt* stmt) +{ + const bool requiresCurlys{!isa(stmt) && !isa(stmt) && !isa(stmt)}; + + if(requiresCurlys) { + mOutputFormatHelper.Append('{'); + } + + InsertArg(stmt); + + if(requiresCurlys) { + mOutputFormatHelper.Append('}'); + } +} +//----------------------------------------------------------------------------- + +template +void CodeGenerator::WrapInParensOrCurlys(const BraceKind braceKind, T&& lambda, const AddSpaceAtTheEnd addSpaceAtTheEnd) +{ + if(BraceKind::Curlys == braceKind) { + mOutputFormatHelper.Append('{'); + } else { + mOutputFormatHelper.Append('('); + } + + lambda(); + + if(BraceKind::Curlys == braceKind) { + mOutputFormatHelper.Append('}'); + } else { + mOutputFormatHelper.Append(')'); + } + + if(AddSpaceAtTheEnd::Yes == addSpaceAtTheEnd) { + mOutputFormatHelper.Append(' '); + } +} +//----------------------------------------------------------------------------- + void StructuredBindingsCodeGenerator::InsertArg(const DeclRefExpr* stmt) { const auto name = GetName(*stmt); diff --git a/CodeGenerator.h b/CodeGenerator.h index 3d35bae1..7ba03785 100644 --- a/CodeGenerator.h +++ b/CodeGenerator.h @@ -105,6 +105,8 @@ class CodeGenerator virtual ~CodeGenerator() = default; +#define IGNORED_DECL(type) \ + virtual void InsertArg(const type*) {} #define IGNORED_STMT(type) \ virtual void InsertArg(const type*) {} #define SUPPORTED_DECL(type) virtual void InsertArg(const type* stmt); @@ -126,10 +128,12 @@ class CodeGenerator } STRONG_BOOL(SkipConstexpr); + STRONG_BOOL(SkipAccess); static void InsertAccessModifierAndNameWithReturnType(OutputFormatHelper& outputFormatHelper, const CXXMethodDecl& decl, - SkipConstexpr skipConstexpr = SkipConstexpr::No); + const SkipConstexpr skipConstexpr = SkipConstexpr::No, + const SkipAccess skipAccess = SkipAccess::No); protected: void HandleCharacterLiteral(const CharacterLiteral& stmt); @@ -160,6 +164,22 @@ class CodeGenerator void InsertTemplateArgs(const ArrayRef& array); void InsertTemplateArg(const TemplateArgument& arg); + /// \brief Check whether or not this statement will add curlys or parentheses and add them only if required. + void InsertCurlysIfRequired(const Stmt* stmt); + + STRONG_BOOL(AddSpaceAtTheEnd); + + enum class BraceKind + { + Parens, + Curlys + }; + + template + void WrapInParensOrCurlys(const BraceKind curlys, + T&& lambda, + const AddSpaceAtTheEnd addSpaceAtTheEnd = AddSpaceAtTheEnd::No); + static const char* GetKind(const UnaryExprOrTypeTraitExpr& uk); static const char* GetOpcodeName(const int kind); static const char* GetBuiltinTypeSuffix(const BuiltinType& type); diff --git a/CodeGeneratorTypes.h b/CodeGeneratorTypes.h index e0a13b32..0beaa514 100644 --- a/CodeGeneratorTypes.h +++ b/CodeGeneratorTypes.h @@ -17,13 +17,22 @@ IGNORED_STMT(OMPOrderedDirective) IGNORED_STMT(OMPParallelForDirective) -IGNORED_DECL(StaticAssertDecl) +IGNORED_DECL(UsingShadowDecl) +IGNORED_DECL(UsingPackDecl) SUPPORTED_DECL(DecompositionDecl) SUPPORTED_DECL(VarDecl) SUPPORTED_DECL(TypeAliasDecl) SUPPORTED_DECL(TypedefDecl) +SUPPORTED_DECL(StaticAssertDecl) +SUPPORTED_DECL(FieldDecl) +SUPPORTED_DECL(AccessSpecDecl) +SUPPORTED_DECL(CXXMethodDecl) +SUPPORTED_DECL(UsingDecl) +SUPPORTED_DECL(CXXRecordDecl) +SUPPORTED_STMT(CXXDeleteExpr) +SUPPORTED_STMT(CXXDefaultInitExpr) SUPPORTED_STMT(MemberExpr) SUPPORTED_STMT(IntegerLiteral) SUPPORTED_STMT(StringLiteral) diff --git a/InsightsBase.h b/InsightsBase.h index 45325d80..1fcd9f33 100644 --- a/InsightsBase.h +++ b/InsightsBase.h @@ -33,8 +33,10 @@ class InsightsBase STRONG_BOOL(SkipConstexpr); +public: static void GenerateFunctionPrototype(OutputFormatHelper& outputFormatHelper, const FunctionDecl& FD); +protected: bool SkipIfAlreadySeen(const Stmt* stmt); private: diff --git a/NumberIterator.h b/NumberIterator.h new file mode 100644 index 00000000..87535964 --- /dev/null +++ b/NumberIterator.h @@ -0,0 +1,34 @@ +#ifndef INSIGHTS_NUMBER_ITERATOR_H +#define INSIGHTS_NUMBER_ITERATOR_H + +template +class NumberIterator +{ +public: + NumberIterator(const T num) + : mNum{num} + , mCount{0} + { + } + + const T& operator*() const { return mCount; } + + NumberIterator& operator++() + { + ++mCount; + + return *this; + } + + bool operator!=(const NumberIterator&) const { return mCount < mNum; } + + const NumberIterator& begin() const { return *this; } + const NumberIterator& end() const { return *this; } + +private: + const T mNum; + T mCount; +}; +//----------------------------------------------------------------------------- + +#endif /* INSIGHTS_NUMBER_ITERATOR_H */ diff --git a/StaticAssertHandler.cpp b/StaticAssertHandler.cpp index d7a7122a..cc12fffc 100644 --- a/StaticAssertHandler.cpp +++ b/StaticAssertHandler.cpp @@ -6,6 +6,7 @@ ****************************************************************************/ #include "StaticAssertHandler.h" +#include "CodeGenerator.h" #include "InsightsHelpers.h" #include "InsightsMatchers.h" #include "InsightsStaticStrings.h" @@ -30,17 +31,15 @@ StaticAssertHandler::StaticAssertHandler(Rewriter& rewrite, MatchFinder& matcher void StaticAssertHandler::run(const MatchFinder::MatchResult& result) { - const auto* matchedDecl = result.Nodes.getNodeAs("static_assert"); - const std::string passFailed = [&]() { - if(!matchedDecl->isFailed()) { - return "/* PASSED: "; - } + if(const auto* matchedDecl = result.Nodes.getNodeAs("static_assert")) { + OutputFormatHelper outputFormatHelper{}; + CodeGenerator codeGenerator{outputFormatHelper}; + codeGenerator.InsertArg(matchedDecl); - return "/* FAILED: "; - }(); + const auto sr = GetSourceRangeAfterToken(matchedDecl->getSourceRange(), tok::semi, result); - mRewrite.InsertText(matchedDecl->getLocStart(), passFailed); - mRewrite.InsertTextAfterToken(matchedDecl->getLocEnd(), "*/"); + mRewrite.ReplaceText(sr, outputFormatHelper.GetString()); + } } //----------------------------------------------------------------------------- diff --git a/TemplateHandler.cpp b/TemplateHandler.cpp index 2b351d7d..d7df0821 100644 --- a/TemplateHandler.cpp +++ b/TemplateHandler.cpp @@ -44,6 +44,10 @@ void TemplateHandler::run(const MatchFinder::MatchResult& result) InsertInstantiatedTemplate(*functionDecl, result); } else if(const auto* clsTmplSpecDecl = result.Nodes.getNodeAs("class")) { + // skip classes/struct's without a definition + if(!clsTmplSpecDecl->hasDefinition()) { + return; + } OutputFormatHelper outputFormatHelper{}; outputFormatHelper.AppendNewLine(); @@ -53,19 +57,9 @@ void TemplateHandler::run(const MatchFinder::MatchResult& result) outputFormatHelper.AppendNewLine("#ifdef INSIGHTS_USE_TEMPLATE"); - outputFormatHelper.Append(kwClassSpace, GetName(*clsTmplSpecDecl)); - CodeGenerator codeGenerator{outputFormatHelper}; - codeGenerator.InsertTemplateArgs(*clsTmplSpecDecl); - - outputFormatHelper.AppendNewLine(); - - outputFormatHelper.OpenScope(); + codeGenerator.InsertArg(clsTmplSpecDecl); - outputFormatHelper.CloseScopeWithSemi(); - outputFormatHelper.AppendNewLine(); - - outputFormatHelper.AppendNewLine(); outputFormatHelper.AppendNewLine("#endif"); const auto* clsTmplDecl = result.Nodes.getNodeAs("decl"); diff --git a/scripts/travis_install.sh b/scripts/travis_install.sh index 6aea5581..9c6da013 100755 --- a/scripts/travis_install.sh +++ b/scripts/travis_install.sh @@ -2,6 +2,7 @@ if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then export HOMEBREW_NO_AUTO_UPDATE=1 + brew update > /dev/null brew install cmake || brew upgrade cmake brew install xz || brew upgrade xz diff --git a/tests/AutoHandler5Test.cpp b/tests/AutoHandler5Test.cpp new file mode 100644 index 00000000..74c509c8 --- /dev/null +++ b/tests/AutoHandler5Test.cpp @@ -0,0 +1,10 @@ +int foo(int a,int b){ return a+b; } + +int main(){ + if(true) { + int (*add)(int,int)= foo; + // auto within a function pointer + auto add1= foo; + } +} + diff --git a/tests/AutoHandler5Test.expect b/tests/AutoHandler5Test.expect new file mode 100644 index 00000000..41e055a9 --- /dev/null +++ b/tests/AutoHandler5Test.expect @@ -0,0 +1,12 @@ +int foo(int a,int b){ return a+b; } + +int main(){ + if(true) { + using FuncPtr_5 = int (*)(int, int); + FuncPtr_5 add = foo; + using FuncPtr_7 = int (*)(int, int); + FuncPtr_7 add1 = foo; + } + +} + diff --git a/tests/CXXDefaultInitExprTest.cpp b/tests/CXXDefaultInitExprTest.cpp new file mode 100644 index 00000000..f8ff9198 --- /dev/null +++ b/tests/CXXDefaultInitExprTest.cpp @@ -0,0 +1,18 @@ +template +class Alloc +{ + const int z; + T* data{nullptr}; + const bool x{false}; + +public: + Alloc() : z{2} + { + } +}; + +int main() +{ + Alloc a; + Alloc b; +} diff --git a/tests/CXXDefaultInitExprTest.expect b/tests/CXXDefaultInitExprTest.expect new file mode 100644 index 00000000..158da454 --- /dev/null +++ b/tests/CXXDefaultInitExprTest.expect @@ -0,0 +1,64 @@ +template +class Alloc +{ + const int z; + T* data{nullptr}; + const bool x{false}; + +public: + Alloc() : z{2} + { + } +}; +/* First instantiated from: CXXDefaultInitExprTest.cpp:16 */ +#ifdef INSIGHTS_USE_TEMPLATE +class Alloc +{ + const int z; + int * data; + const bool x; + + public: + inline Alloc() + : z{2} + , data{nullptr} + , x{false} + { + } + + inline constexpr Alloc(const Alloc &) = default; + inline constexpr Alloc(Alloc &&) = default; + +}; + +#endif + +/* First instantiated from: CXXDefaultInitExprTest.cpp:17 */ +#ifdef INSIGHTS_USE_TEMPLATE +class Alloc +{ + const int z; + char * data; + const bool x; + + public: + inline Alloc() + : z{2} + , data{nullptr} + , x{false} + { + } + + inline constexpr Alloc(const Alloc &) = default; + inline constexpr Alloc(Alloc &&) = default; + +}; + +#endif + + +int main() +{ + Alloc a; + Alloc b; +} diff --git a/tests/CXXDestructorTest.cpp b/tests/CXXDestructorTest.cpp new file mode 100644 index 00000000..68ef0510 --- /dev/null +++ b/tests/CXXDestructorTest.cpp @@ -0,0 +1,31 @@ +template +class Alloc +{ + T* data; + +public: + Alloc() { + if( array ) { + data = new T[10]; + data = new T[10]{1,2,3}; + } else { + data = new T; + data = new T(2); + data = new T{2}; + } + } + + ~Alloc() { + if( array ) { + delete[] data; + } else { + delete data; + } + } +}; + +int main() +{ + Alloc a; + Alloc b; +} diff --git a/tests/CXXDestructorTest.expect b/tests/CXXDestructorTest.expect new file mode 100644 index 00000000..5b4fd640 --- /dev/null +++ b/tests/CXXDestructorTest.expect @@ -0,0 +1,99 @@ +template +class Alloc +{ + T* data; + +public: + Alloc() { + if( array ) { + data = new T[10]; + data = new T[10]{1,2,3}; + } else { + data = new T; + data = new T(2); + data = new T{2}; + } + } + + ~Alloc() { + if( array ) { + delete[] data; + } else { + delete data; + } + } +}; +/* First instantiated from: CXXDestructorTest.cpp:29 */ +#ifdef INSIGHTS_USE_TEMPLATE +class Alloc +{ + int * data; + + public: + inline Alloc() + { + if(false) { + this->data = new int[10]; + this->data = new int[10]{1, 2, 3}; + } else { + this->data = new int; + this->data = new int{2}; + this->data = new int{2}; + } + } + + inline ~Alloc() noexcept + { + if(false) { + delete[] this->data; + } else { + delete this->data; + } + } + + inline constexpr Alloc(const Alloc &) = default; + +}; + +#endif + +/* First instantiated from: CXXDestructorTest.cpp:30 */ +#ifdef INSIGHTS_USE_TEMPLATE +class Alloc +{ + char * data; + + public: + inline Alloc() + { + if(true) { + this->data = new char[10]; + this->data = new char[10]{1, 2, 3}; + } else { + this->data = new char; + this->data = new char{2}; + this->data = new char{2}; + } + } + + inline ~Alloc() noexcept + { + if(true) { + delete[] this->data; + } else { + delete this->data; + } + } + + inline constexpr Alloc(const Alloc &) = default; + +}; + +#endif + + +int main() +{ + Alloc a; + Alloc b; +} diff --git a/tests/CharLiteralTest.expect b/tests/CharLiteralTest.expect index fe5ff366..d064078e 100644 --- a/tests/CharLiteralTest.expect +++ b/tests/CharLiteralTest.expect @@ -21,8 +21,25 @@ struct Foo }; /* First instantiated from: CharLiteralTest.cpp:61 */ #ifdef INSIGHTS_USE_TEMPLATE -class Foo +struct Foo { + int raw; + inline Foo() noexcept = default; + inline constexpr Foo(const Foo & v) noexcept = default; + inline constexpr Foo(int v); + + using retType = int; + inline constexpr operator retType () const + { + return this->raw; + } + + inline constexpr Foo & operator=(const Foo & rhs) = default; + inline Foo & operator=(int v); + + inline volatile void operator=(int v); + + inline ~Foo() noexcept = default; }; @@ -30,8 +47,26 @@ class Foo /* First instantiated from: CharLiteralTest.cpp:60 */ #ifdef INSIGHTS_USE_TEMPLATE -class Foo +struct Foo { + char raw; + inline Foo() noexcept = default; + inline constexpr Foo(const Foo & v) = default; + inline constexpr Foo(char v); + + using retType = char; + inline constexpr operator retType () const; + + inline constexpr Foo & operator=(const Foo & rhs) = default; + inline Foo & operator=(char v) + { + this->raw = v; + return *this; + } + + inline volatile void operator=(char v); + + inline ~Foo() = default; }; diff --git a/tests/ClassOpInTemplateFunctionTest.expect b/tests/ClassOpInTemplateFunctionTest.expect index 83fc423d..79f155f9 100644 --- a/tests/ClassOpInTemplateFunctionTest.expect +++ b/tests/ClassOpInTemplateFunctionTest.expect @@ -29,7 +29,7 @@ public: template<> inline constexpr int get<1>() noexcept { - if constexpr( 1 == 1 ) { + if constexpr(1 == 1) { return this->mX; } } diff --git a/tests/ClassOperatorHandler2Test.expect b/tests/ClassOperatorHandler2Test.expect index 6ae94c7a..d46f366b 100644 --- a/tests/ClassOperatorHandler2Test.expect +++ b/tests/ClassOperatorHandler2Test.expect @@ -65,7 +65,7 @@ int main() int n = 10; f(n); f(42); - f(int{ }); + f(int{}); Foo f = Foo(1); f.operator++(); f.operator++(0); diff --git a/tests/ClassOperatorHandler4Test.expect b/tests/ClassOperatorHandler4Test.expect index 7873f3f7..a06a7439 100644 --- a/tests/ClassOperatorHandler4Test.expect +++ b/tests/ClassOperatorHandler4Test.expect @@ -24,7 +24,7 @@ int main() const bool b = operator==(f1, f2); - if( b ) { + if(b) { return 0; } else { return 1; diff --git a/tests/ClassOperatorHandler5Test.expect b/tests/ClassOperatorHandler5Test.expect index e210bc84..2ddf8882 100644 --- a/tests/ClassOperatorHandler5Test.expect +++ b/tests/ClassOperatorHandler5Test.expect @@ -2,7 +2,7 @@ std::string trim(const std::string& input) { - if( input.length() == 0 ) { + if(input.length() == 0) { return std::basic_string(""); } @@ -14,12 +14,12 @@ std::string trim(const std::string& input) i++; } - if( i >= reinterpret_cast(static_cast(input.length())) ) { + if(i >= reinterpret_cast(static_cast(input.length()))) { return std::basic_string(""); } - if( i > 0 ) { + if(i > 0) { final.operator=(input.substr(static_cast(i), input.length() - static_cast(i))); } diff --git a/tests/ClassOperatorHandler6Test.expect b/tests/ClassOperatorHandler6Test.expect index a2214d18..a30e3e57 100644 --- a/tests/ClassOperatorHandler6Test.expect +++ b/tests/ClassOperatorHandler6Test.expect @@ -99,7 +99,7 @@ int main() const bool b = f1.operator==(f2); void *t; - if( b ) { + if(b) { return 0; } else { return 1; @@ -131,14 +131,14 @@ int main() // ExplicitCastExpr const bool b9 = f1.operator==(new char[2]); - const bool b10 = f1.operator==(new char[2]{ 1, 2 }); + const bool b10 = f1.operator==(new char[2]{1, 2}); char buffer[1024]; - const bool b11 = f1.operator==(new (static_cast(buffer))char[2]{ 1, 2 }); + const bool b11 = f1.operator==(new (static_cast(buffer))char[2]{1, 2}); - const bool b12 = f1.operator==(new Woo(1, 'a')); + const bool b12 = f1.operator==(new Woo{1, 'a'}); - const bool b13 = f1.operator==(Woo(1, 'a')); + const bool b13 = f1.operator==(Woo{1, 'a'}); // thould trigger thisExpr Foo f3{'c'}; diff --git a/tests/ClassOperatorHandler7Test.expect b/tests/ClassOperatorHandler7Test.expect index 60ac1063..605906d3 100644 --- a/tests/ClassOperatorHandler7Test.expect +++ b/tests/ClassOperatorHandler7Test.expect @@ -8,8 +8,13 @@ struct A }; /* First instantiated from: ClassOperatorHandler7Test.cpp:20 */ #ifdef INSIGHTS_USE_TEMPLATE -class A +struct A { + void foo(int); + + inline constexpr A() noexcept = default; + inline constexpr A(const A &) = default; + inline constexpr A(A &&) = default; }; @@ -17,8 +22,23 @@ class A /* First instantiated from: ClassOperatorHandler7Test.cpp:20 */ #ifdef INSIGHTS_USE_TEMPLATE -class A +struct A { + struct B + { + void operator()(int); + + inline constexpr B() noexcept = default; + inline ~B() = default; + inline constexpr B(const A::B &) = default; + inline constexpr B(A::B &&) = default; + + }; + + A::B foo; + inline constexpr A() noexcept = default; + inline constexpr A(const A &) = default; + inline constexpr A(A &&) = default; }; diff --git a/tests/ClassOperatorHandler9Test.expect b/tests/ClassOperatorHandler9Test.expect index 8f988619..8b0f0ca2 100644 --- a/tests/ClassOperatorHandler9Test.expect +++ b/tests/ClassOperatorHandler9Test.expect @@ -30,6 +30,38 @@ public: #ifdef INSIGHTS_USE_TEMPLATE class MyVector { + std::vector > v; + + public: + inline MyVector(const std::size_t n) + : v{std::vector >(n)} + { + } + + inline MyVector(const std::size_t n, const double initialValue) + : v{std::vector >(n, static_cast(initialValue))} + { + } + + inline std::size_t size() const + { + return this->v.size(); + } + + inline int operator[](const std::size_t i) const + { + return this->v.operator[](i); + } + + inline int & operator[](const std::size_t i) + { + return this->v.operator[](i); + } + + inline MyVector(const MyVector &) = default; + inline MyVector(MyVector &&) noexcept = default; + inline MyVector & operator=(MyVector &&) = default; + inline ~MyVector() noexcept = default; }; @@ -64,7 +96,7 @@ MyVector operator*(const MyVector & a, const MyVector & b) { MyVector result = MyVector(a.size()) /* NRVO variable */; for(std::size_t s = 0; - s <= a.size(); ++s) + s <= a.size(); ++s) { result.operator[](s) = a.operator[](s) + b.operator[](s); } diff --git a/tests/ClassOperatorHandlerTest.expect b/tests/ClassOperatorHandlerTest.expect index 954c02d9..5044b0d7 100644 --- a/tests/ClassOperatorHandlerTest.expect +++ b/tests/ClassOperatorHandlerTest.expect @@ -137,12 +137,12 @@ int main() t1.operator+=(t2); - if( t1.operator>(t2) ) { + if(t1.operator>(t2)) { return 1; } - if( t1.operator>=(t2) ) { + if(t1.operator>=(t2)) { return 3; } @@ -163,7 +163,7 @@ int main() Fest f1{2}; Fest f2{3}; - if( operator<(f1, f2) ) { + if(operator<(f1, f2)) { return 22; } @@ -171,7 +171,7 @@ int main() Hello::Bello::Fest f3{3}; Hello::Bello::Fest f4{3}; - if( Hello::Bello::operator<(f3, f4) ) { + if(Hello::Bello::operator<(f3, f4)) { return 44; } diff --git a/tests/DoStmtTest.expect b/tests/DoStmtTest.expect index 314acced..2b6e385c 100644 --- a/tests/DoStmtTest.expect +++ b/tests/DoStmtTest.expect @@ -8,7 +8,7 @@ int main() int x = 1; do { ++x; - } while( true ); + } while(true) ; } } __lambda_3_5{}; diff --git a/tests/EmptyLambda.cpp b/tests/EmptyLambda.cpp new file mode 100644 index 00000000..a60b9d19 --- /dev/null +++ b/tests/EmptyLambda.cpp @@ -0,0 +1,9 @@ +void foo() { +[]() { + // (void)X{1, 2, 3}; // => X(std::initializer_list{1, 2, 3}) + // (void)X{nullptr, 0}; // => X(nullptr, 0) +// takes_y({1, 2}); // => Y _tmp = {1, 2}; takes_y(_tmp); +}(); +} + + diff --git a/tests/EmptyLambda.expect b/tests/EmptyLambda.expect new file mode 100644 index 00000000..45bc1778 --- /dev/null +++ b/tests/EmptyLambda.expect @@ -0,0 +1,14 @@ +void foo() { + + class __lambda_2_1 + { + public: inline /*constexpr */ void operator()() const + { + } + + } __lambda_2_1{}; + + __lambda_2_1.operator()(); +} + + diff --git a/tests/FunctionalCast2Test.expect b/tests/FunctionalCast2Test.expect index 0d1f77c4..647ea9bf 100644 --- a/tests/FunctionalCast2Test.expect +++ b/tests/FunctionalCast2Test.expect @@ -31,7 +31,7 @@ constexpr bool Compare(const T (&ar)[N], const TTo& to) template<> inline constexpr bool Compare(const unsigned char (&ar)[6], const int & to) { - return details::array_single_compare::Compare(ar, to, std::integer_sequence{ }); + return details::array_single_compare::Compare(ar, to, std::integer_sequence{}); } #endif @@ -65,7 +65,7 @@ constexpr bool Compare(const T (&ar)[N], const T (&to)[N]) template<> inline constexpr bool Compare(const unsigned char (&ar)[6], const unsigned char (&to)[6]) { - return details::array_compare::Compare(ar, to, std::integer_sequence{ }); + return details::array_compare::Compare(ar, to, std::integer_sequence{}); } #endif diff --git a/tests/IfStmtHandler2Test.expect b/tests/IfStmtHandler2Test.expect index 4b681ade..9ec40819 100644 --- a/tests/IfStmtHandler2Test.expect +++ b/tests/IfStmtHandler2Test.expect @@ -2,7 +2,7 @@ int main() { { char * ptr = nullptr; - if( ptr ) { + if(ptr) { } else { *ptr = 2; } @@ -11,7 +11,7 @@ int main() const char* ptr2; - if( ptr2 ) { + if(ptr2) { } } diff --git a/tests/IfStmtHandler3Test.expect b/tests/IfStmtHandler3Test.expect index 9892d014..818bae2c 100644 --- a/tests/IfStmtHandler3Test.expect +++ b/tests/IfStmtHandler3Test.expect @@ -3,7 +3,7 @@ int Test() int ret; char buffer[2]; - if( static_cast(buffer[0]) == static_cast('0') ) ret = 1; + if(static_cast(buffer[0]) == static_cast('0')) ret = 1; else ret = 2 ; diff --git a/tests/IfStmtHandlerTest.expect b/tests/IfStmtHandlerTest.expect index a5c4bbc3..84dc6048 100644 --- a/tests/IfStmtHandlerTest.expect +++ b/tests/IfStmtHandlerTest.expect @@ -2,29 +2,29 @@ int main() { - if constexpr( false ) { + if constexpr(false) { printf("False\n"); } else /* constexpr */ { - if( true ) { + if(true) { printf("true"); } } - if constexpr( false ) { + if constexpr(false) { printf("False\n"); } else /* constexpr */ { - if constexpr( true ) { + if constexpr(true) { printf("true"); } } - if constexpr( false ) printf("False\n"); + if constexpr(false) printf("False\n"); else /* constexpr */ { - if( true ) printf("true"); + if(true) printf("true"); } @@ -32,14 +32,14 @@ int main() int x = 1; - if( 1 == x ) printf("a"); + if(1 == x) printf("a"); else { - if( 2 == x ) { + if(2 == x) { printf("b"); - if( x == 5 ) printf("5"); + if(x == 5) printf("5"); } else { - if( x == 3 ) printf("r"); + if(x == 3) printf("r"); } diff --git a/tests/IfSwitchInitHandler3Test.expect b/tests/IfSwitchInitHandler3Test.expect index 6a8acd20..45dd44bd 100644 --- a/tests/IfSwitchInitHandler3Test.expect +++ b/tests/IfSwitchInitHandler3Test.expect @@ -8,8 +8,8 @@ int Foo() // normal if but with an DeclStmt. No rewrite expected { int ret = Open(); - if( static_cast(ret) ) { - if( 1 != ret ) { + if(static_cast(ret)) { + if(1 != ret) { return ret; } } diff --git a/tests/IfSwitchInitHandler5Test.expect b/tests/IfSwitchInitHandler5Test.expect index e3050f4e..9cb367a5 100644 --- a/tests/IfSwitchInitHandler5Test.expect +++ b/tests/IfSwitchInitHandler5Test.expect @@ -7,7 +7,7 @@ int main(){ { std::shared_ptr sharedPtr1 = weakPtr.lock(); - if( static_cast(sharedPtr1.operator bool()) ) { + if(static_cast(sharedPtr1.operator bool())) { std::operator<<(std::cout, "*sharedPtr: ").operator<<(sharedPtr.operator*()).operator<<(std::endl); } else { } diff --git a/tests/IfSwitchInitHandlerTest.expect b/tests/IfSwitchInitHandlerTest.expect index eb9b1fef..938c79e7 100644 --- a/tests/IfSwitchInitHandlerTest.expect +++ b/tests/IfSwitchInitHandlerTest.expect @@ -7,12 +7,12 @@ int Foo() { { int ret = Open(); - if( 1 != ret ) { + if(1 != ret) { return ret; } else { { int ret = Write(); - if( 1 != ret ) { + if(1 != ret) { return ret; } diff --git a/tests/ImplicitCastHandlerTest.expect b/tests/ImplicitCastHandlerTest.expect index 880100dc..fba4ee03 100644 --- a/tests/ImplicitCastHandlerTest.expect +++ b/tests/ImplicitCastHandlerTest.expect @@ -2,12 +2,12 @@ int main() { char c = 1; - if( static_cast(c) == static_cast(true) ) { + if(static_cast(c) == static_cast(true)) { return 1; } - if( static_cast(c) == 100 ) { + if(static_cast(c) == 100) { return 2; } diff --git a/tests/InitalizerListTest.expect b/tests/InitalizerListTest.expect index 9f52c10d..904e5f01 100644 --- a/tests/InitalizerListTest.expect +++ b/tests/InitalizerListTest.expect @@ -1,9 +1,9 @@ #include int main(){ - std::vector myVec{ std::initializer_list{ 1, 2, 3, 4, 5, 6, 7, 8, 9 } }; + std::vector myVec{ std::initializer_list{1, 2, 3, 4, 5, 6, 7, 8, 9} }; - myVec.operator=(std::initializer_list{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }); + myVec.operator=(std::initializer_list{1, 2, 3, 4, 5, 6, 7, 8, 9}); } diff --git a/tests/InitializerList2Test.expect b/tests/InitializerList2Test.expect index 4066e0cf..794bea8b 100644 --- a/tests/InitializerList2Test.expect +++ b/tests/InitializerList2Test.expect @@ -10,7 +10,7 @@ public: int main() { - Foo f{ std::initializer_list{ 1 } }; - Foo f2{ std::initializer_list{ 1, static_cast(true) } }; - Foo f3{ std::initializer_list{ 1, static_cast(true), 4 } }; + Foo f{ std::initializer_list{1} }; + Foo f2{ std::initializer_list{1, static_cast(true)} }; + Foo f3{ std::initializer_list{1, static_cast(true), 4} }; } diff --git a/tests/InitializerListTest.expect b/tests/InitializerListTest.expect index e957cb32..e6f7236f 100644 --- a/tests/InitializerListTest.expect +++ b/tests/InitializerListTest.expect @@ -57,29 +57,29 @@ void something(std::initializer_list) void foo() { - X{ std::initializer_list{ 1, 2, 3 } }; + X{ std::initializer_list{1, 2, 3} }; X{nullptr, 0}; - X x{ std::initializer_list{ 3, 4, 5 } }; - X b{ std::initializer_list{ 1 } }; + X x{ std::initializer_list{3, 4, 5} }; + X b{ std::initializer_list{1} }; - X{1, std::initializer_list{ 2, 3 }}; - X c{1, std::initializer_list{ 2, 3 }}; + X{1, std::initializer_list{2, 3}}; + X c{1, std::initializer_list{2, 3}}; - X{std::initializer_list{ 1, 2 }, 3}; - X d{std::initializer_list{ 1, 2 }, 3}; + X{std::initializer_list{1, 2}, 3}; + X d{std::initializer_list{1, 2}, 3}; - b.operator+=(std::initializer_list{ 2, 4 }); + b.operator+=(std::initializer_list{2, 4}); takes_y({1, 2}); - bar( std::initializer_list{ 1, 2 } ); + bar( std::initializer_list{1, 2} ); - something( std::initializer_list{ 1, 2 } ); + something( std::initializer_list{1, 2} ); - something( std::initializer_list{ 1.0f, 2.0f } ); + something( std::initializer_list{1.0f, 2.0f} ); - V v{ std::initializer_list{ 1 } }; - V vv{ std::initializer_list{ 1, 2 } }; + V v{ std::initializer_list{1} }; + V vv{ std::initializer_list{1, 2} }; } diff --git a/tests/Issue1.expect b/tests/Issue1.expect index ffb3aab3..62c2440d 100644 --- a/tests/Issue1.expect +++ b/tests/Issue1.expect @@ -16,7 +16,7 @@ template T fooGood() {return T{42}; } template<> int fooGood() { - return int{ 42 }; + return int{42}; } #endif diff --git a/tests/Issue20.expect b/tests/Issue20.expect index 0e777142..ece043bc 100644 --- a/tests/Issue20.expect +++ b/tests/Issue20.expect @@ -2,7 +2,7 @@ int main() { - std::map map{ std::initializer_list >{ std::pair(1, 2) } }; + std::map map{ std::initializer_list >{std::pair{1, 2}} }; std::pair __operator6 = std::pair(map.begin().operator*()); std::tuple_element<0, std::pair >::type& key = std::get<0ul>(__operator6); std::tuple_element<1, std::pair >::type& value = std::get<1ul>(__operator6); diff --git a/tests/Issue28.expect b/tests/Issue28.expect index 082a39c1..3f6137be 100644 --- a/tests/Issue28.expect +++ b/tests/Issue28.expect @@ -5,5 +5,5 @@ int main() { using namespace std::string_literals; - std::vector foo{ std::initializer_list >{ std::operator""s("foo", 3ul), std::operator""s("bar", 3ul) } }; + std::vector foo{ std::initializer_list >{std::operator""s("foo", 3ul), std::operator""s("bar", 3ul)} }; } diff --git a/tests/LambdaHandler7Test.expect b/tests/LambdaHandler7Test.expect index ebe93693..0a0c5991 100644 --- a/tests/LambdaHandler7Test.expect +++ b/tests/LambdaHandler7Test.expect @@ -3,7 +3,7 @@ int main() { - std::vector myVec{ std::initializer_list{ 1, 2, 3, 4, 5 } }; + std::vector myVec{ std::initializer_list{1, 2, 3, 4, 5} }; class __lambda_8_57 diff --git a/tests/LambdaHandler9Test.expect b/tests/LambdaHandler9Test.expect index 1986a575..ed06f5e2 100644 --- a/tests/LambdaHandler9Test.expect +++ b/tests/LambdaHandler9Test.expect @@ -75,7 +75,7 @@ int main() { volatile char buffer[10]; for(int i = 0; - static_cast(i) < sizeof(buffer); ++i) + static_cast(i) < sizeof(buffer); ++i) { buffer[i] = 1; } @@ -95,7 +95,7 @@ int main() { volatile char buffer[10]; int i = 0; - for(; static_cast(i) < sizeof(buffer); ++i) + for(; static_cast(i) < sizeof(buffer); ++i) { buffer[i] = 1; } diff --git a/tests/LambdaHandlerVLATest.cerr b/tests/LambdaHandlerVLATest.cerr index 709f985a..cd4bae3f 100644 --- a/tests/LambdaHandlerVLATest.cerr +++ b/tests/LambdaHandlerVLATest.cerr @@ -1,7 +1,7 @@ -.tmp.cpp:63:17: error: invalid use of 'this' outside of a non-static member function +.tmp.cpp:89:17: error: invalid use of 'this' outside of a non-static member function float (&e)[this->nt]; ^ -.tmp.cpp:65:40: error: invalid use of 'this' outside of a non-static member function +.tmp.cpp:91:40: error: invalid use of 'this' outside of a non-static member function public: __lambda_36_8(float (&_e)[this->nt]) ^ 2 errors generated. diff --git a/tests/LambdaHandlerVLATest.expect b/tests/LambdaHandlerVLATest.expect index 9aace313..3212f58a 100644 --- a/tests/LambdaHandlerVLATest.expect +++ b/tests/LambdaHandlerVLATest.expect @@ -24,8 +24,34 @@ struct SA }; /* First instantiated from: LambdaHandlerVLATest.cpp:42 */ #ifdef INSIGHTS_USE_TEMPLATE -class SA<2> +struct SA<2> { + inline SA(const int & PA) + { + float e[this->nt]; + + class __lambda_36_8 + { + public: inline /*constexpr */ bool operator()(int i, int j) const + { + return e[i] < e[j]; + } + + private: + float (&e)[this->nt]; + + public: __lambda_36_8(float (&_e)[this->nt]) + : e{_e} + {} + + }; + + test(__lambda_36_8{e}); + } + + int nt; + inline constexpr SA(const SA<2> &) = default; + inline constexpr SA(SA<2> &&) = default; }; diff --git a/tests/LambdaPackExpansionTest.cpp b/tests/LambdaPackExpansionTest.cpp new file mode 100644 index 00000000..c70df8ba --- /dev/null +++ b/tests/LambdaPackExpansionTest.cpp @@ -0,0 +1,23 @@ +template +int g(Args ...) +{ + return 1; +} + +template +void f(Args... args) { + auto lm = [&] { return g(args...); }; + lm(); +} + +template +void f2(Args... args) { + auto lm = [&, args...] { return g(args...); }; + lm(); +} + +int main() +{ + f(1, 2, 3 , 4, 5); + f2(1, 2, 3 , 4, 5); +} diff --git a/tests/RangeForStmtHandler2Test.expect b/tests/RangeForStmtHandler2Test.expect index cde85b36..87405622 100644 --- a/tests/RangeForStmtHandler2Test.expect +++ b/tests/RangeForStmtHandler2Test.expect @@ -19,7 +19,7 @@ int main() } } - std::vector v{ std::initializer_list{ 1, 2, 3, 5 } }; + std::vector v{ std::initializer_list{1, 2, 3, 5} }; { std::vector > & __range1 = v; diff --git a/tests/RangeForStmtHandler3Test.expect b/tests/RangeForStmtHandler3Test.expect index d9a6f4ca..408d3e0e 100644 --- a/tests/RangeForStmtHandler3Test.expect +++ b/tests/RangeForStmtHandler3Test.expect @@ -34,7 +34,7 @@ template<> inline bool operator!=(const char *const & ptr, null_sentinal_t) { - return !(operator==(ptr, null_sentinal_t{ })); + return !(operator==(ptr, null_sentinal_t{})); } #endif @@ -70,8 +70,20 @@ struct str_view { }; /* First instantiated from: RangeForStmtHandler3Test.cpp:49 */ #ifdef INSIGHTS_USE_TEMPLATE -class str_view +struct str_view { + const char * ptr; + inline const char * begin() const + { + return this->ptr; + } + + inline null_sentinal_t end() const + { + return {}; + } + + inline ~str_view() noexcept = default; }; @@ -80,7 +92,7 @@ class str_view int main() { { - str_view && __range1 = str_view{ "hello world\n" }; + str_view && __range1 = str_view{"hello world\n"}; const char * __begin1 = __range1.begin(); null_sentinal_t __end1 = __range1.end(); diff --git a/tests/RangeForStmtHandler4Test.expect b/tests/RangeForStmtHandler4Test.expect index c62a7e1d..d87566b4 100644 --- a/tests/RangeForStmtHandler4Test.expect +++ b/tests/RangeForStmtHandler4Test.expect @@ -12,6 +12,23 @@ public: #ifdef INSIGHTS_USE_TEMPLATE class MyArrayWrapper { + int * data; + int size; + + public: + inline int * begin() + { + return this->size > 0 ? &this->data[0] : nullptr; + } + + inline int * end() + { + return this->size > 0 ? &this->data[this->size - 1] : nullptr; + } + + inline MyArrayWrapper() noexcept = default; + inline constexpr MyArrayWrapper(const MyArrayWrapper &) = default; + inline constexpr MyArrayWrapper(MyArrayWrapper &&) = default; }; diff --git a/tests/RangeForStmtHandlerTest.expect b/tests/RangeForStmtHandlerTest.expect index 1972d6b5..4899ae57 100644 --- a/tests/RangeForStmtHandlerTest.expect +++ b/tests/RangeForStmtHandlerTest.expect @@ -108,7 +108,7 @@ int main() } } - std::vector v{ std::initializer_list{ 1, 2, 3, 5 } }; + std::vector v{ std::initializer_list{1, 2, 3, 5} }; { std::vector > & __range1 = v; diff --git a/tests/StaticAssertTest.expect b/tests/StaticAssertTest.expect index 04b49516..c3381c5a 100644 --- a/tests/StaticAssertTest.expect +++ b/tests/StaticAssertTest.expect @@ -2,7 +2,8 @@ struct S { int x; }; -/* PASSED: static_assert(sizeof(S) == sizeof(int))*/; +/* PASSED: static_assert(sizeof(S) == sizeof(int)); */ + //static_assert(sizeof(S) != sizeof(int)); diff --git a/tests/StaticHandlerTest.expect b/tests/StaticHandlerTest.expect index a4a13fce..a6038818 100644 --- a/tests/StaticHandlerTest.expect +++ b/tests/StaticHandlerTest.expect @@ -84,7 +84,7 @@ Bingleton* B(bool c) } ; - if( c ) { + if(c) { return nullptr; } @@ -105,7 +105,7 @@ Bingleton& BB(bool c) } ; - if( c ) { + if(c) { return *reinterpret_cast(__bb); } diff --git a/tests/StaticInLambdaTest.expect b/tests/StaticInLambdaTest.expect index ef8feac3..ef1e983a 100644 --- a/tests/StaticInLambdaTest.expect +++ b/tests/StaticInLambdaTest.expect @@ -74,7 +74,7 @@ int main() new (&__bb) Bingleton; __bbB = true; } - if( c ) { + if(c) { return Bingleton(*reinterpret_cast(__bb)); } return Bingleton(*reinterpret_cast(__bb)); @@ -99,7 +99,7 @@ int main() new (&__bb) Bingleton; __bbB = true; } - if( c ) { + if(c) { return &*reinterpret_cast(__bb); } return &*reinterpret_cast(__bb); diff --git a/tests/StructuredBindingsHandler3Test.cerr b/tests/StructuredBindingsHandler3Test.cerr index 696d40dc..b1e8b668 100644 --- a/tests/StructuredBindingsHandler3Test.cerr +++ b/tests/StructuredBindingsHandler3Test.cerr @@ -1,61 +1,61 @@ -.tmp.cpp:78:48: error: no matching function for call to 'get' +.tmp.cpp:81:48: error: no matching function for call to 'get' std::tuple_element<0, constant::Q>::type a = constant::get<0ul>(constant::__q17); ^~~~~~~~~~~~~~~~~~ -.tmp.cpp:40:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument +.tmp.cpp:43:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument template constexpr int get(Q &&) { return N * N; } ^ -.tmp.cpp:79:48: error: no matching function for call to 'get' +.tmp.cpp:82:48: error: no matching function for call to 'get' std::tuple_element<1, constant::Q>::type b = constant::get<1ul>(constant::__q17); ^~~~~~~~~~~~~~~~~~ -.tmp.cpp:40:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument +.tmp.cpp:43:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument template constexpr int get(Q &&) { return N * N; } ^ -.tmp.cpp:80:48: error: no matching function for call to 'get' +.tmp.cpp:83:48: error: no matching function for call to 'get' std::tuple_element<2, constant::Q>::type c = constant::get<2ul>(constant::__q17); ^~~~~~~~~~~~~~~~~~ -.tmp.cpp:40:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument +.tmp.cpp:43:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument template constexpr int get(Q &&) { return N * N; } ^ -.tmp.cpp:85:50: error: no matching function for call to 'get' +.tmp.cpp:88:50: error: no matching function for call to 'get' std::tuple_element<0, constant::Q>::type a = constant::get<0ul>(__q20); ^~~~~~~~~~~~~~~~~~ -.tmp.cpp:40:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument +.tmp.cpp:43:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument template constexpr int get(Q &&) { return N * N; } ^ -.tmp.cpp:86:50: error: no matching function for call to 'get' +.tmp.cpp:89:50: error: no matching function for call to 'get' std::tuple_element<1, constant::Q>::type b = constant::get<1ul>(__q20); ^~~~~~~~~~~~~~~~~~ -.tmp.cpp:40:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument +.tmp.cpp:43:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument template constexpr int get(Q &&) { return N * N; } ^ -.tmp.cpp:87:50: error: no matching function for call to 'get' +.tmp.cpp:90:50: error: no matching function for call to 'get' std::tuple_element<2, constant::Q>::type c = constant::get<2ul>(__q20); ^~~~~~~~~~~~~~~~~~ -.tmp.cpp:40:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument +.tmp.cpp:43:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument template constexpr int get(Q &&) { return N * N; } ^ -.tmp.cpp:85:46: error: variables defined in a constexpr function must be initialized +.tmp.cpp:88:46: error: variables defined in a constexpr function must be initialized std::tuple_element<0, constant::Q>::type a = constant::get<0ul>(__q20); ^ -.tmp.cpp:96:52: error: no matching function for call to 'get' +.tmp.cpp:99:52: error: no matching function for call to 'get' std::tuple_element<0, constant::Q>::type a = constant::get<0ul>(__q27); ^~~~~~~~~~~~~~~~~~ -.tmp.cpp:40:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument +.tmp.cpp:43:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument template constexpr int get(Q &&) { return N * N; } ^ -.tmp.cpp:97:52: error: no matching function for call to 'get' +.tmp.cpp:100:52: error: no matching function for call to 'get' std::tuple_element<1, constant::Q>::type b = constant::get<1ul>(__q27); ^~~~~~~~~~~~~~~~~~ -.tmp.cpp:40:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument +.tmp.cpp:43:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument template constexpr int get(Q &&) { return N * N; } ^ -.tmp.cpp:98:52: error: no matching function for call to 'get' +.tmp.cpp:101:52: error: no matching function for call to 'get' std::tuple_element<2, constant::Q>::type c = constant::get<2ul>(__q27); ^~~~~~~~~~~~~~~~~~ -.tmp.cpp:40:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument +.tmp.cpp:43:33: note: candidate function not viable: no known conversion from 'constant::Q' to 'constant::Q &&' for 1st argument template constexpr int get(Q &&) { return N * N; } ^ -.tmp.cpp:96:48: error: variables defined in a constexpr function must be initialized +.tmp.cpp:99:48: error: variables defined in a constexpr function must be initialized std::tuple_element<0, constant::Q>::type a = constant::get<0ul>(__q27); ^ 11 errors generated. diff --git a/tests/StructuredBindingsHandler3Test.expect b/tests/StructuredBindingsHandler3Test.expect index e7a6adf9..ddeacc4b 100644 --- a/tests/StructuredBindingsHandler3Test.expect +++ b/tests/StructuredBindingsHandler3Test.expect @@ -5,8 +5,9 @@ namespace std { template struct tuple_size; } namespace std { template struct tuple_element; /* First instantiated from: StructuredBindingsHandler3Test.cpp:17 */ #ifdef INSIGHTS_USE_TEMPLATE -class tuple_element<0, constant::Q> +struct tuple_element<0, constant::Q> { + using type = int; }; @@ -14,8 +15,9 @@ class tuple_element<0, constant::Q> /* First instantiated from: StructuredBindingsHandler3Test.cpp:17 */ #ifdef INSIGHTS_USE_TEMPLATE -class tuple_element<1, constant::Q> +struct tuple_element<1, constant::Q> { + using type = int; }; @@ -23,8 +25,9 @@ class tuple_element<1, constant::Q> /* First instantiated from: StructuredBindingsHandler3Test.cpp:17 */ #ifdef INSIGHTS_USE_TEMPLATE -class tuple_element<2, constant::Q> +struct tuple_element<2, constant::Q> { + using type = int; }; diff --git a/tests/StructuredBindingsHandler4Test.expect b/tests/StructuredBindingsHandler4Test.expect index 5c0de488..f9f4b513 100644 --- a/tests/StructuredBindingsHandler4Test.expect +++ b/tests/StructuredBindingsHandler4Test.expect @@ -1,14 +1,14 @@ int main() { char p[2]; - char const __p4[2] = { p[0], p[1] }; + char const __p4[2] = {p[0], p[1]}; const char x = __p4[0]; const char y = __p4[1]; volatile char p2[2]; - volatile char const __p28[2] = { p2[0], p2[1] }; + volatile char const __p28[2] = {p2[0], p2[1]}; const volatile char x2 = __p28[0]; const volatile char y2 = __p28[1]; diff --git a/tests/StructuredBindingsHandler5Test.expect b/tests/StructuredBindingsHandler5Test.expect index 5c31e966..6d7e6a3f 100644 --- a/tests/StructuredBindingsHandler5Test.expect +++ b/tests/StructuredBindingsHandler5Test.expect @@ -49,9 +49,9 @@ public: template<> inline constexpr double & get<0>() noexcept { - if constexpr( 0ul == 1 ) ; + if constexpr(0ul == 1) ; else /* constexpr */ { - if constexpr( 0ul == 0 ) { + if constexpr(0ul == 0) { return (this->mY); } @@ -65,7 +65,7 @@ public: template<> inline constexpr double get<1>() noexcept { - if constexpr( 1ul == 1 ) { + if constexpr(1ul == 1) { return this->GetX(); } } @@ -87,9 +87,9 @@ public: template<> inline constexpr const double & get<0>() noexcept { - if constexpr( 0ul == 1 ) ; + if constexpr(0ul == 1) ; else /* constexpr */ { - if constexpr( 0ul == 0 ) { + if constexpr(0ul == 0) { return (this->mY); } @@ -103,7 +103,7 @@ public: template<> inline constexpr double get<1>() noexcept { - if constexpr( 1ul == 1 ) { + if constexpr(1ul == 1) { return this->GetX(); } } diff --git a/tests/StructuredBindingsHandler6Test.expect b/tests/StructuredBindingsHandler6Test.expect index ea4d2f08..20e1dead 100644 --- a/tests/StructuredBindingsHandler6Test.expect +++ b/tests/StructuredBindingsHandler6Test.expect @@ -56,9 +56,9 @@ public: template<> inline constexpr double get<0>() noexcept { - if constexpr( 0ul == 1 ) ; + if constexpr(0ul == 1) ; else /* constexpr */ { - if constexpr( 0ul == 0 ) { + if constexpr(0ul == 0) { return this->mY; } @@ -72,7 +72,7 @@ public: template<> inline constexpr double get<1>() noexcept { - if constexpr( 1ul == 1 ) { + if constexpr(1ul == 1) { return this->GetX(); } } @@ -95,7 +95,7 @@ int main() printf("x:%lf y:%lf\n", x, y); char ar[2]{7,8}; - char __ar64[2] = { ar[0], ar[1] }; + char __ar64[2] = {ar[0], ar[1]}; char a1 = __ar64[0]; char a2 = __ar64[1]; diff --git a/tests/StructuredBindingsHandlerTest.expect b/tests/StructuredBindingsHandlerTest.expect index 9463aba6..1775021f 100644 --- a/tests/StructuredBindingsHandlerTest.expect +++ b/tests/StructuredBindingsHandlerTest.expect @@ -1,7 +1,7 @@ int main() { char p[2]; - char __p4[2] = { p[0], p[1] }; + char __p4[2] = {p[0], p[1]}; char x = __p4[0]; char y = __p4[1]; diff --git a/tests/TemplateArgumentsTest.expect b/tests/TemplateArgumentsTest.expect index 12c7f47b..d73e3cf2 100644 --- a/tests/TemplateArgumentsTest.expect +++ b/tests/TemplateArgumentsTest.expect @@ -15,7 +15,7 @@ static inline decltype(auto) Normalize(const T& arg) template<> inline static char const (&)[8] Normalize(char const (&arg)[8]) { - if constexpr( std::is_same_v> ) ; + if constexpr(std::is_same_v>) ; else /* constexpr */ { return arg; } @@ -28,7 +28,7 @@ inline static char const (&)[8] Normalize(char const (&arg)[8]) template<> inline static const int & Normalize(const int & arg) { - if constexpr( std::is_same_v> ) ; + if constexpr(std::is_same_v>) ; else /* constexpr */ { return arg; } @@ -41,7 +41,7 @@ inline static const int & Normalize(const int & arg) template<> inline static const char * Normalize >(const std::basic_string & arg) { - if constexpr( std::is_same_v, std::basic_string> ) { + if constexpr(std::is_same_v, std::basic_string>) { return arg.c_str(); } } diff --git a/tests/TemplateAsTemplateArgumentTest.expect b/tests/TemplateAsTemplateArgumentTest.expect index c5b653bc..d8b3e833 100644 --- a/tests/TemplateAsTemplateArgumentTest.expect +++ b/tests/TemplateAsTemplateArgumentTest.expect @@ -3,6 +3,10 @@ template class my_array {}; #ifdef INSIGHTS_USE_TEMPLATE class my_array { + inline constexpr my_array() noexcept = default; + inline ~my_array() = default; + inline constexpr my_array(const my_array &) = default; + inline constexpr my_array(my_array &&) = default; }; @@ -20,6 +24,11 @@ class Map #ifdef INSIGHTS_USE_TEMPLATE class Map { + my_array key; + my_array value; + inline constexpr Map() noexcept = default; + inline constexpr Map(const Map &) = default; + inline constexpr Map(Map &&) = default; }; diff --git a/tests/TemplateClassWithoutDefinitionTest.cpp b/tests/TemplateClassWithoutDefinitionTest.cpp new file mode 100644 index 00000000..d28710c7 --- /dev/null +++ b/tests/TemplateClassWithoutDefinitionTest.cpp @@ -0,0 +1,12 @@ +template +class Foo{}; + +typedef Foo IntFoo; // this type is never instantiated which results in a + // CXXRecordDecl without a definition +typedef Foo DoubleFoo; + + +int main() +{ + DoubleFoo df; +} diff --git a/tests/TemplateClassWithoutDefinitionTest.expect b/tests/TemplateClassWithoutDefinitionTest.expect new file mode 100644 index 00000000..8b1ddbba --- /dev/null +++ b/tests/TemplateClassWithoutDefinitionTest.expect @@ -0,0 +1,24 @@ +template +class Foo{}; +/* First instantiated from: TemplateClassWithoutDefinitionTest.cpp:11 */ +#ifdef INSIGHTS_USE_TEMPLATE +class Foo +{ + inline constexpr Foo() noexcept = default; + inline constexpr Foo(const Foo &) = default; + inline constexpr Foo(Foo &&) = default; + +}; + +#endif + + +typedef Foo IntFoo; // this type is never instantiated which results in a + // CXXRecordDecl without a definition +typedef Foo DoubleFoo; + + +int main() +{ + DoubleFoo df; +} diff --git a/tests/TemplateExpansion2Test.cpp b/tests/TemplateExpansion2Test.cpp new file mode 100644 index 00000000..af17a225 --- /dev/null +++ b/tests/TemplateExpansion2Test.cpp @@ -0,0 +1,64 @@ +#include +#include + +namespace details { + template + struct remove_reference { typedef T type; }; + template + struct remove_reference { typedef T type; }; + template + struct remove_reference { typedef T type; }; + + template + struct extent + { + static constexpr size_t value = N; + + static_assert(N != 0, "Arrays only"); + }; + + template + struct extent + { + static constexpr size_t value = I; + + static_assert(I != 0, "Arrays only"); + }; + +} // namespace details + +#define ARRAY_SIZE(var_x) \ + details::extent::type>::value + +class B +{ +}; + +class E{}; + +template +class S : public B +{ +}; + +template +class Y : public S, public E +{ +}; + + +void test() +{ + int buffer[16]{}; + + const auto& xx = ARRAY_SIZE(buffer); + + S s; + + Y y; +} + + +int main(){} + diff --git a/tests/TemplateExpansion2Test.expect b/tests/TemplateExpansion2Test.expect new file mode 100644 index 00000000..b6c114ae --- /dev/null +++ b/tests/TemplateExpansion2Test.expect @@ -0,0 +1,128 @@ +#include +#include + +namespace details { + template + struct remove_reference { typedef T type; }; + #ifdef INSIGHTS_USE_TEMPLATE + struct remove_reference + { + using type = int [16]; + + }; + + #endif + + template + struct remove_reference { typedef T type; }; + template + struct remove_reference { typedef T type; }; + + template + struct extent + { + static constexpr size_t value = N; + + static_assert(N != 0, "Arrays only"); + }; + #ifdef INSIGHTS_USE_TEMPLATE + struct extent + { + inline static constexpr const size_t value = 16ul; + /* PASSED: static_assert(16ul != 0, "Arrays only"); */ + + }; + + #endif + + + template + struct extent + { + static constexpr size_t value = I; + + static_assert(I != 0, "Arrays only"); + }; + +} // namespace details + +#define ARRAY_SIZE(var_x) \ + details::extent::type>::value + +class B +{ +/* public: inline constexpr B() noexcept; */ +/* public: inline ~B(); */ +/* public: inline constexpr B(const B &); */ +/* public: inline constexpr B(B &&); */ +}; + +class E{/* public: inline constexpr E() noexcept; */ +/* public: inline ~E(); */ +/* public: inline constexpr E(const E &); */ +/* public: inline constexpr E(E &&); */ +}; + +template +class S : public B +{ +}; +/* First instantiated from: TemplateExpansion2Test.cpp:57 */ +#ifdef INSIGHTS_USE_TEMPLATE +class S : public B +{ + inline constexpr S() noexcept = default; + inline constexpr S(const S &) = default; + inline constexpr S(S &&) = default; + +}; + +#endif + +/* First instantiated from: TemplateExpansion2Test.cpp:46 */ +#ifdef INSIGHTS_USE_TEMPLATE +class S : public B +{ + inline constexpr S() noexcept = default; + inline ~S() = default; + inline constexpr S(const S &) = default; + inline constexpr S(S &&) = default; + +}; + +#endif + + +template +class Y : public S, public E +{ +}; +/* First instantiated from: TemplateExpansion2Test.cpp:59 */ +#ifdef INSIGHTS_USE_TEMPLATE +class Y : public S, public E +{ + inline constexpr Y() noexcept = default; + inline constexpr Y(const Y &) = default; + inline constexpr Y(Y &&) = default; + +}; + +#endif + + + +void test() +{ + int buffer[16]{}; + + const unsigned long & xx = ARRAY_SIZE(buffer); + + S s; + + Y y; +} + + +int main(){} + diff --git a/tests/TemplateExpansionTest.expect b/tests/TemplateExpansionTest.expect index 1c7cf1b7..9317e5f1 100644 --- a/tests/TemplateExpansionTest.expect +++ b/tests/TemplateExpansionTest.expect @@ -2,8 +2,9 @@ template