зеркало из https://github.com/mono/CppSharp.git
Generate valid C# for templates with external specializations only
Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
This commit is contained in:
Родитель
27c52ecf54
Коммит
f1915b3066
|
@ -247,25 +247,17 @@ namespace CppSharp.AST
|
|||
return null;
|
||||
}
|
||||
|
||||
public static bool HasDependentValueFieldInLayout(this Class @class)
|
||||
{
|
||||
if (@class.Fields.Any(f => IsValueDependent(f.Type)))
|
||||
return true;
|
||||
|
||||
if (@class.Bases.Where(b => b.IsClass).Select(
|
||||
b => b.Class).Any(HasDependentValueFieldInLayout))
|
||||
return true;
|
||||
|
||||
public static bool HasDependentValueFieldInLayout(this Class @class,
|
||||
IEnumerable<ClassTemplateSpecialization> specializations = null) =>
|
||||
@class.Fields.Any(f => IsValueDependent(f.Type)) ||
|
||||
@class.Bases.Where(b => b.IsClass).Select(
|
||||
b => b.Class).Any(c => c.HasDependentValueFieldInLayout()) ||
|
||||
// HACK: Clang can't always resolve complex templates such as the base of std::atomic in msvc
|
||||
if (@class.IsTemplate && @class.Specializations.Any(
|
||||
s => s.Layout.Fields.Any(
|
||||
f => f.QualifiedType.Type.TryGetDeclaration(
|
||||
out ClassTemplateSpecialization specialization) &&
|
||||
specialization.TemplatedDecl.TemplatedClass.HasDependentValueFieldInLayout())))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
(@class.IsTemplate && (specializations ?? @class.Specializations).Any(
|
||||
s => s.Layout.Fields.Any(
|
||||
f => f.QualifiedType.Type.TryGetDeclaration(
|
||||
out ClassTemplateSpecialization specialization) &&
|
||||
specialization.TemplatedDecl.TemplatedClass.HasDependentValueFieldInLayout())));
|
||||
|
||||
public static IEnumerable<Property> GetConstCharFieldProperties(this Class @class) =>
|
||||
@class.Properties.Where(p => p.HasGetter && p.HasSetter &&
|
||||
|
|
|
@ -3067,7 +3067,9 @@ void Parser::CompleteIfSpecializationType(const clang::QualType& QualType)
|
|||
Scope Scope(nullptr, Scope::ScopeFlags::ClassScope, c->getSema().getDiagnostics());
|
||||
c->getSema().TUScope = &Scope;
|
||||
|
||||
InstantiateSpecialization(CTS);
|
||||
if (!CTS->isCompleteDefinition())
|
||||
c->getSema().InstantiateClassTemplateSpecialization(CTS->getBeginLoc(),
|
||||
CTS, clang::TemplateSpecializationKind::TSK_ImplicitInstantiation, false);
|
||||
|
||||
c->getSema().getDiagnostics().setClient(existingClient, false);
|
||||
c->getSema().TUScope = nullptr;
|
||||
|
@ -3083,32 +3085,6 @@ void Parser::CompleteIfSpecializationType(const clang::QualType& QualType)
|
|||
}
|
||||
}
|
||||
|
||||
void Parser::InstantiateSpecialization(clang::ClassTemplateSpecializationDecl* CTS)
|
||||
{
|
||||
using namespace clang;
|
||||
|
||||
if (!CTS->isCompleteDefinition())
|
||||
{
|
||||
c->getSema().InstantiateClassTemplateSpecialization(CTS->getBeginLoc(),
|
||||
CTS, clang::TemplateSpecializationKind::TSK_ImplicitInstantiation, false);
|
||||
}
|
||||
|
||||
for (auto Decl : CTS->decls())
|
||||
{
|
||||
if (Decl->getKind() == Decl::Kind::CXXRecord)
|
||||
{
|
||||
CXXRecordDecl* Nested = cast<CXXRecordDecl>(Decl);
|
||||
CXXRecordDecl* Template = Nested->getInstantiatedFromMemberClass();
|
||||
if (Template && !Nested->isCompleteDefinition() && !Nested->hasDefinition())
|
||||
{
|
||||
c->getSema().InstantiateClass(Nested->getBeginLoc(), Nested, Template,
|
||||
MultiLevelTemplateArgumentList(CTS->getTemplateArgs()),
|
||||
clang::TemplateSpecializationKind::TSK_ImplicitInstantiation, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Parameter* Parser::WalkParameter(const clang::ParmVarDecl* PVD,
|
||||
const clang::SourceLocation& ParamStartLoc)
|
||||
{
|
||||
|
|
|
@ -137,7 +137,6 @@ private:
|
|||
std::string GetTypeName(const clang::Type* Type);
|
||||
bool CanCheckCodeGenInfo(const clang::Type* Ty);
|
||||
void CompleteIfSpecializationType(const clang::QualType& QualType);
|
||||
void InstantiateSpecialization(clang::ClassTemplateSpecializationDecl* CTS);
|
||||
Parameter* WalkParameter(const clang::ParmVarDecl* PVD,
|
||||
const clang::SourceLocation& ParamStartLoc);
|
||||
void SetBody(const clang::FunctionDecl* FD, Function* F);
|
||||
|
|
|
@ -330,7 +330,7 @@ namespace CppSharp.Generators.CSharp
|
|||
GenerateClassTemplateSpecializationsInternals(
|
||||
nestedTemplate, nestedTemplate.Specializations);
|
||||
|
||||
if (template.HasDependentValueFieldInLayout() ||
|
||||
if (template.HasDependentValueFieldInLayout(specializations) ||
|
||||
template.Specializations.Intersect(specializations).Count() == specializations.Count)
|
||||
foreach (var specialization in generated)
|
||||
GenerateClassInternals(specialization);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "../NamespacesBase/NamespacesBase.h"
|
||||
#include "Independent.h"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
// Namespace clashes with NamespacesBase.OverlappingNamespace
|
||||
|
@ -71,6 +72,7 @@ private:
|
|||
IndependentFields<int> independentSpecialization;
|
||||
IndependentFields<Derived> independentExternalSpecialization;
|
||||
IndependentFields<Derived>::Nested nestedInExternalSpecialization;
|
||||
std::unordered_map<int, Derived> externalSpecializationOnly;
|
||||
};
|
||||
|
||||
class DLL_API HasVirtualInDependency : public HasVirtualInCore
|
||||
|
|
Загрузка…
Ссылка в новой задаче