Skip to content

Commit 7fc681a

Browse files
ddobrevtritao
authored andcommitted
Ensure complete template specializations in AST
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent 2fb1376 commit 7fc681a

File tree

6 files changed

+27
-51
lines changed

6 files changed

+27
-51
lines changed

src/CppParser/Decl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ class CS_API ClassTemplate : public Template
663663
ClassTemplate();
664664
~ClassTemplate();
665665
VECTOR(ClassTemplateSpecialization*, Specializations)
666-
ClassTemplateSpecialization* FindSpecialization(const std::string& usr);
666+
ClassTemplateSpecialization* FindSpecialization(const std::string& usr);
667667
ClassTemplatePartialSpecialization* FindPartialSpecialization(const std::string& usr);
668668
};
669669

src/CppParser/Parser.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2999,13 +2999,22 @@ void Parser::CompleteIfSpecializationType(const clang::QualType& QualType)
29992999

30003000
auto existingClient = c->getSema().getDiagnostics().getClient();
30013001
std::unique_ptr<::DiagnosticConsumer> SemaDiagnostics(new ::DiagnosticConsumer());
3002-
SemaDiagnostics-> Decl = CTS;
3002+
SemaDiagnostics->Decl = CTS;
30033003
c->getSema().getDiagnostics().setClient(SemaDiagnostics.get(), false);
30043004

30053005
c->getSema().InstantiateClassTemplateSpecialization(CTS->getBeginLoc(),
30063006
CTS, TSK_ImplicitInstantiation, false);
30073007

30083008
c->getSema().getDiagnostics().setClient(existingClient, false);
3009+
3010+
auto CT = WalkClassTemplate(CTS->getSpecializedTemplate());
3011+
auto USR = GetDeclUSR(CTS);
3012+
auto TS = CT->FindSpecialization(USR);
3013+
if (TS != nullptr && TS->isIncomplete)
3014+
{
3015+
TS->isIncomplete = false;
3016+
WalkRecordCXX(CTS, TS);
3017+
}
30093018
}
30103019

30113020
Parameter* Parser::WalkParameter(const clang::ParmVarDecl* PVD,

src/Generator.Tests/AST/TestAST.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,10 @@ public void TestASTClassTemplates()
293293
var paramType = ctor.Parameters[0].Type as TemplateParameterType;
294294
Assert.IsNotNull(paramType);
295295
Assert.AreEqual(templateTypeParameter, paramType.Parameter);
296-
Assert.AreEqual(5, template.Specializations.Count);
296+
Assert.AreEqual(6, template.Specializations.Count);
297297
Assert.AreEqual(TemplateSpecializationKind.ExplicitInstantiationDefinition, template.Specializations[0].SpecializationKind);
298-
Assert.AreEqual(TemplateSpecializationKind.ExplicitInstantiationDefinition, template.Specializations[3].SpecializationKind);
299-
Assert.AreEqual(TemplateSpecializationKind.Undeclared, template.Specializations[4].SpecializationKind);
298+
Assert.AreEqual(TemplateSpecializationKind.ExplicitInstantiationDefinition, template.Specializations[4].SpecializationKind);
299+
Assert.AreEqual(TemplateSpecializationKind.Undeclared, template.Specializations[5].SpecializationKind);
300300
var typeDef = AstContext.FindTypedef("TestTemplateClassInt").FirstOrDefault();
301301
Assert.IsNotNull(typeDef, "Couldn't find TestTemplateClassInt typedef.");
302302
var integerInst = typeDef.Type as TemplateSpecializationType;
@@ -574,7 +574,7 @@ public void TestPrintNestedInSpecialization()
574574
{
575575
var template = AstContext.FindDecl<ClassTemplate>("TestTemplateClass").First();
576576
var cppTypePrinter = new CppTypePrinter(Context) { ScopeKind = TypePrintScopeKind.Qualified };
577-
Assert.That(template.Specializations[3].Classes.First().Visit(cppTypePrinter).Type,
577+
Assert.That(template.Specializations[4].Classes.First().Visit(cppTypePrinter).Type,
578578
Is.EqualTo("TestTemplateClass<Math::Complex>::NestedInTemplate"));
579579
}
580580

@@ -629,5 +629,13 @@ public void TestPrivateCCtorCopyAssignment()
629629
Assert.That(@class.Constructors.Any(c => c.IsCopyConstructor), Is.True);
630630
Assert.That(@class.Methods.Any(o => o.OperatorKind == CXXOperatorKind.Equal), Is.True);
631631
}
632+
633+
[Test]
634+
public void TestCompletionSpecializationInFunction()
635+
{
636+
Function function = AstContext.FindFunction("returnIncompleteTemplateSpecialization").First();
637+
function.ReturnType.Type.TryGetClass(out Class specialization);
638+
Assert.That(specialization.IsIncomplete, Is.False);
639+
}
632640
}
633641
}

