Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parser.cpp: fix WalkType + many native bugs #1819

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
130 changes: 75 additions & 55 deletions src/CppParser/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,6 @@ static clang::CXXRecordDecl* GetCXXRecordDeclFromBaseType(const clang::QualType&
else if (auto Injected = Ty->getAs<clang::InjectedClassNameType>())
return Injected->getDecl();

assert(0 && "Could not get base CXX record from type");
return nullptr;
}

Expand Down Expand Up @@ -1623,6 +1622,10 @@ FunctionTemplate* Parser::WalkFunctionTemplate(const clang::FunctionTemplateDecl

using namespace clang;

auto TemplatedDecl = TD->getTemplatedDecl();
if (dyn_cast<CXXDeductionGuideDecl>(TemplatedDecl))
return nullptr;

auto NS = GetNamespace(TD);
assert(NS && "Expected a valid namespace");

Expand All @@ -1632,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<CXXMethodDecl>(TemplatedDecl))
F = WalkMethodCXX(MD);
Expand Down Expand Up @@ -2639,36 +2641,40 @@ 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)
do
{
auto TypeLocClass = TL->getTypeLocClass();
if (TypeLocClass == TypeLoc::Qualified)
{
UTL = TL->getUnqualifiedLoc();
TL = &UTL;
}
else if (TypeLocClass == TypeLoc::Elaborated)
if (LocValid)
{
ETL = TL->getAs<ElaboratedTypeLoc>();
ITL = ETL.getNextTypeLoc();
TL = &ITL;
}

assert(TL->getTypeLocClass() == TypeLoc::TemplateSpecialization);
}

TemplateSpecializationTypeLoc TSpecTL;
TemplateSpecializationTypeLoc *TSTL = 0;
if (LocValid)
{
TSpecTL = TL->getAs<TemplateSpecializationTypeLoc>();
TSTL = &TSpecTL;
}
TypeLoc UTL, ETL, ITL;
if (TL->getTypeLocClass() == TypeLoc::Qualified)
{
UTL = TL->getUnqualifiedLoc();
TL = &UTL;
}
if (TL->getTypeLocClass() == TypeLoc::Elaborated)
{
ETL = TL->getAs<ElaboratedTypeLoc>();
ITL = ETL.getNextTypeLoc();
TL = &ITL;
}

TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments());
TST->Arguments = WalkTemplateArgumentList(&TArgs, TSTL);
if (TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization)
{
DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs<DependentTemplateSpecializationTypeLoc>();
TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL);
break;
}
else if (TL->getTypeLocClass() == TypeLoc::TemplateSpecialization)
{
TemplateSpecializationTypeLoc TSpecTL = TL->getAs<TemplateSpecializationTypeLoc>();
TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL);
break;
}
}
TST->Arguments = WalkTemplateArgumentList(&TArgs, (TemplateSpecializationTypeLoc*)nullptr);
} while (false);

Ty = TST;
break;
Expand All @@ -2681,36 +2687,40 @@ 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)
do
{
auto TypeLocClass = TL->getTypeLocClass();
if (TypeLocClass == TypeLoc::Qualified)
{
UTL = TL->getUnqualifiedLoc();
TL = &UTL;
}
else if (TypeLocClass == TypeLoc::Elaborated)
if (LocValid)
{
ETL = TL->getAs<ElaboratedTypeLoc>();
ITL = ETL.getNextTypeLoc();
TL = &ITL;
}

assert(TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization);
}

DependentTemplateSpecializationTypeLoc TSpecTL;
DependentTemplateSpecializationTypeLoc *TSTL = 0;
if (LocValid)
{
TSpecTL = TL->getAs<DependentTemplateSpecializationTypeLoc>();
TSTL = &TSpecTL;
}
TypeLoc UTL, ETL, ITL;
if (TL->getTypeLocClass() == TypeLoc::Qualified)
{
UTL = TL->getUnqualifiedLoc();
TL = &UTL;
}
if (TL->getTypeLocClass() == TypeLoc::Elaborated)
{
ETL = TL->getAs<ElaboratedTypeLoc>();
ITL = ETL.getNextTypeLoc();
TL = &ITL;
}

TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments());
TST->Arguments = WalkTemplateArgumentList(&TArgs, TSTL);
if (TL->getTypeLocClass() == TypeLoc::DependentTemplateSpecialization)
{
DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs<DependentTemplateSpecializationTypeLoc>();
TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL);
break;
}
else if (TL->getTypeLocClass() == TypeLoc::TemplateSpecialization)
{
TemplateSpecializationTypeLoc TSpecTL = TL->getAs<TemplateSpecializationTypeLoc>();
TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL);
break;
}
}
TST->Arguments = WalkTemplateArgumentList(&TArgs, (DependentTemplateSpecializationTypeLoc*)nullptr);
} while (false);

Ty = TST;
break;
Expand All @@ -2734,7 +2744,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<ElaboratedTypeLoc>();
ITL = ETL.getNextTypeLoc();
Expand Down Expand Up @@ -2922,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<clang::DeducedTemplateSpecializationType>();
if (DTS->isSugared())
Ty = WalkType(DTS->getCanonicalTypeInternal());
else
return nullptr;
break;
}
default:
{
Debug("Unhandled type class '%s'\n", Type->getTypeClassName());
Expand Down Expand Up @@ -4269,6 +4288,7 @@ Declaration* Parser::WalkDeclaration(const clang::Decl* D)
case Decl::IndirectField:
case Decl::StaticAssert:
case Decl::NamespaceAlias:
case Decl::CXXDeductionGuide:
break;
default:
{
Expand Down