Browse Source

Fixed an assert when parsing template instantiations of void.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
cpp_module_crash
Dimitar Dobrev 9 years ago
parent
commit
50a5d328db
  1. 84
      src/CppParser/Parser.cpp
  2. 19
      src/Generator/Passes/TrimSpecializationsPass.cs
  3. 13
      tests/Common/Common.h

84
src/CppParser/Parser.cpp

@ -2229,17 +2229,41 @@ static const clang::CodeGen::CGFunctionInfo& GetCodeGenFuntionInfo( @@ -2229,17 +2229,41 @@ static const clang::CodeGen::CGFunctionInfo& GetCodeGenFuntionInfo(
return CodeGenTypes->arrangeFunctionDeclaration(FD);
}
static const clang::Type* GetFinalType(const clang::Type* Ty)
{
auto FinalType = Ty;
while (true)
{
FinalType = FinalType->getUnqualifiedDesugaredType();
if (FinalType->getPointeeType().isNull())
return FinalType;
FinalType = FinalType->getPointeeType().getTypePtr();
}
}
static bool CanCheckCodeGenInfo(clang::Sema& S, const clang::Type* Ty)
{
bool CheckCodeGenInfo = true;
auto FinalType = GetFinalType(Ty);
if (auto RT = Ty->getAs<clang::RecordType>())
CheckCodeGenInfo &= RT->getDecl()->getDefinition() != 0;
if (FinalType->isDependentType() || FinalType->isInstantiationDependentType())
return false;
if (auto RD = Ty->getAsCXXRecordDecl())
CheckCodeGenInfo &= RD->hasDefinition();
if (auto RT = FinalType->getAs<clang::RecordType>())
{
if (RT->getDecl()->isInvalidDecl() || RT->getDecl()->isDependentContext() ||
!RT->getDecl()->getDefinition())
return false;
return CheckCodeGenInfo;
for (const auto& F : RT->getDecl()->fields())
{
auto FT = GetFinalType(F->getType().getTypePtr());
const clang::RecordType* FR;
if ((FR = FT->getAs<clang::RecordType>()) && FR->getDecl()->isInvalidDecl())
return false;
}
}
return true;
}
void Parser::WalkFunction(clang::FunctionDecl* FD, Function* F,
@ -2322,10 +2346,8 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, Function* F, @@ -2322,10 +2346,8 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, Function* F,
if (GetDeclText(Range, Sig))
F->Signature = Sig;
for(auto it = FD->param_begin(); it != FD->param_end(); ++it)
for (const auto& VD : FD->parameters())
{
ParmVarDecl* VD = (*it);
auto P = new Parameter();
P->Name = VD->getNameAsString();
@ -2367,30 +2389,34 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, Function* F, @@ -2367,30 +2389,34 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, Function* F,
F->HasThisReturn = HasThisReturn;
bool CheckCodeGenInfo = !FD->isDependentContext() && !FD->isInvalidDecl();
CheckCodeGenInfo &= CanCheckCodeGenInfo(C->getSema(), FD->getReturnType().getTypePtr());
if (auto FTSI = FD->getTemplateSpecializationInfo())
F->SpecializationInfo = WalkFunctionTemplateSpec(FTSI, F);
CXXMethodDecl* MD;
if ((MD = dyn_cast<CXXMethodDecl>(FD)) && !MD->isStatic() &&
!CanCheckCodeGenInfo(C->getSema(), MD->getThisType(C->getASTContext()).getTypePtr()))
return;
if (!CanCheckCodeGenInfo(C->getSema(), FD->getReturnType().getTypePtr()))
return;
for (auto I = FD->param_begin(), E = FD->param_end(); I != E; ++I)
CheckCodeGenInfo &= CanCheckCodeGenInfo(C->getSema(), (*I)->getType().getTypePtr());
if (!CanCheckCodeGenInfo(C->getSema(), (*I)->getType().getTypePtr()))
return;
if (CheckCodeGenInfo)
{
auto& CGInfo = GetCodeGenFuntionInfo(CodeGenTypes, FD);
F->IsReturnIndirect = CGInfo.getReturnInfo().isIndirect();
auto& CGInfo = GetCodeGenFuntionInfo(CodeGenTypes, FD);
F->IsReturnIndirect = CGInfo.getReturnInfo().isIndirect();
unsigned Index = 0;
for (auto I = CGInfo.arg_begin(), E = CGInfo.arg_end(); I != E; I++)
{
// Skip the first argument as it's the return type.
if (I == CGInfo.arg_begin())
continue;
if (Index >= F->Parameters.size())
continue;
F->Parameters[Index++]->IsIndirect = I->info.isIndirect();
}
unsigned Index = 0;
for (auto I = CGInfo.arg_begin(), E = CGInfo.arg_end(); I != E; I++)
{
// Skip the first argument as it's the return type.
if (I == CGInfo.arg_begin())
continue;
if (Index >= F->Parameters.size())
continue;
F->Parameters[Index++]->IsIndirect = I->info.isIndirect();
}
if (auto FTSI = FD->getTemplateSpecializationInfo())
F->SpecializationInfo = WalkFunctionTemplateSpec(FTSI, F);
}
Function* Parser::WalkFunction(clang::FunctionDecl* FD, bool IsDependent,

19
src/Generator/Passes/TrimSpecializationsPass.cs

@ -8,14 +8,21 @@ namespace CppSharp.Passes @@ -8,14 +8,21 @@ namespace CppSharp.Passes
{
public override bool VisitClassTemplateDecl(ClassTemplate template)
{
if (!base.VisitClassTemplateDecl(template) ||
template.Specializations.Count == 0)
if (!base.VisitClassTemplateDecl(template))
return false;
var lastGroup = (from specialization in template.Specializations
group specialization by specialization.Arguments.All(
a => a.Type.Type != null && a.Type.Type.IsAddress()) into @group
select @group).Last();
template.Specializations.RemoveAll(
s => s.Fields.Any(f => f.Type.IsPrimitiveType(PrimitiveType.Void)));
if (template.Specializations.Count == 0)
return false;
var groups = (from specialization in template.Specializations
group specialization by specialization.Arguments.All(
a => a.Type.Type != null && a.Type.Type.IsAddress()) into @group
select @group).ToList();
var lastGroup = groups.Last();
if (lastGroup.Key)
{
foreach (var specialization in lastGroup.Skip(1))

13
tests/Common/Common.h

@ -1093,3 +1093,16 @@ struct TestsTypes @@ -1093,3 +1093,16 @@ struct TestsTypes
{
int(*FunctionNoProto)();
};
template <class T>
struct SpecialisesVoid
{
private:
T t;
};
class UsesSpecialisationOfVoid
{
private:
SpecialisesVoid<void>* s;
};

Loading…
Cancel
Save