src/Generator/Types/TypeMapDatabase.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ public bool FindTypeMap(Type type, out TypeMap typeMap)
117117
}
118118

119119
typeMap = null;
120-
var typedef = type as TypedefType;
121-
return typedef != null && FindTypeMap(typedef.Declaration.Type, out typeMap);
120+
return false;
122121
}
123122

124123
public bool FindTypeMap(Declaration declaration, out TypeMap typeMap) =>

tests/CLI/CLI.cs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using CppSharp.AST;
2-
using CppSharp.AST.Extensions;
32
using CppSharp.Generators;
4-
using CppSharp.Passes;
53
using CppSharp.Types;
64
using CppSharp.Utils;
75

@@ -21,38 +19,6 @@ public override void CLIMarshalToManaged(MarshalContext ctx)
2119
}
2220
}
2321

24-
public class CompleteIgnoredClassTemplateForEmployeeTypedefPass : TranslationUnitPass
25-
{
26-
public override bool VisitTypedefDecl(TypedefDecl typedef)
27-
{
28-
var templateType = GetDesugaredFinalPointeeElseType(typedef?.Type?.Desugar()) as TemplateSpecializationType;
29-
bool isTemplateTypedef = IsTemplateTypedef(templateType?.Template?.OriginalName);
30-
if (isTemplateTypedef)
31-
{
32-
Class @class;
33-
if (templateType.TryGetClass(out @class))
34-
{
35-
@class.IsIncomplete = false;
36-
return true;
37-
}
38-
}
39-
40-
return base.VisitTypedefDecl(typedef);
41-
}
42-
43-
private bool IsTemplateTypedef(string templateName)
44-
{
45-
return !string.IsNullOrEmpty(templateName) && "IgnoredClassTemplateForEmployee" == templateName;
46-
}
47-
48-
public Type GetDesugaredFinalPointeeElseType(Type t)
49-
{
50-
Type finalPointee = t.GetFinalPointee();
51-
52-
return finalPointee != null ? finalPointee.Desugar() : t;
53-
}
54-
}
55-
5622
public class CLITestsGenerator : GeneratorTest
5723
{
5824
public CLITestsGenerator(GeneratorKind kind)
@@ -67,15 +33,6 @@ public override void Setup(Driver driver)
6733
base.Setup(driver);
6834
}
6935

70-
public override void Preprocess(Driver driver, ASTContext ctx)
71-
{
72-
}
73-
74-
public override void SetupPasses(Driver driver)
75-
{
76-
driver.AddTranslationUnitPass(new CompleteIgnoredClassTemplateForEmployeeTypedefPass());
77-
}
78-
7936
public static void Main(string[] args)
8037
{
8138
ConsoleDriver.Run(new CLITestsGenerator(GeneratorKind.CLI));

tests/Native/AST.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ class ForwardedTemplate;
201201

202202
typedef ForwardedTemplate<int> i;
203203
typedef ForwardedTemplate<long> l;
204+
typedef TestTemplateClass<double> forceInSpecializations;
204205

205206
template class TestSpecializationArguments<const TestASTEnumItemByName>;
206207

@@ -248,3 +249,5 @@ class HasPrivateCCtorCopyAssignment
248249

249250
__attribute__((deprecated)) int deprecated_func(int num);
250251
int non_deprecated_func(int num);
252+
253+
TestTemplateClass<double> returnIncompleteTemplateSpecialization();

0 commit comments

Comments
 (0)