diff --git a/src/CppParser/Decl.h b/src/CppParser/Decl.h index 298bf478..12c4368f 100644 --- a/src/CppParser/Decl.h +++ b/src/CppParser/Decl.h @@ -663,7 +663,7 @@ public: ClassTemplate(); ~ClassTemplate(); VECTOR(ClassTemplateSpecialization*, Specializations) - ClassTemplateSpecialization* FindSpecialization(const std::string& usr); + ClassTemplateSpecialization* FindSpecialization(const std::string& usr); ClassTemplatePartialSpecialization* FindPartialSpecialization(const std::string& usr); }; diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 9c4aaeba..abd2325a 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -2999,13 +2999,22 @@ void Parser::CompleteIfSpecializationType(const clang::QualType& QualType) auto existingClient = c->getSema().getDiagnostics().getClient(); std::unique_ptr<::DiagnosticConsumer> SemaDiagnostics(new ::DiagnosticConsumer()); - SemaDiagnostics-> Decl = CTS; + SemaDiagnostics->Decl = CTS; c->getSema().getDiagnostics().setClient(SemaDiagnostics.get(), false); c->getSema().InstantiateClassTemplateSpecialization(CTS->getBeginLoc(), CTS, TSK_ImplicitInstantiation, false); c->getSema().getDiagnostics().setClient(existingClient, false); + + auto CT = WalkClassTemplate(CTS->getSpecializedTemplate()); + auto USR = GetDeclUSR(CTS); + auto TS = CT->FindSpecialization(USR); + if (TS != nullptr && TS->isIncomplete) + { + TS->isIncomplete = false; + WalkRecordCXX(CTS, TS); + } } Parameter* Parser::WalkParameter(const clang::ParmVarDecl* PVD, diff --git a/src/Generator.Tests/AST/TestAST.cs b/src/Generator.Tests/AST/TestAST.cs index 82068930..d635f79a 100644 --- a/src/Generator.Tests/AST/TestAST.cs +++ b/src/Generator.Tests/AST/TestAST.cs @@ -293,10 +293,10 @@ namespace CppSharp.Generator.Tests.AST var paramType = ctor.Parameters[0].Type as TemplateParameterType; Assert.IsNotNull(paramType); Assert.AreEqual(templateTypeParameter, paramType.Parameter); - Assert.AreEqual(5, template.Specializations.Count); + Assert.AreEqual(6, template.Specializations.Count); Assert.AreEqual(TemplateSpecializationKind.ExplicitInstantiationDefinition, template.Specializations[0].SpecializationKind); - Assert.AreEqual(TemplateSpecializationKind.ExplicitInstantiationDefinition, template.Specializations[3].SpecializationKind); - Assert.AreEqual(TemplateSpecializationKind.Undeclared, template.Specializations[4].SpecializationKind); + Assert.AreEqual(TemplateSpecializationKind.ExplicitInstantiationDefinition, template.Specializations[4].SpecializationKind); + Assert.AreEqual(TemplateSpecializationKind.Undeclared, template.Specializations[5].SpecializationKind); var typeDef = AstContext.FindTypedef("TestTemplateClassInt").FirstOrDefault(); Assert.IsNotNull(typeDef, "Couldn't find TestTemplateClassInt typedef."); var integerInst = typeDef.Type as TemplateSpecializationType; @@ -574,7 +574,7 @@ namespace CppSharp.Generator.Tests.AST { var template = AstContext.FindDecl("TestTemplateClass").First(); var cppTypePrinter = new CppTypePrinter(Context) { ScopeKind = TypePrintScopeKind.Qualified }; - Assert.That(template.Specializations[3].Classes.First().Visit(cppTypePrinter).Type, + Assert.That(template.Specializations[4].Classes.First().Visit(cppTypePrinter).Type, Is.EqualTo("TestTemplateClass::NestedInTemplate")); } @@ -629,5 +629,13 @@ namespace CppSharp.Generator.Tests.AST Assert.That(@class.Constructors.Any(c => c.IsCopyConstructor), Is.True); Assert.That(@class.Methods.Any(o => o.OperatorKind == CXXOperatorKind.Equal), Is.True); } + + [Test] + public void TestCompletionSpecializationInFunction() + { + Function function = AstContext.FindFunction("returnIncompleteTemplateSpecialization").First(); + function.ReturnType.Type.TryGetClass(out Class specialization); + Assert.That(specialization.IsIncomplete, Is.False); + } } } diff --git a/src/Generator/Types/TypeMapDatabase.cs b/src/Generator/Types/TypeMapDatabase.cs index 9843e775..93c1e1ce 100644 --- a/src/Generator/Types/TypeMapDatabase.cs +++ b/src/Generator/Types/TypeMapDatabase.cs @@ -117,8 +117,7 @@ namespace CppSharp.Types } typeMap = null; - var typedef = type as TypedefType; - return typedef != null && FindTypeMap(typedef.Declaration.Type, out typeMap); + return false; } public bool FindTypeMap(Declaration declaration, out TypeMap typeMap) => diff --git a/tests/CLI/CLI.cs b/tests/CLI/CLI.cs index c929a3a3..5848404a 100644 --- a/tests/CLI/CLI.cs +++ b/tests/CLI/CLI.cs @@ -1,7 +1,5 @@ using CppSharp.AST; -using CppSharp.AST.Extensions; using CppSharp.Generators; -using CppSharp.Passes; using CppSharp.Types; using CppSharp.Utils; @@ -21,38 +19,6 @@ namespace CppSharp.Tests } } - public class CompleteIgnoredClassTemplateForEmployeeTypedefPass : TranslationUnitPass - { - public override bool VisitTypedefDecl(TypedefDecl typedef) - { - var templateType = GetDesugaredFinalPointeeElseType(typedef?.Type?.Desugar()) as TemplateSpecializationType; - bool isTemplateTypedef = IsTemplateTypedef(templateType?.Template?.OriginalName); - if (isTemplateTypedef) - { - Class @class; - if (templateType.TryGetClass(out @class)) - { - @class.IsIncomplete = false; - return true; - } - } - - return base.VisitTypedefDecl(typedef); - } - - private bool IsTemplateTypedef(string templateName) - { - return !string.IsNullOrEmpty(templateName) && "IgnoredClassTemplateForEmployee" == templateName; - } - - public Type GetDesugaredFinalPointeeElseType(Type t) - { - Type finalPointee = t.GetFinalPointee(); - - return finalPointee != null ? finalPointee.Desugar() : t; - } - } - public class CLITestsGenerator : GeneratorTest { public CLITestsGenerator(GeneratorKind kind) @@ -67,15 +33,6 @@ namespace CppSharp.Tests base.Setup(driver); } - public override void Preprocess(Driver driver, ASTContext ctx) - { - } - - public override void SetupPasses(Driver driver) - { - driver.AddTranslationUnitPass(new CompleteIgnoredClassTemplateForEmployeeTypedefPass()); - } - public static void Main(string[] args) { ConsoleDriver.Run(new CLITestsGenerator(GeneratorKind.CLI)); diff --git a/tests/Native/AST.h b/tests/Native/AST.h index 3a67d4a4..00680dab 100644 --- a/tests/Native/AST.h +++ b/tests/Native/AST.h @@ -201,6 +201,7 @@ class ForwardedTemplate; typedef ForwardedTemplate i; typedef ForwardedTemplate l; +typedef TestTemplateClass forceInSpecializations; template class TestSpecializationArguments; @@ -248,3 +249,5 @@ private: __attribute__((deprecated)) int deprecated_func(int num); int non_deprecated_func(int num); + +TestTemplateClass returnIncompleteTemplateSpecialization();