mirror of https://github.com/mono/CppSharp.git
Browse Source
ClassTemplate in Clang does not actually represent a complete declaration. For example, let's see the implementation of clang::ClassTemplateDecl::isThisDeclarationADefinition: bool isThisDeclarationADefinition() const { return getTemplatedDecl()->isThisDeclarationADefinition(); } (http://clang.llvm.org/doxygen/DeclTemplate_8h_source.html#l01995 at the time of this commit) The above shows that class templates do not have definitions, instead, their "definitions" are those of the real templates classes. In addition let's see ClassTemplateDecl::getCanonicalDecl(): const ClassTemplateDecl *getCanonicalDecl() const { return cast<ClassTemplateDecl>( RedeclarableTemplateDecl::getCanonicalDecl()); } (http://clang.llvm.org/doxygen/DeclTemplate_8h_source.html#l02023 at the time of this commit) In turn RedeclarableTemplateDecl::getCanonicalDecl() is defined as: RedeclarableTemplateDecl *getCanonicalDecl() override { return getFirstDecl(); } where getFirstDecl() returns just that - the first encountered declaration which might as well be a forward one. This means that the only complete declaration ClassTemplateDecl can point to is the template class itself, and the latter is therefore our only choice if we want to have a full list of all specializations of that template class. Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>pull/678/head
8 changed files with 48 additions and 146 deletions
@ -1,66 +0,0 @@
@@ -1,66 +0,0 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using CppSharp.AST; |
||||
|
||||
namespace CppSharp.Passes |
||||
{ |
||||
public class MoveNestedTemplateInternalsPass : TranslationUnitPass |
||||
{ |
||||
public MoveNestedTemplateInternalsPass() |
||||
{ |
||||
Options.VisitClassBases = false; |
||||
Options.VisitClassFields = false; |
||||
Options.VisitClassMethods = false; |
||||
Options.VisitClassProperties = false; |
||||
Options.VisitFunctionParameters = false; |
||||
Options.VisitFunctionReturnType = false; |
||||
Options.VisitNamespaceEnums = false; |
||||
Options.VisitNamespaceEvents = false; |
||||
Options.VisitNamespaceTypedefs = false; |
||||
Options.VisitNamespaceVariables = false; |
||||
Options.VisitTemplateArguments = false; |
||||
} |
||||
|
||||
public override bool VisitLibrary(ASTContext context) |
||||
{ |
||||
var result = base.VisitLibrary(context); |
||||
foreach (var entry in movedClassTemplates) |
||||
{ |
||||
foreach (var template in entry.Value) |
||||
{ |
||||
foreach (var decl in new[] { template, template.TemplatedDecl }) |
||||
{ |
||||
int index = entry.Key.Declarations.IndexOf(decl.Namespace); |
||||
decl.Namespace.Declarations.Remove(decl); |
||||
decl.Namespace = entry.Key; |
||||
entry.Key.Declarations.Insert(index, decl); |
||||
} |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public override bool VisitClassTemplateDecl(ClassTemplate template) |
||||
{ |
||||
if (!base.VisitClassTemplateDecl(template) || |
||||
template.Specializations.Count == 0 || |
||||
template.Specializations.All(s => s is ClassTemplatePartialSpecialization)) |
||||
return false; |
||||
|
||||
var @class = template.TemplatedDecl.Namespace as Class; |
||||
if (@class == null || @class is ClassTemplateSpecialization || |
||||
@class.Namespace is Class) |
||||
return false; |
||||
|
||||
if (movedClassTemplates.ContainsKey(@class.Namespace)) |
||||
movedClassTemplates[@class.Namespace].Add(template); |
||||
else |
||||
movedClassTemplates.Add(@class.Namespace, new List<ClassTemplate> { template }); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private Dictionary<DeclarationContext, IList<ClassTemplate>> movedClassTemplates = |
||||
new Dictionary<DeclarationContext, IList<ClassTemplate>>(); |
||||
} |
||||
} |
Loading…
Reference in new issue