From eb8dffecd17197462ac3e795f8ff2899c8aabb8d Mon Sep 17 00:00:00 2001 From: Deadlocklogic Date: Sun, 31 Dec 2023 01:13:19 +0200 Subject: [PATCH 1/6] Parser.cpp: fix WalkType for clang::Type::TypeClass == clang::Type::DependentTemplateSpecialization --- src/CppParser/Parser.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 06b39aa12..3569ec9fa 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -2681,10 +2681,11 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, if (TS->isSugared()) TST->desugared = GetQualifiedType(TS->getCanonicalTypeInternal(), TL); - TypeLoc UTL, ETL, ITL; + TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); if (LocValid) { + TypeLoc UTL, ETL, ITL; auto TypeLocClass = TL->getTypeLocClass(); if (TypeLocClass == TypeLoc::Qualified) { @@ -2698,20 +2699,26 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, TL = &ITL; } - assert(TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization); + if (TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization) + { + DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + } + else if (TL->getTypeLocClass() == TypeLoc::TemplateSpecialization) + { + TemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + } + else + { + llvm_unreachable("Unexpected semantics"); + } } - - DependentTemplateSpecializationTypeLoc TSpecTL; - DependentTemplateSpecializationTypeLoc *TSTL = 0; - if (LocValid) + else { - TSpecTL = TL->getAs(); - TSTL = &TSpecTL; + TST->Arguments = WalkTemplateArgumentList(&TArgs, (DependentTemplateSpecializationTypeLoc*)nullptr); } - TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); - TST->Arguments = WalkTemplateArgumentList(&TArgs, TSTL); - Ty = TST; break; } From 7b0375d76775fba6f9b9efa4ab653321022876ac Mon Sep 17 00:00:00 2001 From: Deadlocklogic Date: Sun, 31 Dec 2023 02:29:59 +0200 Subject: [PATCH 2/6] Parser.cpp: fix buggy in GetCXXRecordDeclFromBaseType --- src/CppParser/Parser.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 3569ec9fa..b12e991c1 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -900,7 +900,6 @@ static clang::CXXRecordDecl* GetCXXRecordDeclFromBaseType(const clang::QualType& else if (auto Injected = Ty->getAs()) return Injected->getDecl(); - assert(0 && "Could not get base CXX record from type"); return nullptr; } From 4b6b3ca4719736a101b19e64e9bc9e8f6275da62 Mon Sep 17 00:00:00 2001 From: Deadlocklogic Date: Mon, 1 Jan 2024 03:46:50 +0200 Subject: [PATCH 3/6] Parser.cpp: fix WalkType for clang::Type::TypeClass == clang::Type::TemplateSpecialization --- src/CppParser/Parser.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index b12e991c1..379a1b8c9 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -2638,10 +2638,11 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, if (TS->isSugared()) TST->desugared = GetQualifiedType(TS->getCanonicalTypeInternal(), TL); - TypeLoc UTL, ETL, ITL; + TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); if (LocValid) { + TypeLoc UTL, ETL, ITL; auto TypeLocClass = TL->getTypeLocClass(); if (TypeLocClass == TypeLoc::Qualified) { @@ -2655,20 +2656,26 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, TL = &ITL; } - assert(TL->getTypeLocClass() == TypeLoc::TemplateSpecialization); + if (TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization) + { + DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + } + else if (TL->getTypeLocClass() == TypeLoc::TemplateSpecialization) + { + TemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + } + else + { + llvm_unreachable("Unexpected semantics"); + } } - - TemplateSpecializationTypeLoc TSpecTL; - TemplateSpecializationTypeLoc *TSTL = 0; - if (LocValid) + else { - TSpecTL = TL->getAs(); - TSTL = &TSpecTL; + TST->Arguments = WalkTemplateArgumentList(&TArgs, (TemplateSpecializationTypeLoc*)nullptr); } - TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); - TST->Arguments = WalkTemplateArgumentList(&TArgs, TSTL); - Ty = TST; break; } From 3a202a8517ab8f241262ee223e43d2c3814a4ff1 Mon Sep 17 00:00:00 2001 From: Deadlocklogic Date: Tue, 2 Jan 2024 07:21:41 +0200 Subject: [PATCH 4/6] Parser.cpp: fix TypeLoc::Elaborated wrapped inside TypeLoc::Qualified --- src/CppParser/Parser.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 379a1b8c9..6f06249a4 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -2643,13 +2643,12 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, if (LocValid) { TypeLoc UTL, ETL, ITL; - auto TypeLocClass = TL->getTypeLocClass(); - if (TypeLocClass == TypeLoc::Qualified) + if (TL->getTypeLocClass() == TypeLoc::Qualified) { UTL = TL->getUnqualifiedLoc(); TL = &UTL; } - else if (TypeLocClass == TypeLoc::Elaborated) + if (TL->getTypeLocClass() == TypeLoc::Elaborated) { ETL = TL->getAs(); ITL = ETL.getNextTypeLoc(); @@ -2692,13 +2691,12 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, if (LocValid) { TypeLoc UTL, ETL, ITL; - auto TypeLocClass = TL->getTypeLocClass(); - if (TypeLocClass == TypeLoc::Qualified) + if (TL->getTypeLocClass() == TypeLoc::Qualified) { UTL = TL->getUnqualifiedLoc(); TL = &UTL; } - else if (TypeLocClass == TypeLoc::Elaborated) + if (TL->getTypeLocClass() == TypeLoc::Elaborated) { ETL = TL->getAs(); ITL = ETL.getNextTypeLoc(); @@ -2747,7 +2745,7 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, UTL = TL->getUnqualifiedLoc(); TL = &UTL; } - else if (TypeLocClass == TypeLoc::Elaborated) + if (TypeLocClass == TypeLoc::Elaborated) { ETL = TL->getAs(); ITL = ETL.getNextTypeLoc(); From b3b04e5a7e4e36e579973fd4438dd579761cba7a Mon Sep 17 00:00:00 2001 From: Deadlocklogic Date: Tue, 2 Jan 2024 07:28:20 +0200 Subject: [PATCH 5/6] Parser.cpp: use nullptr TypeLoc fallthrough when semantics are unexpected --- src/CppParser/Parser.cpp | 112 +++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 58 deletions(-) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 6f06249a4..04bae6c91 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -2640,40 +2640,38 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); - if (LocValid) + do { - TypeLoc UTL, ETL, ITL; - if (TL->getTypeLocClass() == TypeLoc::Qualified) - { - UTL = TL->getUnqualifiedLoc(); - TL = &UTL; - } - if (TL->getTypeLocClass() == TypeLoc::Elaborated) + if (LocValid) { - ETL = TL->getAs(); - ITL = ETL.getNextTypeLoc(); - TL = &ITL; - } + TypeLoc UTL, ETL, ITL; + if (TL->getTypeLocClass() == TypeLoc::Qualified) + { + UTL = TL->getUnqualifiedLoc(); + TL = &UTL; + } + if (TL->getTypeLocClass() == TypeLoc::Elaborated) + { + ETL = TL->getAs(); + ITL = ETL.getNextTypeLoc(); + TL = &ITL; + } - if (TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization) - { - DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs(); - TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); - } - else if (TL->getTypeLocClass() == TypeLoc::TemplateSpecialization) - { - TemplateSpecializationTypeLoc TSpecTL = TL->getAs(); - TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); - } - else - { - llvm_unreachable("Unexpected semantics"); + if (TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization) + { + DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + break; + } + else if (TL->getTypeLocClass() == TypeLoc::TemplateSpecialization) + { + TemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + break; + } } - } - else - { TST->Arguments = WalkTemplateArgumentList(&TArgs, (TemplateSpecializationTypeLoc*)nullptr); - } + } while (false); Ty = TST; break; @@ -2688,40 +2686,38 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); - if (LocValid) + do { - TypeLoc UTL, ETL, ITL; - if (TL->getTypeLocClass() == TypeLoc::Qualified) - { - UTL = TL->getUnqualifiedLoc(); - TL = &UTL; - } - if (TL->getTypeLocClass() == TypeLoc::Elaborated) + if (LocValid) { - ETL = TL->getAs(); - ITL = ETL.getNextTypeLoc(); - TL = &ITL; - } + TypeLoc UTL, ETL, ITL; + if (TL->getTypeLocClass() == TypeLoc::Qualified) + { + UTL = TL->getUnqualifiedLoc(); + TL = &UTL; + } + if (TL->getTypeLocClass() == TypeLoc::Elaborated) + { + ETL = TL->getAs(); + ITL = ETL.getNextTypeLoc(); + TL = &ITL; + } - if (TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization) - { - DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs(); - TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); - } - else if (TL->getTypeLocClass() == TypeLoc::TemplateSpecialization) - { - TemplateSpecializationTypeLoc TSpecTL = TL->getAs(); - TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); - } - else - { - llvm_unreachable("Unexpected semantics"); + if (TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization) + { + DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + break; + } + else if (TL->getTypeLocClass() == TypeLoc::TemplateSpecialization) + { + TemplateSpecializationTypeLoc TSpecTL = TL->getAs(); + TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + break; + } } - } - else - { TST->Arguments = WalkTemplateArgumentList(&TArgs, (DependentTemplateSpecializationTypeLoc*)nullptr); - } + } while (false); Ty = TST; break; From bc06a0d61501db1e60bc106f82af463833a933fa Mon Sep 17 00:00:00 2001 From: Deadlocklogic Date: Tue, 2 Jan 2024 17:29:53 +0200 Subject: [PATCH 6/6] Parser.cpp: implement CXXDeductionGuide --- src/CppParser/Parser.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 04bae6c91..ce8de65e5 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -1622,6 +1622,10 @@ FunctionTemplate* Parser::WalkFunctionTemplate(const clang::FunctionTemplateDecl using namespace clang; + auto TemplatedDecl = TD->getTemplatedDecl(); + if (dyn_cast(TemplatedDecl)) + return nullptr; + auto NS = GetNamespace(TD); assert(NS && "Expected a valid namespace"); @@ -1631,7 +1635,6 @@ FunctionTemplate* Parser::WalkFunctionTemplate(const clang::FunctionTemplateDecl return FT; CppSharp::CppParser::AST::Function* F = nullptr; - auto TemplatedDecl = TD->getTemplatedDecl(); if (auto MD = dyn_cast(TemplatedDecl)) F = WalkMethodCXX(MD); @@ -2929,6 +2932,15 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, Ty = WalkType(MT->getUnderlyingType(), TL); break; } + case clang::Type::DeducedTemplateSpecialization: + { + auto DTS = Type->getAs(); + if (DTS->isSugared()) + Ty = WalkType(DTS->getCanonicalTypeInternal()); + else + return nullptr; + break; + } default: { Debug("Unhandled type class '%s'\n", Type->getTypeClassName()); @@ -4276,6 +4288,7 @@ Declaration* Parser::WalkDeclaration(const clang::Decl* D) case Decl::IndirectField: case Decl::StaticAssert: case Decl::NamespaceAlias: + case Decl::CXXDeductionGuide: break; default: {