From 2d85053f225276ce1dd528fd694242d7106d6a43 Mon Sep 17 00:00:00 2001 From: Andreas Fertig Date: Mon, 1 Sep 2025 09:48:41 +0200 Subject: [PATCH] Support for Clang 21 This fixed #723 and #738. --- .github/workflows/ci.yml | 70 +++--- ASTHelpers.cpp | 11 +- CMakeLists.txt | 2 +- CodeGenerator.cpp | 61 ++++-- InsightsHelpers.cpp | 211 ++++++++++++------- InsightsHelpers.h | 1 + scripts/prepare-release.py | 6 +- tests/DeductionGuide2Test.cpp | 12 ++ tests/DeductionGuide2Test.expect | 36 ++++ tests/DependentTemplateParameterTest.cpp | 9 + tests/DependentTemplateParameterTest.expect | 16 ++ tests/EduCfrontTest17.cerr | 12 +- tests/EduCfrontTestLifeTime2.cerr | 4 +- tests/FoldExpressionTest.cpp | 1 + tests/FunctionPointerTest.cpp | 28 +++ tests/FunctionPointerTest.expect | 54 +++++ tests/FunctionProtoTypeTest.cpp | 6 + tests/FunctionProtoTypeTest.expect | 11 + tests/Issue101.expect | 16 +- tests/Issue102.expect | 26 +-- tests/Issue188_2.expect | 11 +- tests/Issue205.expect | 1 - tests/Issue205_2.expect | 1 - tests/Issue391.expect | 2 +- tests/Issue41.cerr | 2 +- tests/Issue596.expect | 8 - tests/Issue628.expect | 1 - tests/Issue723.cpp | 9 + tests/Issue723.expect | 20 ++ tests/Issue738.cpp | 3 + tests/Issue738.expect | 3 + tests/LambdaAndInClassInitializerTest.expect | 14 -- tests/LambdaInVariadicTemplateTest.expect | 18 +- tests/MemberPointer2Test.cpp | 26 +++ tests/MemberPointer2Test.expect | 69 ++++++ tests/PointerToDataMemberTest.cpp | 9 + tests/PointerToDataMemberTest.expect | 11 + tests/PointerToMemberFunctionTest.cpp | 17 ++ tests/PointerToMemberFunctionTest.expect | 29 +++ tests/p0315_4Test.expect | 2 +- tests/p0780_2Test.cerr | 4 +- version.h.in | 2 +- 42 files changed, 643 insertions(+), 212 deletions(-) create mode 100644 tests/DeductionGuide2Test.cpp create mode 100644 tests/DeductionGuide2Test.expect create mode 100644 tests/DependentTemplateParameterTest.cpp create mode 100644 tests/DependentTemplateParameterTest.expect create mode 100644 tests/FunctionPointerTest.cpp create mode 100644 tests/FunctionPointerTest.expect create mode 100644 tests/FunctionProtoTypeTest.cpp create mode 100644 tests/FunctionProtoTypeTest.expect create mode 100644 tests/Issue723.cpp create mode 100644 tests/Issue723.expect create mode 100644 tests/Issue738.cpp create mode 100644 tests/Issue738.expect create mode 100644 tests/MemberPointer2Test.cpp create mode 100644 tests/MemberPointer2Test.expect create mode 100644 tests/PointerToDataMemberTest.cpp create mode 100644 tests/PointerToDataMemberTest.expect create mode 100644 tests/PointerToMemberFunctionTest.cpp create mode 100644 tests/PointerToMemberFunctionTest.expect diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a317003a..aeae4bd1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ on: env: CMAKE_VERSION: 3.29.0 NINJA_VERSION: 1.11.1 - LLVM_VERSION: 20.1.0 + LLVM_VERSION: 21.1.0 NINJA_STATUS: "[%f/%t %o/sec] " jobs: @@ -32,7 +32,7 @@ jobs: name: "Linux Clang - Format check", os: ubuntu-22.04, build_type: Release, - cformat_name: 'clang-format-20' + cformat_name: 'clang-format-21' } steps: @@ -45,7 +45,7 @@ jobs: run: | wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh - sudo ./llvm.sh 20 + sudo ./llvm.sh 21 sudo apt-get install ${{ matrix.config.cformat_name }} - name: clang-format check @@ -68,11 +68,11 @@ jobs: config: # AppleClang - { - name: "Clang 20 / LLVM 20 @ macOS Release", + name: "Clang 21 / LLVM 21 @ macOS Release", os: macos-14, build_type: Release, cxx: "clang++", - llvm_version: "20.1.0", + llvm_version: "21.1.0", llvm_config: "llvm-config", coverage: "No", static: "No", @@ -87,11 +87,11 @@ jobs: # AppleClang - { - name: "Clang 20 / LLVM 20 @ macOS Debug", + name: "Clang 21 / LLVM 21 @ macOS Debug", os: macos-14, build_type: Release, cxx: "clang++", - llvm_version: "20.1.0", + llvm_version: "21.1.0", llvm_config: "llvm-config", coverage: "No", static: "No", @@ -106,11 +106,11 @@ jobs: # AppleClang - { - name: "Clang 20 / LLVM 20 @ macOS Coverage & Debug", + name: "Clang 21 / LLVM 21 @ macOS Coverage & Debug", os: macos-14, build_type: Release, cxx: "clang++", - llvm_version: "20.1.0", + llvm_version: "21.1.0", llvm_config: "llvm-config", coverage: "Yes", static: "No", @@ -124,11 +124,11 @@ jobs: # # MSVC 2019 # - { - # name: "MSVC 2022 / LLVM 20 @ Windows Release", + # name: "MSVC 2022 / LLVM 21 @ Windows Release", # os: windows-2022, # build_type: Release, # cxx: "cl", - # llvm_version: "20.1.0", + # llvm_version: "21.1.0", # llvm_config: "current/bin/llvm-config.exe", # static: "Yes", # debug: "No", @@ -143,11 +143,11 @@ jobs: # # MSVC 2019 # - { - # name: "MSVC 2022 / LLVM 20 @ Windows Debug", + # name: "MSVC 2022 / LLVM 21 @ Windows Debug", # os: windows-2022, # build_type: Release, # cxx: "cl", - # llvm_version: "20.1.0", + # llvm_version: "21.1.0", # llvm_config: "current/bin/llvm-config.exe", # static: "Yes", # debug: "Yes", @@ -161,11 +161,11 @@ jobs: # # MSVC 2019 # - { - # name: "MSVC 2022 / LLVM 20 @ Windows Code Coverage & Debug", + # name: "MSVC 2022 / LLVM 21 @ Windows Code Coverage & Debug", # os: windows-2022, # build_type: Release, # cxx: "clang-cl.exe", - # llvm_version: "20.1.0", + # llvm_version: "21.1.0", # llvm_config: "current/bin/llvm-config.exe", # coverage: "Yes", # static: "Yes", @@ -462,13 +462,13 @@ jobs: - ubuntu-22.04-arm config: - # GCC 14 / LLVM 20 + # GCC 16 / LLVM 21 - { - name: "GCC 14 / LLVM 20 @ Ubuntu Release", + name: "GCC 16 / LLVM 21 @ Ubuntu Release", build_type: Release, - cxx: "g++-14", - llvm_version: "20.1.0", - llvm_config: "/usr/bin/llvm-config-20", + cxx: "g++-16", + llvm_version: "21.1.0", + llvm_config: "/usr/bin/llvm-config-21", coverage: "No", static: "Yes", debug: "No", @@ -481,13 +481,13 @@ jobs: docs: "Yes", } - # GCC 14 / LLVM 20 + # GCC 16 / LLVM 21 - { - name: "GCC 14 / LLVM 20 @ Ubuntu Code Coverage & Debug", + name: "GCC 16 / LLVM 21 @ Ubuntu Code Coverage & Debug", build_type: Release, - cxx: "g++-14", - llvm_version: "20.1.0", - llvm_config: "/usr/bin/llvm-config-20", + cxx: "g++-16", + llvm_version: "21.1.0", + llvm_config: "/usr/bin/llvm-config-21", coverage: "Yes", static: "No", debug: "Yes", @@ -498,13 +498,13 @@ jobs: archive_name: "insights-ubuntu", } - # GCC 14 / LLVM 20 + # GCC 16 / LLVM 21 - { - name: "GCC 14 / LLVM 20 @ Ubuntu Code Coverage (libc++)", + name: "GCC 16 / LLVM 21 @ Ubuntu Code Coverage (libc++)", build_type: Release, - cxx: "g++-14", - llvm_version: "20.1.0", - llvm_config: "/usr/bin/llvm-config-20", + cxx: "g++-16", + llvm_version: "21.1.0", + llvm_config: "/usr/bin/llvm-config-21", coverage: "Yes", static: "No", debug: "Yes", @@ -630,13 +630,13 @@ jobs: - amd64 config: - # GCC 14 / LLVM 20 + # GCC 16 / LLVM 21 - { - name: "GCC 14 / LLVM 20 @ Ubuntu Release", + name: "GCC 16 / LLVM 21 @ Ubuntu Release", build_type: Release, - cxx: "g++-14", - llvm_version: "20.1.0", - llvm_config: "/usr/bin/llvm-config-20", + cxx: "g++-16", + llvm_version: "21.1.0", + llvm_config: "/usr/bin/llvm-config-21", coverage: "No", static: "Yes", debug: "No", diff --git a/ASTHelpers.cpp b/ASTHelpers.cpp index acbe0e0b..e0f8a938 100644 --- a/ASTHelpers.cpp +++ b/ASTHelpers.cpp @@ -385,7 +385,12 @@ FunctionBase(std::string_view name, QualType returnType, const params_vector& pa false, false, ConstexprSpecKind::Unspecified, - nullptr); +#if IS_CLANG_NEWER_THAN(20) + AssociatedConstraint {} +#else + nullptr +#endif + ); fdd->setImplicit(true); SmallVector paramVarDecls{}; @@ -695,7 +700,11 @@ CXXNewExpr* New(ArrayRef placementArgs, const Expr* expr, QualType t) false, nullptr, nullptr, +#if IS_CLANG_NEWER_THAN(20) + ImplicitAllocationParameters{AlignedAllocationMode::Yes}, +#else true, +#endif false, placementArgs, SourceRange{}, diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f947177..25b90fe7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ option(INSIGHTS_STATIC "Use static linking" Off) set(INSIGHTS_LLVM_CONFIG "llvm-config" CACHE STRING "LLVM config executable to use") -set(INSIGHTS_MIN_LLVM_MAJOR_VERSION 20) +set(INSIGHTS_MIN_LLVM_MAJOR_VERSION 21) set(INSIGHTS_MIN_LLVM_VERSION ${INSIGHTS_MIN_LLVM_MAJOR_VERSION}.0) if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) diff --git a/CodeGenerator.cpp b/CodeGenerator.cpp index dae468ac..92abe0a9 100644 --- a/CodeGenerator.cpp +++ b/CodeGenerator.cpp @@ -42,8 +42,8 @@ namespace ranges = std::ranges; //----------------------------------------------------------------------------- namespace clang::insights { -#define BUILD_OPT_AND(name, param) std::function name = [](param t) -> MyOptional -#define BUILD_OPT_AND_O(name, param, ret) std::function name = [](param t) -> MyOptional +#define BUILD_OPT_AND(name, param) std::function name = [](param t)->MyOptional +#define BUILD_OPT_AND_O(name, param, ret) std::function name = [](param t)->MyOptional BUILD_OPT_AND(IsPointer, QualType) { @@ -1412,7 +1412,6 @@ void CodeGenerator::InsertArg(const VarDecl* stmt) // } } else { - mProcessingVarDecl = false; BackupAndRestore _{mProcessingVarDecl, true}; if(MyOptional initList{dyn_cast_or_null(init)}; @@ -2398,18 +2397,20 @@ void CodeGenerator::InsertArg(const ImplicitCastExpr* stmt) } else { auto castName{GetCastName(castKind)}; const QualType castDestType{[&] { - const auto type{stmt->getType()}; + auto type{stmt->getType()}; + + // In case of a dependent type the canonical type doesn't know the parameters name. + if(not type->isDependentType()) { + type = type.getCanonicalType(); + } // In at least the case a structured bindings the compiler adds xvalue casts but the && is missing to // make it valid C++. if(VK_XValue == stmt->getValueKind()) { - return GetGlobalAST().getRValueReferenceType(type.getCanonicalType()); - } else if(type->isDependentType()) { // In case of a dependent type the canonical type doesn't know the - // parameters name. - return type; + return GetGlobalAST().getRValueReferenceType(type); } - return type.getCanonicalType(); + return type; }()}; FormatCast(castName, castDestType, subExpr, castKind); @@ -3178,16 +3179,21 @@ void CodeGenerator::InsertArg(const TypeAliasDecl* stmt) mOutputFormatHelper.Append(stream.str()); InsertTemplateArgs(*templateSpecializationType); - } else if(auto* dependentTemplateSpecializationType = - underlyingType->getAs()) { - mOutputFormatHelper.Append(GetElaboratedTypeKeyword(dependentTemplateSpecializationType->getKeyword())); + } else if(auto* depSpecType = underlyingType->getAs()) { + mOutputFormatHelper.Append(GetElaboratedTypeKeyword(depSpecType->getKeyword())); - InsertNamespace(dependentTemplateSpecializationType->getQualifier()); +#if IS_CLANG_NEWER_THAN(20) + InsertNamespace(depSpecType->getDependentTemplateName().getQualifier()); - mOutputFormatHelper.Append(kwTemplateSpace, dependentTemplateSpecializationType->getIdentifier()->getName()); + mOutputFormatHelper.Append(kwTemplateSpace, GetName(depSpecType->getDependentTemplateName())); +#else + InsertNamespace(depSpecType->getQualifier()); + + mOutputFormatHelper.Append(kwTemplateSpace, depSpecType->getIdentifier()->getName()); +#endif - InsertTemplateArgs(*dependentTemplateSpecializationType); + InsertTemplateArgs(*depSpecType); } else { mOutputFormatHelper.Append(GetName(underlyingType)); @@ -3802,6 +3808,11 @@ void CodeGenerator::InsertAttribute(const Attr& attr) // skip this custom clang attribute RETURN_IF(attr::NoInline == attr.getKind()); +#if IS_CLANG_NEWER_THAN(20) + // skip this custom clang attribute + RETURN_IF(attr::InferredNoReturn == attr.getKind()); +#endif + // Clang's printPretty misses the parameter pack ellipsis. Hence treat this special case here. if(const auto* alignedAttr = dyn_cast_or_null(&attr)) { auto insert = [&](const QualType type, const TemplateTypeParmType* tmplTypeParam) { @@ -4460,7 +4471,7 @@ void CodeGenerator::InsertArg(const CXXStdInitializerListExpr* stmt) auto internalListName = MakeLineColumnName(GetGlobalAST().getSourceManager(), stmt->getBeginLoc(), BuildInternalVarName("list"sv)); - ofm.Append(modifiers, GetTypeNameAsParameter(subExpr->getType(), internalListName)); + ofm.Append(modifiers, GetTypeNameAsParameter(subExpr->getType().getCanonicalType(), internalListName)); CodeGeneratorVariant codeGenerator{ofm}; codeGenerator->InsertArg(subExpr); ofm.AppendSemiNewLine(); @@ -4637,11 +4648,19 @@ void CodeGenerator::InsertTemplateArg(const TemplateArgument& arg) if(const auto* tmplDecl = arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl()) { mOutputFormatHelper.Append(GetName(*tmplDecl, QualifiedName::Yes)); +#if IS_CLANG_NEWER_THAN(20) + } else if(const auto* depName = arg.getAsTemplateOrTemplatePattern().getAsDependentTemplateName(); + depName->getName().getIdentifier()) { + InsertNamespace(depName->getQualifier()); + + mOutputFormatHelper.Append(kwTemplateSpace, GetName(*depName)); +#else } else if(const auto* depName = arg.getAsTemplateOrTemplatePattern().getAsDependentTemplateName(); depName->isIdentifier()) { InsertNamespace(depName->getQualifier()); mOutputFormatHelper.Append(kwTemplateSpace, depName->getIdentifier()->getName()); +#endif } else { ToDo(arg, mOutputFormatHelper); } @@ -4834,7 +4853,17 @@ void CodeGenerator::InsertConceptConstraint(const TemplateParameterList& tmplDec void CodeGenerator::InsertConceptConstraint(const FunctionDecl* tmplDecl) { SmallVector constraints{}; + +#if IS_CLANG_NEWER_THAN(20) + SmallVector assocConstraints{}; + tmplDecl->getAssociatedConstraints(assocConstraints); + + for(auto& e : assocConstraints) { + constraints.push_back(e.ConstraintExpr); + } +#else tmplDecl->getAssociatedConstraints(constraints); +#endif InsertConceptConstraint(constraints, InsertInline::Yes); } diff --git a/InsightsHelpers.cpp b/InsightsHelpers.cpp index b5d31b06..a48d4ab5 100644 --- a/InsightsHelpers.cpp +++ b/InsightsHelpers.cpp @@ -133,7 +133,13 @@ struct CppInsightsPrintingPolicy : PrintingPolicy Alignof = true; ConstantsAsWritten = true; AnonymousTagLocations = false; // does remove filename and line for from lambdas in parameters - PrintCanonicalTypes = InsightsCanonicalTypes::Yes == insightsCanonicalTypes; +#if IS_CLANG_NEWER_THAN(20) + PrintAsCanonical +#else + PrintCanonicalTypes + +#endif + = InsightsCanonicalTypes::Yes == insightsCanonicalTypes; CppInsightsUnqualified = (Unqualified::Yes == unqualified); CppInsightsSuppressScope = supressScope; @@ -162,9 +168,7 @@ BuildNamespace(std::string& fullNamespace, const NestedNameSpecifier* stmt, cons { RETURN_IF(not stmt); - if(const auto* prefix = stmt->getPrefix(); - prefix and not((NestedNameSpecifier::TypeSpecWithTemplate == stmt->getKind()) and - isa(stmt->getAsType()))) { + if(const auto* prefix = stmt->getPrefix()) { BuildNamespace(fullNamespace, prefix, ignoreNamespace); } @@ -178,14 +182,15 @@ BuildNamespace(std::string& fullNamespace, const NestedNameSpecifier* stmt, cons break; case NestedNameSpecifier::NamespaceAlias: fullNamespace.append(stmt->getAsNamespaceAlias()->getName()); break; - +#if IS_CLANG_NEWER_THAN(20) +#else case NestedNameSpecifier::TypeSpecWithTemplate: if(auto* dependentSpecType = stmt->getAsType()->getAs()) { fullNamespace.append(GetElaboratedTypeKeyword(dependentSpecType->getKeyword())); } [[fallthrough]]; - +#endif case NestedNameSpecifier::TypeSpec: fullNamespace.append(GetUnqualifiedScopelessName(stmt->getAsType(), InsightsSuppressScope::Yes)); // The template parameters are already contained in the type we inserted above. @@ -448,20 +453,23 @@ class SimpleTypePrinter bool mScanningArrayDimension{}; //!< Only the outer most ConstantArrayType handles the array dimensions and size std::string mScope{}; //!< A scope coming from an ElaboratedType which is used for a //!< ClassTemplateSpecializationDecl if there is no other scope + bool mTmplParamTypeRes{}; //!< When processing FunctionProtoType parameters we need to get the identifiers bool HandleType(const TemplateTypeParmType* type) { - const TemplateTypeParmDecl* decl = type->getDecl(); - - if((nullptr == type->getIdentifier()) or + if(const TemplateTypeParmDecl* decl = type->getDecl(); + (nullptr == type->getIdentifier()) or (decl and decl->isImplicit()) /* this fixes auto operator()(type_parameter_0_0 container) const */) { AppendTemplateTypeParamName(mData, decl, true, type); return true; + + } else if(nullptr != type->getIdentifier()) { + mData.Append(type->getIdentifier()->getName()); } - return false; + return mTmplParamTypeRes; } bool HandleType(const LValueReferenceType* type) @@ -480,17 +488,32 @@ class SimpleTypePrinter bool HandleType(const PointerType* type) { - mDataAfter += " *"sv; + const bool ret = HandleType(type->getPointeeType().getTypePtrOrNull()); - return HandleType(type->getPointeeType().getTypePtrOrNull()); + if(not mData.empty() and (mData.GetString().back() != ' ') and not isa(type->getPointeeType())) { + mData.Append(' '); + } + + mData.Append("*"sv); + + HandleTypeAfter(type); + + return ret; } bool HandleType(const InjectedClassNameType* type) { return HandleType(type->getInjectedTST()); } bool HandleType(const RecordType* type) { - /// In case one of the template parameters is a lambda we need to insert the made up name. + OutputFormatHelper ofm{}; + FinalAction _{[&] { mData.Append(ofm); }}; + if(const auto* tt = dyn_cast_or_null(type->getDecl())) { + // Always get potential template arguments + CodeGenerator codeGenerator{ofm}; + codeGenerator.InsertTemplateArgs(*tt); + + /// In case one of the template parameters is a lambda we need to insert the made up name. if(const auto* identifierName = mType.getBaseTypeIdentifier()) { const auto& scope = GetScope(type->getDecl()->getDeclContext()); @@ -502,19 +525,18 @@ class SimpleTypePrinter } mData.Append(identifierName->getName()); - CodeGenerator codeGenerator{mData}; - codeGenerator.InsertTemplateArgs(*tt); return true; } - } else if(const auto* cxxRecordDecl = type->getAsCXXRecordDecl()) { + } + + if(const auto* cxxRecordDecl = type->getAsCXXRecordDecl()) { // Special handling for dependent types. For example, ClassOperatorHandler7Test.cpp A<...* >::B. if(type->isDependentType()) { std::string context{GetDeclContext(type->getDecl()->getDeclContext())}; if(not context.empty()) { - mData.Append(std::move(context)); - mData.Append(cxxRecordDecl->getName()); + mData.Append(std::move(context), cxxRecordDecl->getName()); return true; } @@ -527,7 +549,7 @@ class SimpleTypePrinter } // Handle anonymous struct or union. - if(IsAnonymousStructOrUnion(cxxRecordDecl)) { + else if(IsAnonymousStructOrUnion(cxxRecordDecl)) { mData.Append(GetAnonymStructOrUnionName(*cxxRecordDecl)); return true; @@ -564,11 +586,19 @@ class SimpleTypePrinter bool HandleType(const DependentTemplateSpecializationType* type) { +#if IS_CLANG_NEWER_THAN(20) + mData.Append(GetElaboratedTypeKeyword(type->getKeyword()), + GetNestedName(type->getDependentTemplateName().getQualifier()), + kwTemplateSpace, + GetName(type->getDependentTemplateName())); +#else mData.Append(GetElaboratedTypeKeyword(type->getKeyword()), GetNestedName(type->getQualifier()), kwTemplateSpace, type->getIdentifier()->getName()); +#endif + CodeGenerator codeGenerator{mData}; codeGenerator.InsertTemplateArgs(*type); @@ -590,57 +620,81 @@ class SimpleTypePrinter } } - /// This is a specialty discovered with #188_2. In some cases there is a `TemplateTypeParmDecl` which has no - /// identifier name. Then it will end up as `type-parameter-...`. At least in #188_2: _Head_base<_Idx, - /// type_parameter_0_1, true> the repetition of the template specialization arguments is not required. - /// `hasNoName` tries to detect this case and does then print the name of the template only. - const bool hasNoName{[&] { - for(const auto& arg : type->template_arguments()) { - StringStream sstream{}; - sstream.Print(arg); + return false; + } - if(Contains(sstream.str(), "type-parameter"sv)) { - return true; - } - } + bool HandleType(const MemberPointerType* type) + { + const auto* pointeeType{type->getPointeeType().getTypePtrOrNull()}; + { + BackupAndRestore _{mSkipSpace, + (not type->isMemberFunctionPointer() and (isa(pointeeType) or + isa(pointeeType)))}; + HandleType(pointeeType); + } - return false; - }()}; + // Other types seem to add the otherwise missing space after the typename + if(not type->isMemberFunctionPointer() and + (isa(pointeeType) or isa(pointeeType))) { + mData.Append(' '); + } - if(hasNoName) { - StringStream sstream{}; - sstream.Print(*type); + const bool ret = +#if IS_CLANG_NEWER_THAN(20) + true; - mData.Append(sstream.str()); + mData.Append(GetNestedName(type->getQualifier())); - return true; - } + mData.Append("*"sv); +#else + HandleType(type->getClass()); - return false; + mData.Append("::*)"sv); +#endif + + HandleTypeAfter(pointeeType); + + return ret; } - bool HandleType(const MemberPointerType* type) + bool HandleType(const FunctionProtoType* type) { - HandleType(type->getPointeeType().getTypePtrOrNull()); + BackupAndRestore _{mSkipSpace, true}; - mData.Append('('); + const bool ret = HandleType(type->getReturnType().getTypePtrOrNull()); + mData.Append(" ("sv); - const bool ret = HandleType(type->getClass()); - - mData.Append("::*)"sv); + return ret; + } - HandleTypeAfter(type->getPointeeType().getTypePtrOrNull()); + bool HandleType(const ParenType* type) + { + const bool ret = HandleType(type->getInnerType().getTypePtrOrNull()); + if(not isa(type->getInnerType())) { + mData.Append('('); + } return ret; } - bool HandleType(const FunctionProtoType* type) { return HandleType(type->getReturnType().getTypePtrOrNull()); } + void HandleTypeAfter(const PointerType* type) { HandleTypeAfter(type->getPointeeType().getTypePtrOrNull()); } + + void HandleTypeAfter(const ParenType* type) + { + if(not isa(type->getInnerType())) { + mData.Append(')'); + } + + HandleTypeAfter(type->getInnerType().getTypePtrOrNull()); + } void HandleTypeAfter(const FunctionProtoType* type) { - mData.Append('('); + BackupAndRestore _{mTmplParamTypeRes, true}; + BackupAndRestore _1{mSkipSpace, true}; + + mData.Append(")("sv); - mSkipSpace = true; for(OnceFalse needsComma{}; const auto& t : type->getParamTypes()) { if(needsComma) { mData.Append(", "sv); @@ -649,8 +703,6 @@ class SimpleTypePrinter HandleType(t.getTypePtrOrNull()); } - mSkipSpace = false; - mData.Append(')'); if(not type->getMethodQuals().empty()) { @@ -675,15 +727,6 @@ class SimpleTypePrinter bool HandleType(const TypedefType* type) { if(const auto* decl = type->getDecl()) { - /// Another filter place for type-parameter where it is contained in the FQN but leads to none compiling - /// code. Remove it to keep the code valid. - if(Contains(decl->getQualifiedNameAsString(), "type-parameter"sv)) { - auto* identifierInfo = decl->getIdentifier(); - mData.Append(identifierInfo->getName()); - - return true; - } - return HandleType(decl->getUnderlyingType().getTypePtrOrNull()); } @@ -729,13 +772,10 @@ class SimpleTypePrinter // A DecltypeType in a template definition is unevaluated and refers ti itself. This check ensures, that in such // a situation no expansion is performed. if(not isa_and_nonnull(type->desugar().getTypePtrOrNull())) { - const bool skipSpace{mSkipSpace}; - mSkipSpace = true; + BackupAndRestore _{mSkipSpace, true}; HandleType(type->desugar().getTypePtrOrNull()); - mSkipSpace = skipSpace; - // if we hit a DecltypeType always use the expanded version to support things like a DecltypeType wrapped in // an LValueReferenceType return true; @@ -763,6 +803,7 @@ class SimpleTypePrinter HANDLE_TYPE(FunctionProtoType); HANDLE_TYPE(PointerType); + HANDLE_TYPE(ParenType); HANDLE_TYPE(LValueReferenceType); HANDLE_TYPE(RValueReferenceType); HANDLE_TYPE(TemplateTypeParmType); @@ -793,7 +834,9 @@ class SimpleTypePrinter } if(nullptr != type) { + HANDLE_TYPE(PointerType); HANDLE_TYPE(FunctionProtoType); + HANDLE_TYPE(ParenType); } } @@ -857,24 +900,24 @@ static std::string GetName(QualType t, (isa(t.getTypePtrOrNull())) ? InsightsCanonicalTypes::Yes : InsightsCanonicalTypes::No}; - QualType tt = t; - - if(const auto* et = tt->getAs()) { - if((nullptr == et->getQualifier()) and (nullptr == et->getOwnedTagDecl())) { - const auto quals = tt.getLocalFastQualifiers(); - tt = et->getNamedType(); - tt.setLocalFastQualifiers(quals); - } - } - if(SimpleTypePrinter st{t, printingPolicy}; st.GetTypeString()) { return ScopeHandler::RemoveCurrentScope(st.GetString()); + } + + // To get the namespace handling right we need to look into the ElaboratedType in some cases. + // However, only do that, if the type it not a dependent type. A dependent type might cause type-parameter stuff. + if(const auto* et = t->getAs(); + et and (nullptr == et->getQualifier()) and (nullptr == et->getOwnedTagDecl()) and not et->isDependentType()) { + const auto quals = t.getLocalFastQualifiers(); + t = et->getNamedType(); + t.setLocalFastQualifiers(quals); + } - } else if(true == printingPolicy.CppInsightsUnqualified) { - return ScopeHandler::RemoveCurrentScope(GetAsCPPStyleString(tt.getUnqualifiedType(), printingPolicy)); + if(true == printingPolicy.CppInsightsUnqualified) { + t = t.getUnqualifiedType(); } - return ScopeHandler::RemoveCurrentScope(GetAsCPPStyleString(tt, printingPolicy)); + return ScopeHandler::RemoveCurrentScope(GetAsCPPStyleString(t, printingPolicy)); } } // namespace details //----------------------------------------------------------------------------- @@ -887,7 +930,11 @@ static bool HasOverload(const FunctionDecl* fd) LookupResult result{sema, ncfd->getDeclName(), {}, Sema::LookupOrdinaryName}; if(sema.LookupName(result, sema.getScopeForContext(ncfd->getDeclContext()))) { +#if IS_CLANG_NEWER_THAN(20) + return LookupResultKind::FoundOverloaded == result.getResultKind(); +#else return LookupResult::FoundOverloaded == result.getResultKind(); +#endif } return false; @@ -1092,6 +1139,14 @@ static std::string GetTemplateParameterPackArgumentName(std::string_view name, c } //----------------------------------------------------------------------------- +#if IS_CLANG_NEWER_THAN(20) +StringRef GetName(const DependentTemplateStorage& name) +{ + return name.getName().getIdentifier()->getName(); +} +#endif +//----------------------------------------------------------------------------- + std::string GetName(const NamedDecl& nd, const QualifiedName qualifiedName) { std::string name{}; diff --git a/InsightsHelpers.h b/InsightsHelpers.h index 75cd2a28..be6dfbd3 100644 --- a/InsightsHelpers.h +++ b/InsightsHelpers.h @@ -108,6 +108,7 @@ std::string GetPlainName(const DeclRefExpr& DRE); std::string GetName(const DeclRefExpr& declRefExpr); std::string GetName(const VarDecl& VD); std::string GetName(const TemplateParamObjectDecl& decl); +StringRef GetName(const class DependentTemplateStorage& name); //----------------------------------------------------------------------------- STRONG_BOOL(QualifiedName); diff --git a/scripts/prepare-release.py b/scripts/prepare-release.py index 26564046..3499d692 100755 --- a/scripts/prepare-release.py +++ b/scripts/prepare-release.py @@ -14,8 +14,8 @@ def main(): versionH = open('version.h.in', 'r').read() - oldClangStable = '19' - newClangStable = '20' + oldClangStable = '20' + newClangStable = '21' newInsightsVersion = f'{newClangStable}.1' oldInsightsVersion = re.search(r'INSIGHTS_VERSION\s+"(.*?)"', versionH, re.DOTALL | re.MULTILINE).group(1) @@ -63,7 +63,7 @@ def main(): open(cppInsightsDockerBaseFile, 'w').write(dockerFile) - gitTag = f'v_{oldInsightsVersion}' + gitTag = f'v_{newClangStable}' print(f' - Tagging {gitTag}') cmd = ['git', 'tag', gitTag, 'main'] diff --git a/tests/DeductionGuide2Test.cpp b/tests/DeductionGuide2Test.cpp new file mode 100644 index 00000000..ba2fe355 --- /dev/null +++ b/tests/DeductionGuide2Test.cpp @@ -0,0 +1,12 @@ +template +class Data { +public: + Data(const T& t) {} +}; + +Data(const char *) -> Data; +Data(int) -> Data ; + +int main() { + Data d1{5}; +} diff --git a/tests/DeductionGuide2Test.expect b/tests/DeductionGuide2Test.expect new file mode 100644 index 00000000..6e8df37d --- /dev/null +++ b/tests/DeductionGuide2Test.expect @@ -0,0 +1,36 @@ +template +class Data +{ + + public: + inline Data(const T & t) + { + } + +}; + +/* First instantiated from: DeductionGuide2Test.cpp:11 */ +#ifdef INSIGHTS_USE_TEMPLATE +template<> +class Data +{ + + public: + inline Data(const long & t) + { + } + +}; + +#endif + + + +Data(const char *) -> Data; +Data(int) -> Data; + +int main() +{ + Data d1 = Data{5}; + return 0; +} diff --git a/tests/DependentTemplateParameterTest.cpp b/tests/DependentTemplateParameterTest.cpp new file mode 100644 index 00000000..09c752da --- /dev/null +++ b/tests/DependentTemplateParameterTest.cpp @@ -0,0 +1,9 @@ +// cmdline:-std=c++23 + +template +auto Fun(T val) +{ + return val; +} + +auto x = Fun(3); diff --git a/tests/DependentTemplateParameterTest.expect b/tests/DependentTemplateParameterTest.expect new file mode 100644 index 00000000..62ab2b6d --- /dev/null +++ b/tests/DependentTemplateParameterTest.expect @@ -0,0 +1,16 @@ +template +auto Fun(T val) +{ + return static_cast(val); +} + +#ifdef INSIGHTS_USE_TEMPLATE +template<> +int Fun(int val) +{ + return static_cast(val); +} +#endif + + +int x = Fun(3); diff --git a/tests/EduCfrontTest17.cerr b/tests/EduCfrontTest17.cerr index d8be8a7c..d15f8e43 100644 --- a/tests/EduCfrontTest17.cerr +++ b/tests/EduCfrontTest17.cerr @@ -10,22 +10,22 @@ | ^~~ .tmp.cpp:14:12: error: use of undeclared identifier 'BT' 14 | inline Foo * Constructor_Foo(Foo * __this) - | ^ + | ^~ .tmp.cpp:14:34: error: use of undeclared identifier 'BT' 14 | inline Foo * Constructor_Foo(Foo * __this) - | ^ + | ^~ .tmp.cpp:14:42: error: use of undeclared identifier 'BT' 14 | inline Foo * Constructor_Foo(Foo * __this) - | ^ + | ^~ .tmp.cpp:19:12: error: use of undeclared identifier 'BT' 19 | inline Foo * Constructor_Foo(Foo * __this, BT v) - | ^ + | ^~ .tmp.cpp:19:34: error: use of undeclared identifier 'BT' 19 | inline Foo * Constructor_Foo(Foo * __this, BT v) - | ^ + | ^~ .tmp.cpp:19:42: error: use of undeclared identifier 'BT' 19 | inline Foo * Constructor_Foo(Foo * __this, BT v) - | ^ + | ^~ .tmp.cpp:19:56: error: unknown type name 'BT' 19 | inline Foo * Constructor_Foo(Foo * __this, BT v) | ^ diff --git a/tests/EduCfrontTestLifeTime2.cerr b/tests/EduCfrontTestLifeTime2.cerr index 13f07306..681a596f 100644 --- a/tests/EduCfrontTestLifeTime2.cerr +++ b/tests/EduCfrontTestLifeTime2.cerr @@ -6,13 +6,13 @@ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .tmp.cpp:103:20: error: use of undeclared identifier 'tt' 103 | Destructor_Test(&tt); - | ^ + | ^~ .tmp.cpp:104:20: error: use of undeclared identifier 't' 104 | Destructor_Test(&t); | ^ .tmp.cpp:105:20: error: use of undeclared identifier 'tt' 105 | Destructor_Test(&tt); - | ^ + | ^~ .tmp.cpp:106:20: error: use of undeclared identifier 't' 106 | Destructor_Test(&t); | ^ diff --git a/tests/FoldExpressionTest.cpp b/tests/FoldExpressionTest.cpp index 0229fe84..3a0af241 100644 --- a/tests/FoldExpressionTest.cpp +++ b/tests/FoldExpressionTest.cpp @@ -1,3 +1,4 @@ +// cmdline:-Wno-parentheses // + - * / % ^ & | = < > << >> += -= *= /= %= ^= &= |= <<= >>= == != <= >= && || , .* ->* // Tests for some of the 32 operators diff --git a/tests/FunctionPointerTest.cpp b/tests/FunctionPointerTest.cpp new file mode 100644 index 00000000..30b0b08b --- /dev/null +++ b/tests/FunctionPointerTest.cpp @@ -0,0 +1,28 @@ +template +struct FunctionArgs{}; + + +template +struct FunctionArgs {}; + + + +template +struct FunctionArgs {}; + + +template +struct myString +{ +}; + +using string = myString; + +struct Test +{ + string Fun(double) const { return {}; } +}; + + +FunctionArgs a; + diff --git a/tests/FunctionPointerTest.expect b/tests/FunctionPointerTest.expect new file mode 100644 index 00000000..c331540a --- /dev/null +++ b/tests/FunctionPointerTest.expect @@ -0,0 +1,54 @@ +template +struct FunctionArgs +{ +}; + +/* First instantiated from: FunctionPointerTest.cpp:27 */ +#ifdef INSIGHTS_USE_TEMPLATE +template<> +struct FunctionArgs (Test::*)(double) const> +{ + // inline constexpr FunctionArgs() noexcept = default; +}; + +#endif + +template +struct FunctionArgs +{ +}; + + +template +struct FunctionArgs +{ +}; + + +template +struct myString +{ +}; + +/* First instantiated from: FunctionPointerTest.cpp:23 */ +#ifdef INSIGHTS_USE_TEMPLATE +template<> +struct myString +{ +}; + +#endif + +using string = myString; + +struct Test +{ + inline myString Fun(double) const + { + return {}; + } + +}; + + +FunctionArgs (Test::*)(double) const> a; diff --git a/tests/FunctionProtoTypeTest.cpp b/tests/FunctionProtoTypeTest.cpp new file mode 100644 index 00000000..addd0298 --- /dev/null +++ b/tests/FunctionProtoTypeTest.cpp @@ -0,0 +1,6 @@ +template +struct FunctionArgs : FunctionArgs {}; + +template +struct FunctionArgs {}; + diff --git a/tests/FunctionProtoTypeTest.expect b/tests/FunctionProtoTypeTest.expect new file mode 100644 index 00000000..098d0f3d --- /dev/null +++ b/tests/FunctionProtoTypeTest.expect @@ -0,0 +1,11 @@ +template +struct FunctionArgs : public FunctionArgs +{ +}; + + +template +struct FunctionArgs +{ +}; + diff --git a/tests/Issue101.expect b/tests/Issue101.expect index 11905977..247826c8 100644 --- a/tests/Issue101.expect +++ b/tests/Issue101.expect @@ -339,7 +339,7 @@ struct compose struct to > { template - using result = compose<>::template template to > >::template result; + using result = compose<>::template to > >::template result; }; #endif @@ -349,7 +349,7 @@ struct compose struct to > { template - using result = compose<>::template template to > >::template result; + using result = compose<>::template to > >::template result; }; #endif @@ -370,7 +370,7 @@ struct compose struct to > { template - using result = compose<>::template template to > >::template result; + using result = compose<>::template to > >::template result; }; #endif @@ -380,7 +380,7 @@ struct compose struct to { template - using result = compose<>::template template to >::template result; + using result = compose<>::template to >::template result; }; #endif @@ -390,7 +390,7 @@ struct compose struct to { template - using result = compose<>::template template to >::template result; + using result = compose<>::template to >::template result; }; #endif @@ -411,7 +411,7 @@ struct compose struct to { template - using result = compose::template template to >::template result; + using result = compose::template to >::template result; }; #endif @@ -421,7 +421,7 @@ struct compose struct to { template - using result = compose::template template to >::template result; + using result = compose::template to >::template result; }; #endif @@ -442,7 +442,7 @@ struct compose struct to { template - using result = compose::template template to >::template result; + using result = compose::template to >::template result; }; #endif diff --git a/tests/Issue102.expect b/tests/Issue102.expect index 411d9e71..8afc1cb3 100644 --- a/tests/Issue102.expect +++ b/tests/Issue102.expect @@ -17,7 +17,7 @@ struct FunctionArgs : public FunctionArgs /* First instantiated from: Issue102.cpp:16 */ #ifdef INSIGHTS_USE_TEMPLATE template<> -struct FunctionArgs<(__lambda_73_4::*)() const> : public FunctionArgsBase, std::allocator >, std::basic_string, std::allocator > > +struct FunctionArgs, std::allocator > (__lambda_73_4::*)(std::basic_string, std::allocator >) const> : public FunctionArgsBase, std::allocator >, std::basic_string, std::allocator > > { }; @@ -33,7 +33,7 @@ struct FunctionArgs : public FunctionArgsBase /* First instantiated from: Issue102.cpp:16 */ #ifdef INSIGHTS_USE_TEMPLATE template<> -struct FunctionArgs<(__lambda_73_4::*)() const> : public FunctionArgsBase, std::allocator >, std::basic_string, std::allocator > > +struct FunctionArgs, std::allocator > (__lambda_73_4::*)(std::basic_string, std::allocator >) const> : public FunctionArgsBase, std::allocator >, std::basic_string, std::allocator > > { }; @@ -49,7 +49,7 @@ struct FunctionArgs : public FunctionArgsBase /* First instantiated from: Issue102.cpp:16 */ #ifdef INSIGHTS_USE_TEMPLATE template<> -struct FunctionArgs<(__lambda_73_4::*)() const> : public FunctionArgsBase, std::allocator >, std::basic_string, std::allocator > > +struct FunctionArgs, std::allocator > (__lambda_73_4::*)(std::basic_string, std::allocator >) const> : public FunctionArgsBase, std::allocator >, std::basic_string, std::allocator > > { }; @@ -57,7 +57,7 @@ struct FunctionArgs<(__lambda_73_4::*)() const> : public FunctionArgsBase -struct FunctionArgs<__lambda_73_4> : public FunctionArgs<(__lambda_73_4::*)() const> +struct FunctionArgs<__lambda_73_4> : public FunctionArgs, std::allocator > (__lambda_73_4::*)(std::basic_string, std::allocator >) const> { }; @@ -73,7 +73,7 @@ struct FunctionArgs<__lambda_74_4> : public FunctionArgs -struct FunctionArgs<__lambda_73_4> : public FunctionArgs<(__lambda_73_4::*)() const> +struct FunctionArgs<__lambda_73_4> : public FunctionArgs, std::allocator > (__lambda_73_4::*)(std::basic_string, std::allocator >) const> { }; @@ -89,7 +89,7 @@ struct FunctionArgs<__lambda_74_4> : public FunctionArgs -struct FunctionArgs<__lambda_73_4> : public FunctionArgs<(__lambda_73_4::*)() const> +struct FunctionArgs<__lambda_73_4> : public FunctionArgs, std::allocator > (__lambda_73_4::*)(std::basic_string, std::allocator >) const> { }; @@ -396,7 +396,7 @@ decltype(auto) test(T && value) inline auto operator()(std::basic_string, std::allocator > value) const { std::operator<<(std::cout, "This is string "); - return operator+(value, " Hi!"); + return std::operator+(value, " Hi!"); } using retType_73_4 = auto (*)(std::string); @@ -472,10 +472,10 @@ int test(int && value) inline std::basic_string, std::allocator > operator()(std::basic_string, std::allocator > value) const { std::operator<<(std::cout, "This is string "); - return operator+(value, " Hi!"); + return std::operator+(value, " Hi!"); } - using retType_73_4 = string (*)(std::string); + using retType_73_4 = basic_string, std::allocator > (*)(std::string); inline constexpr operator retType_73_4 () const noexcept { return __invoke; @@ -550,10 +550,10 @@ int test(const char (&value)[3]) inline std::basic_string, std::allocator > operator()(std::basic_string, std::allocator > value) const { std::operator<<(std::cout, "This is string "); - return operator+(value, " Hi!"); + return std::operator+(value, " Hi!"); } - using retType_73_4 = string (*)(std::string); + using retType_73_4 = basic_string, std::allocator > (*)(std::string); inline constexpr operator retType_73_4 () const noexcept { return __invoke; @@ -638,10 +638,10 @@ std::basic_string, std::allocator > test, std::allocator > operator()(std::basic_string, std::allocator > value) const { std::operator<<(std::cout, "This is string "); - return operator+(value, " Hi!"); + return std::operator+(value, " Hi!"); } - using retType_73_4 = string (*)(std::string); + using retType_73_4 = basic_string, std::allocator > (*)(std::string); inline constexpr operator retType_73_4 () const noexcept { return __invoke; diff --git a/tests/Issue188_2.expect b/tests/Issue188_2.expect index ed826748..c2bc46c3 100644 --- a/tests/Issue188_2.expect +++ b/tests/Issue188_2.expect @@ -56,7 +56,7 @@ namespace mstd { } - inline constexpr _Head_base(const _Head_base &) = default; + inline constexpr _Head_base(const _Head_base<_Idx, _Head, true> &) = default; }; template @@ -72,7 +72,7 @@ namespace mstd { } - inline constexpr _Head_base(const _Head_base &) = default; + inline constexpr _Head_base(const _Head_base<_Idx, _Head, false> &) = default; _Head _M_head_impl; }; @@ -96,13 +96,6 @@ namespace mstd template inline constexpr _Tuple_impl(const _Tuple_impl<2UL, _UElements...> & __in); - - #ifdef INSIGHTS_USE_TEMPLATE - template<> - inline constexpr _Tuple_impl(const _Tuple_impl<2, long> & __in); - #endif - - }; #endif diff --git a/tests/Issue205.expect b/tests/Issue205.expect index b97ceae9..0b7e4afc 100644 --- a/tests/Issue205.expect +++ b/tests/Issue205.expect @@ -22,7 +22,6 @@ class EventContainer private: EventContainer * __this; public: - // inline /*constexpr */ __lambda_6_43 & operator=(const __lambda_6_43 &) /* noexcept */ = delete; // inline /*constexpr */ __lambda_6_43(const __lambda_6_43 &) noexcept = default; // inline /*constexpr */ __lambda_6_43(__lambda_6_43 &&) noexcept = default; __lambda_6_43(EventContainer * _this) diff --git a/tests/Issue205_2.expect b/tests/Issue205_2.expect index 3376bb8c..d8e357fa 100644 --- a/tests/Issue205_2.expect +++ b/tests/Issue205_2.expect @@ -20,7 +20,6 @@ class EventContainer private: EventContainer * __this; public: - // inline /*constexpr */ __lambda_6_43 & operator=(const __lambda_6_43 &) /* noexcept */ = delete; // inline /*constexpr */ __lambda_6_43(const __lambda_6_43 &) noexcept = default; // inline /*constexpr */ __lambda_6_43(__lambda_6_43 &&) noexcept = default; __lambda_6_43(EventContainer * _this) diff --git a/tests/Issue391.expect b/tests/Issue391.expect index a74204ea..ef74d56f 100644 --- a/tests/Issue391.expect +++ b/tests/Issue391.expect @@ -98,7 +98,7 @@ namespace tnt /* First instantiated from: Issue391.cpp:89 */ #ifdef INSIGHTS_USE_TEMPLATE template<> - inline void operator() > >(std::basic_string_view > name, std::string_view my_type::*ptr) + inline void operator() > >(std::basic_string_view > name, std::basic_string_view > my_type::*ptr) { std::operator<<(std::operator<<(std::operator<<(std::operator<<(std::operator<<(std::operator<<(std::operator<<(std::cout, "\t"), type_name > >()), ' '), std::basic_string_view >(name)), " = "), std::basic_string_view >(std::invoke(ptr, this->data))), ";\n"); } diff --git a/tests/Issue41.cerr b/tests/Issue41.cerr index f2e5ec7b..284a9e32 100644 --- a/tests/Issue41.cerr +++ b/tests/Issue41.cerr @@ -6,7 +6,7 @@ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from .tmp.cpp:1: In file included from ... vector:352: -In file included from ... algorithm:1852: +In file included from ... algorithm:1859: ... find_if.h:25:9: error: no matching function for call to object of type '__lambda_12_26' 25 | if (__pred(*__first)) | ^~~~~~ diff --git a/tests/Issue596.expect b/tests/Issue596.expect index 324c3b1a..d48ab288 100644 --- a/tests/Issue596.expect +++ b/tests/Issue596.expect @@ -27,14 +27,6 @@ class Data #endif -template -Data(const T & t) -> Data; - -#ifdef INSIGHTS_USE_TEMPLATE -template<> -Data(const int & t) -> Data; -#endif - Data(const char *) -> Data, std::allocator > >; diff --git a/tests/Issue628.expect b/tests/Issue628.expect index a806644c..fd3fb769 100644 --- a/tests/Issue628.expect +++ b/tests/Issue628.expect @@ -48,7 +48,6 @@ struct mysleep std::coroutine_handle h; std::chrono::duration > d; public: - // inline /*constexpr */ __lambda_20_25 & operator=(const __lambda_20_25 &) /* noexcept */ = delete; // inline /*constexpr */ __lambda_20_25(const __lambda_20_25 &) noexcept = default; // inline /*constexpr */ __lambda_20_25(__lambda_20_25 &&) noexcept = default; __lambda_20_25(const std::chrono::time_point > > & _start, const std::coroutine_handle & _h, const std::chrono::duration > & _d) diff --git a/tests/Issue723.cpp b/tests/Issue723.cpp new file mode 100644 index 00000000..dd9bcec1 --- /dev/null +++ b/tests/Issue723.cpp @@ -0,0 +1,9 @@ +#include +#include + +int main() { + std::map m; + for (const auto& [k, v] : m) { + decltype(k) a = 1; + } +} diff --git a/tests/Issue723.expect b/tests/Issue723.expect new file mode 100644 index 00000000..0234a127 --- /dev/null +++ b/tests/Issue723.expect @@ -0,0 +1,20 @@ +#include +#include + +int main() +{ + std::map, std::allocator >, std::less, std::allocator, std::allocator > > > > m = std::map, std::allocator >, std::less, std::allocator, std::allocator > > > >(); + { + std::map, std::allocator >, std::less, std::allocator, std::allocator > > > > & __range1 = m; + std::__map_iterator, std::allocator > >, std::__tree_node, std::allocator > >, void *> *, long> > __begin1 = __range1.begin(); + std::__map_iterator, std::allocator > >, std::__tree_node, std::allocator > >, void *> *, long> > __end1 = __range1.end(); + for(; operator!=(__begin1, __end1); __begin1.operator++()) { + const std::pair, std::allocator > > & __operator6 = __begin1.operator*(); + const int & k = std::get<0UL>(__operator6); + const std::basic_string, std::allocator > & v = std::get<1UL>(__operator6); + const int a = 1; + } + + } + return 0; +} diff --git a/tests/Issue738.cpp b/tests/Issue738.cpp new file mode 100644 index 00000000..f6bae20b --- /dev/null +++ b/tests/Issue738.cpp @@ -0,0 +1,3 @@ +int x = 0; +int* p = &x; +decltype((p)) e = p; diff --git a/tests/Issue738.expect b/tests/Issue738.expect new file mode 100644 index 00000000..6e5fc569 --- /dev/null +++ b/tests/Issue738.expect @@ -0,0 +1,3 @@ +int x = 0; +int * p = &x; +int * & e = p; diff --git a/tests/LambdaAndInClassInitializerTest.expect b/tests/LambdaAndInClassInitializerTest.expect index 401daf88..33856b27 100644 --- a/tests/LambdaAndInClassInitializerTest.expect +++ b/tests/LambdaAndInClassInitializerTest.expect @@ -32,20 +32,6 @@ class function #endif - - #ifdef INSIGHTS_USE_TEMPLATE - template<> - inline function &>(const function & f); - #endif - - - - #ifdef INSIGHTS_USE_TEMPLATE - template<> - inline function >(function && f); - #endif - - }; #endif diff --git a/tests/LambdaInVariadicTemplateTest.expect b/tests/LambdaInVariadicTemplateTest.expect index a419baa1..b423be3e 100644 --- a/tests/LambdaInVariadicTemplateTest.expect +++ b/tests/LambdaInVariadicTemplateTest.expect @@ -52,7 +52,7 @@ decltype(auto) test(T && value) inline auto operator()(std::basic_string, std::allocator > value) const { std::operator<<(std::cout, "This is string "); - return operator+(value, " Hi!"); + return std::operator+(value, " Hi!"); } using retType_13_4 = auto (*)(std::string); @@ -128,10 +128,10 @@ int test(int && value) inline std::basic_string, std::allocator > operator()(std::basic_string, std::allocator > value) const { std::operator<<(std::cout, "This is string "); - return operator+(value, " Hi!"); + return std::operator+(value, " Hi!"); } - using retType_13_4 = string (*)(std::string); + using retType_13_4 = basic_string, std::allocator > (*)(std::string); inline constexpr operator retType_13_4 () const noexcept { return __invoke; @@ -206,10 +206,10 @@ int test(const char (&value)[3]) inline std::basic_string, std::allocator > operator()(std::basic_string, std::allocator > value) const { std::operator<<(std::cout, "This is string "); - return operator+(value, " Hi!"); + return std::operator+(value, " Hi!"); } - using retType_13_4 = string (*)(std::string); + using retType_13_4 = basic_string, std::allocator > (*)(std::string); inline constexpr operator retType_13_4 () const noexcept { return __invoke; @@ -284,10 +284,10 @@ int test, std::allocator > inline std::basic_string, std::allocator > operator()(std::basic_string, std::allocator > value) const { std::operator<<(std::cout, "This is string "); - return operator+(value, " Hi!"); + return std::operator+(value, " Hi!"); } - using retType_13_4 = string (*)(std::string); + using retType_13_4 = basic_string, std::allocator > (*)(std::string); inline constexpr operator retType_13_4 () const noexcept { return __invoke; @@ -362,10 +362,10 @@ int test(float && value) inline std::basic_string, std::allocator > operator()(std::basic_string, std::allocator > value) const { std::operator<<(std::cout, "This is string "); - return operator+(value, " Hi!"); + return std::operator+(value, " Hi!"); } - using retType_13_4 = string (*)(std::string); + using retType_13_4 = basic_string, std::allocator > (*)(std::string); inline constexpr operator retType_13_4 () const noexcept { return __invoke; diff --git a/tests/MemberPointer2Test.cpp b/tests/MemberPointer2Test.cpp new file mode 100644 index 00000000..590228e3 --- /dev/null +++ b/tests/MemberPointer2Test.cpp @@ -0,0 +1,26 @@ +template +struct myStringView { +}; + +using string_view = myStringView; + +template +struct printer final { + template + void operator()(R T::* ptr) + {} +}; + +struct my_type final { + string_view b; + int i; +}; + +int main() +{ + constexpr my_type t{}; + printer p{}; + p(&my_type::b); + p(&my_type::i); +} + diff --git a/tests/MemberPointer2Test.expect b/tests/MemberPointer2Test.expect new file mode 100644 index 00000000..3f6a989a --- /dev/null +++ b/tests/MemberPointer2Test.expect @@ -0,0 +1,69 @@ +template +struct myStringView +{ +}; + +/* First instantiated from: MemberPointer2Test.cpp:15 */ +#ifdef INSIGHTS_USE_TEMPLATE +template<> +struct myStringView +{ +}; + +#endif + +using string_view = myStringView; + +template +struct printer final +{ + template + inline void operator()(R T::*ptr) + { + } +}; + +/* First instantiated from: MemberPointer2Test.cpp:22 */ +#ifdef INSIGHTS_USE_TEMPLATE +template<> +struct printer final +{ + template + inline void operator()(R my_type::*ptr); + + /* First instantiated from: MemberPointer2Test.cpp:23 */ + #ifdef INSIGHTS_USE_TEMPLATE + template<> + inline void operator() >(myStringView my_type::*ptr) + { + } + #endif + + + /* First instantiated from: MemberPointer2Test.cpp:24 */ + #ifdef INSIGHTS_USE_TEMPLATE + template<> + inline void operator()(int my_type::*ptr) + { + } + #endif + +}; + +#endif + +struct my_type final +{ + myStringView b; + int i; +}; + + +int main() +{ + constexpr const my_type t = {{}, 0}; + printer p = {}; + p.operator()(&my_type::b); + p.operator()(&my_type::i); + return 0; +} diff --git a/tests/PointerToDataMemberTest.cpp b/tests/PointerToDataMemberTest.cpp new file mode 100644 index 00000000..bd751a98 --- /dev/null +++ b/tests/PointerToDataMemberTest.cpp @@ -0,0 +1,9 @@ +struct PtrToMemTest +{ + int value; +}; + + +int PtrToMemTest::*fixed = &PtrToMemTest::value; + +auto deduced = &PtrToMemTest::value; diff --git a/tests/PointerToDataMemberTest.expect b/tests/PointerToDataMemberTest.expect new file mode 100644 index 00000000..9b395bb9 --- /dev/null +++ b/tests/PointerToDataMemberTest.expect @@ -0,0 +1,11 @@ +struct PtrToMemTest +{ + int value; +}; + + +using MemberVarPtr_7 = int PtrToMemTest::*; +MemberVarPtr_7 fixed = &PtrToMemTest::value; + +using MemberVarPtr_9 = int PtrToMemTest::*; +MemberVarPtr_9 deduced = &PtrToMemTest::value; diff --git a/tests/PointerToMemberFunctionTest.cpp b/tests/PointerToMemberFunctionTest.cpp new file mode 100644 index 00000000..ffa17822 --- /dev/null +++ b/tests/PointerToMemberFunctionTest.cpp @@ -0,0 +1,17 @@ +#define INSIGHTS_USE_TEMPLATE + +struct Person { + int age; + + int Fun(double) { return 2;} +}; + +template +Key extractKey(Key POD::*pMember); + +struct S { void f(); }; + +int main() +{ + auto p = &Person::Fun; +} diff --git a/tests/PointerToMemberFunctionTest.expect b/tests/PointerToMemberFunctionTest.expect new file mode 100644 index 00000000..6ae06795 --- /dev/null +++ b/tests/PointerToMemberFunctionTest.expect @@ -0,0 +1,29 @@ +#define INSIGHTS_USE_TEMPLATE + +struct Person +{ + int age; + inline int Fun(double) + { + return 2; + } + +}; + + +template +Key extractKey(Key POD::*pMember); + +struct S +{ + void f(); + +}; + + +int main() +{ + using MemberVarPtr_16 = int (Person::*)(double); + MemberVarPtr_16 p = &Person::Fun; + return 0; +} diff --git a/tests/p0315_4Test.expect b/tests/p0315_4Test.expect index c690b04f..35c55bb4 100644 --- a/tests/p0315_4Test.expect +++ b/tests/p0315_4Test.expect @@ -41,7 +41,7 @@ struct Test inline constexpr operator retType_7_29 () const noexcept { return __invoke; - }; + } private: static inline /*constexpr */ void __invoke() diff --git a/tests/p0780_2Test.cerr b/tests/p0780_2Test.cerr index a0a1b6bc..78ec2e1f 100644 --- a/tests/p0780_2Test.cerr +++ b/tests/p0780_2Test.cerr @@ -18,8 +18,8 @@ error: templates cannot be declared inside of a local class 45 | inline /*constexpr */ invoke_result_t operator()() const | ^~~~~~~~~~~~~~~ | std::invoke_result_t -... invoke.h:314:1: note: 'std::invoke_result_t' declared here - 314 | using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; +... invoke.h:387:1: note: 'std::invoke_result_t' declared here + 387 | using invoke_result_t = __invoke_result_t<_Fn, _Args...>; | ^ .tmp.cpp:68:10: error: no viable conversion from returned value of type 'class __lambda_15_12' to function return type 'int' 68 | return __lambda_15_12; diff --git a/version.h.in b/version.h.in index c65b5a1b..f6973a75 100644 --- a/version.h.in +++ b/version.h.in @@ -1,7 +1,7 @@ #ifndef INSIGHTS_VERSION_H #define INSIGHTS_VERSION_H -#define INSIGHTS_VERSION "20.1" +#define INSIGHTS_VERSION "21.1" #define GIT_REPO_URL "@GIT_REPO_URL@" #define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@"