Browse Source

Generate valid C++ for specialisations with void

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
update-llvm
Dimitar Dobrev 3 years ago
parent
commit
a69f6d1d6d
  1. 47
      src/CppParser/Parser.cpp
  2. 2
      src/CppParser/Parser.h
  3. 5
      src/Generator/Generators/CSharp/CSharpSources.cs
  4. 2
      tests/CSharp/CSharpTemplates.cpp
  5. 20
      tests/CSharp/CSharpTemplates.h

47
src/CppParser/Parser.cpp

@ -2978,18 +2978,19 @@ static const clang::CodeGen::CGFunctionInfo& GetCodeGenFunctionInfo( @@ -2978,18 +2978,19 @@ static const clang::CodeGen::CGFunctionInfo& GetCodeGenFunctionInfo(
FTy.castAs<clang::FunctionProtoType>());
}
bool Parser::CanCheckCodeGenInfo(clang::Sema& S, const clang::Type* Ty)
bool Parser::CanCheckCodeGenInfo(const clang::Type* Ty)
{
auto FinalType = GetFinalType(Ty);
if (FinalType->isDependentType() ||
FinalType->isInstantiationDependentType() || FinalType->isUndeducedType())
FinalType->isInstantiationDependentType() ||
FinalType->isUndeducedType())
return false;
if (FinalType->isFunctionType())
{
auto FTy = FinalType->getAs<clang::FunctionType>();
auto CanCheck = CanCheckCodeGenInfo(S, FTy->getReturnType().getTypePtr());
auto CanCheck = CanCheckCodeGenInfo(FTy->getReturnType().getTypePtr());
if (!CanCheck)
return false;
@ -2998,7 +2999,7 @@ bool Parser::CanCheckCodeGenInfo(clang::Sema& S, const clang::Type* Ty) @@ -2998,7 +2999,7 @@ bool Parser::CanCheckCodeGenInfo(clang::Sema& S, const clang::Type* Ty)
auto FPTy = FinalType->getAs<clang::FunctionProtoType>();
for (const auto& ParamType : FPTy->getParamTypes())
{
auto CanCheck = CanCheckCodeGenInfo(S, ParamType.getTypePtr());
auto CanCheck = CanCheckCodeGenInfo(ParamType.getTypePtr());
if (!CanCheck)
return false;
}
@ -3015,7 +3016,8 @@ bool Parser::CanCheckCodeGenInfo(clang::Sema& S, const clang::Type* Ty) @@ -3015,7 +3016,8 @@ bool Parser::CanCheckCodeGenInfo(clang::Sema& S, const clang::Type* Ty)
{
if (auto MPT = Ty->getAs<clang::MemberPointerType>())
if (!MPT->isDependentType())
S.RequireCompleteType(clang::SourceLocation(), clang::QualType(Ty, 0), 1);
c->getSema().RequireCompleteType(clang::SourceLocation(),
clang::QualType(Ty, 0), 1);
}
return true;
@ -3088,7 +3090,7 @@ void Parser::InstantiateSpecialization(clang::ClassTemplateSpecializationDecl* C @@ -3088,7 +3090,7 @@ void Parser::InstantiateSpecialization(clang::ClassTemplateSpecializationDecl* C
if (!CTS->isCompleteDefinition())
{
c->getSema().InstantiateClassTemplateSpecialization(CTS->getBeginLoc(),
CTS, TSK_ImplicitInstantiation, false);
CTS, clang::TemplateSpecializationKind::TSK_ImplicitInstantiation, false);
}
for (auto Decl : CTS->decls())
@ -3101,7 +3103,7 @@ void Parser::InstantiateSpecialization(clang::ClassTemplateSpecializationDecl* C @@ -3101,7 +3103,7 @@ void Parser::InstantiateSpecialization(clang::ClassTemplateSpecializationDecl* C
{
c->getSema().InstantiateClass(Nested->getBeginLoc(), Nested, Template,
MultiLevelTemplateArgumentList(CTS->getTemplateArgs()),
TSK_ImplicitInstantiation, false);
clang::TemplateSpecializationKind::TSK_ImplicitInstantiation, false);
}
}
}
@ -3210,7 +3212,8 @@ void Parser::MarkValidity(Function* F) @@ -3210,7 +3212,8 @@ void Parser::MarkValidity(Function* F)
auto FD = static_cast<FunctionDecl*>(F->originalPtr);
if (!FD->getTemplateInstantiationPattern() || !FD->isExternallyVisible())
if (!FD->isImplicit() &&
(!FD->getTemplateInstantiationPattern() || !FD->isExternallyVisible()))
return;
auto existingClient = c->getSema().getDiagnostics().getClient();
@ -3230,6 +3233,18 @@ void Parser::MarkValidity(Function* F) @@ -3230,6 +3233,18 @@ void Parser::MarkValidity(Function* F)
F->isInvalid = IsInvalid(FD->getBody(), Bodies);
}
if (!F->isInvalid)
{
DeclContext* Context = FD->getDeclContext();
while (Context)
{
F->isInvalid = cast<Decl>(Context)->isInvalidDecl();
if (F->isInvalid)
break;
Context = Context->getParent();
}
}
c->getSema().getDiagnostics().setClient(existingClient, false);
c->getSema().TUScope = nullptr;
}
@ -3332,14 +3347,11 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F) @@ -3332,14 +3347,11 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F)
ParamStartLoc = VD->getEndLoc();
}
if (!opts->skipFunctionBodies)
{
if (FD->hasBody())
if (!opts->skipFunctionBodies && FD->hasBody())
{
if (auto Body = FD->getBody())
F->bodyStmt = WalkStatement(Body);
}
}
auto& CXXABI = codeGenTypes->getCXXABI();
bool HasThisReturn = false;
@ -3355,15 +3367,17 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F) @@ -3355,15 +3367,17 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F)
if (auto FTSI = FD->getTemplateSpecializationInfo())
F->specializationInfo = WalkFunctionTemplateSpec(FTSI, F);
MarkValidity(F);
F->qualifiedType = GetQualifiedType(FD->getType(), &FTL);
const CXXMethodDecl* MD;
if (FD->isDependentContext() ||
((MD = dyn_cast<CXXMethodDecl>(FD)) && !MD->isStatic() &&
!HasLayout(cast<CXXRecordDecl>(MD->getDeclContext()))) ||
!CanCheckCodeGenInfo(c->getSema(), FD->getReturnType().getTypePtr()) ||
!CanCheckCodeGenInfo(FD->getReturnType().getTypePtr()) ||
std::any_of(FD->parameters().begin(), FD->parameters().end(),
[this](auto* P) { return !CanCheckCodeGenInfo(c->getSema(), P->getType().getTypePtr()); }))
[this](auto* P) { return !CanCheckCodeGenInfo(P->getType().getTypePtr()); }))
{
F->qualifiedType = GetQualifiedType(FD->getType(), &FTL);
return;
}
@ -3377,9 +3391,6 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F) @@ -3377,9 +3391,6 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F)
F->Parameters[Index++]->isIndirect =
Arg.info.isIndirect() && !Arg.info.getIndirectByVal();
}
MarkValidity(F);
F->qualifiedType = GetQualifiedType(FD->getType(), &FTL);
}
Function* Parser::WalkFunction(const clang::FunctionDecl* FD)

2
src/CppParser/Parser.h

@ -135,7 +135,7 @@ private: @@ -135,7 +135,7 @@ private:
bool IsValidDeclaration(const clang::SourceLocation& Loc);
std::string GetDeclMangledName(const clang::Decl* D);
std::string GetTypeName(const clang::Type* Type);
bool CanCheckCodeGenInfo(clang::Sema & S, const clang::Type * Ty);
bool CanCheckCodeGenInfo(const clang::Type* Ty);
void CompleteIfSpecializationType(const clang::QualType& QualType);
void InstantiateSpecialization(clang::ClassTemplateSpecializationDecl* CTS);
Parameter* WalkParameter(const clang::ParmVarDecl* PVD,

5
src/Generator/Generators/CSharp/CSharpSources.cs

@ -365,7 +365,10 @@ namespace CppSharp.Generators.CSharp @@ -365,7 +365,10 @@ namespace CppSharp.Generators.CSharp
if (dependentClass.HasDependentValueFieldInLayout())
return specializedClasses.KeepSingleAllPointersSpecialization();
return new[] { specializedClasses.FirstOrDefault(s => s.IsGenerated) ??
return new[] {
specializedClasses.FirstOrDefault(
s => s.IsGenerated && s.Classes.All(c => !c.IsIncomplete)) ??
specializedClasses.FirstOrDefault(s => s.IsGenerated) ??
specializedClasses.First()};
}

2
tests/CSharp/CSharpTemplates.cpp

@ -120,7 +120,7 @@ void forceUseSpecializations(IndependentFields<int> _1, IndependentFields<bool> @@ -120,7 +120,7 @@ void forceUseSpecializations(IndependentFields<int> _1, IndependentFields<bool>
{
}
void hasIgnoredParam(DependentValueFields<IndependentFields<Ignored>> ii)
void hasIgnoredParam(DependentValueFields<IndependentFields<Ignored>> ii, Base<void> _24)
{
}

20
tests/CSharp/CSharpTemplates.h

@ -195,9 +195,27 @@ template <typename T> @@ -195,9 +195,27 @@ template <typename T>
class Base
{
public:
class Nested
{
public:
void f(const T& t);
friend void f(Nested& n) {}
};
void invokeFriend();
typedef T* typedefT;
};
template <typename T>
void Base<T>::Nested::f(const T& t)
{
}
template <typename T>
void Base<T>::invokeFriend()
{
f(Nested());
}
template <typename T>
class DependentValueFields : public Base<T>
{
@ -844,7 +862,7 @@ void forceUseSpecializations(IndependentFields<int> _1, IndependentFields<bool> @@ -844,7 +862,7 @@ void forceUseSpecializations(IndependentFields<int> _1, IndependentFields<bool>
VirtualDependentValueFields<float> _22, VirtualDependentValueFields<const char*> _23,
std::string s);
void hasIgnoredParam(DependentValueFields<IndependentFields<Ignored>> ii);
void hasIgnoredParam(DependentValueFields<IndependentFields<Ignored>> ii, Base<void> _24);
std::map<int, int> usesValidSpecialisationOfIgnoredTemplate();

Loading…
Cancel
Save