Skip to content

Commit c89f07c

Browse files
committed
WIP
1 parent 090f159 commit c89f07c

File tree

11 files changed

+76
-23
lines changed

11 files changed

+76
-23
lines changed

include/swift/AST/ClangModuleLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class ClangModuleLoader : public ModuleLoader {
177177
StringRef relatedEntityKind,
178178
llvm::function_ref<void(TypeDecl *)> receiver) = 0;
179179
/// Instantiate and import class template.
180-
virtual NominalTypeDecl *
180+
virtual StructDecl *
181181
instantiateCXXClassTemplate(clang::ClassTemplateDecl *decl,
182182
ArrayRef<clang::TemplateArgument> arguments) = 0;
183183

include/swift/AST/Decl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3392,12 +3392,17 @@ class EnumDecl final : public NominalTypeDecl {
33923392
/// to get the declared type ("Complex" in the above example).
33933393
class StructDecl final : public NominalTypeDecl {
33943394
SourceLoc StructLoc;
3395+
Type TemplateInstantiationType;
33953396

33963397
public:
33973398
StructDecl(SourceLoc StructLoc, Identifier Name, SourceLoc NameLoc,
33983399
ArrayRef<TypeLoc> Inherited,
33993400
GenericParamList *GenericParams, DeclContext *DC);
34003401

3402+
StructDecl(SourceLoc StructLoc, Identifier Name, SourceLoc NameLoc,
3403+
ArrayRef<TypeLoc> Inherited,
3404+
GenericParamList *GenericParams, DeclContext *DC, Type templateInstantiationType);
3405+
34013406
SourceLoc getStartLoc() const { return StructLoc; }
34023407
SourceRange getSourceRange() const {
34033408
return SourceRange(StructLoc, getBraces().End);
@@ -3436,6 +3441,9 @@ class StructDecl final : public NominalTypeDecl {
34363441
bool isCxxNonTrivial() const { return Bits.StructDecl.IsCxxNonTrivial; }
34373442

34383443
void setIsCxxNonTrivial(bool v) { Bits.StructDecl.IsCxxNonTrivial = v; }
3444+
3445+
Type getTemplateInstantiationType() const { return TemplateInstantiationType; }
3446+
void setTemplateInstantiationType(Type t) { TemplateInstantiationType = t; }
34393447
};
34403448

34413449
/// This is the base type for AncestryOptions. Each flag describes possible

include/swift/ClangImporter/ClangImporter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ class ClangImporter final : public ClangModuleLoader {
240240
StringRef relatedEntityKind,
241241
llvm::function_ref<void(TypeDecl *)> receiver) override;
242242

243-
NominalTypeDecl *
243+
StructDecl *
244244
instantiateCXXClassTemplate(clang::ClassTemplateDecl *decl,
245245
ArrayRef<clang::TemplateArgument> arguments) override;
246246

lib/AST/Decl.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3974,15 +3974,21 @@ void EnumDecl::setRawType(Type rawType) {
39743974

39753975
StructDecl::StructDecl(SourceLoc StructLoc, Identifier Name, SourceLoc NameLoc,
39763976
ArrayRef<TypeLoc> Inherited,
3977-
GenericParamList *GenericParams, DeclContext *Parent)
3977+
GenericParamList *GenericParams, DeclContext *Parent, Type TemplateInstantiationType)
39783978
: NominalTypeDecl(DeclKind::Struct, Parent, Name, NameLoc, Inherited,
39793979
GenericParams),
3980-
StructLoc(StructLoc)
3980+
StructLoc(StructLoc), TemplateInstantiationType(TemplateInstantiationType)
39813981
{
39823982
Bits.StructDecl.HasUnreferenceableStorage = false;
39833983
Bits.StructDecl.IsCxxNonTrivial = false;
39843984
}
39853985

3986+
StructDecl::StructDecl(SourceLoc StructLoc, Identifier Name, SourceLoc NameLoc,
3987+
ArrayRef<TypeLoc> Inherited,
3988+
GenericParamList *GenericParams, DeclContext *Parent)
3989+
: StructDecl(StructLoc, Name, NameLoc, Inherited, GenericParams, Parent, Type())
3990+
{}
3991+
39863992
bool NominalTypeDecl::hasMemberwiseInitializer() const {
39873993
// Currently only structs can have memberwise initializers.
39883994
auto *sd = dyn_cast<StructDecl>(this);

lib/ClangImporter/ClangImporter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4151,7 +4151,7 @@ clang::FunctionDecl *ClangImporter::instantiateCXXFunctionTemplate(
41514151
return spec;
41524152
}
41534153

4154-
NominalTypeDecl *
4154+
StructDecl *
41554155
ClangImporter::instantiateCXXClassTemplate(
41564156
clang::ClassTemplateDecl *decl,
41574157
ArrayRef<clang::TemplateArgument> arguments) {
@@ -4169,7 +4169,7 @@ ClangImporter::instantiateCXXClassTemplate(
41694169
assert(isa<clang::RecordType>(CanonType) &&
41704170
"type of non-dependent specialization is not a RecordType");
41714171

4172-
return dyn_cast_or_null<NominalTypeDecl>(
4172+
return dyn_cast_or_null<StructDecl>(
41734173
Impl.importDecl(ctsd, Impl.CurrentVersion));
41744174
}
41754175

lib/ClangImporter/Serializability.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "ImporterImpl.h"
2525
#include "swift/ClangImporter/SwiftAbstractBasicWriter.h"
26+
#include "clang/AST/DeclTemplate.h"
2627

2728
using namespace swift;
2829

@@ -72,9 +73,12 @@ class SerializationPathFinder {
7273
// easier to just avoid doing so and fall into the external-path code.
7374
if (!isa<TypeAliasDecl>(swiftDecl)) {
7475
// Only accept this declaration if it round-trips.
75-
if (auto swiftClangDecl = swiftDecl->getClangDecl())
76-
if (isSameDecl(decl, swiftClangDecl))
77-
return swiftDecl;
76+
if (auto swiftClangDecl = swiftDecl->getClangDecl()) {
77+
if (!isa<clang::ClassTemplateSpecializationDecl>(swiftClangDecl)) {
78+
if (isSameDecl(decl, swiftClangDecl))
79+
return swiftDecl;
80+
}
81+
}
7882
}
7983
}
8084

@@ -102,7 +106,7 @@ class SerializationPathFinder {
102106
bool findExternalPath(const clang::TagDecl *decl, ExternalPath &path) {
103107
// We can't handle class template specializations right now.
104108
if (isa<clang::ClassTemplateSpecializationDecl>(decl))
105-
return false;
109+
decl->dump();
106110

107111
// Named tags are straightforward.
108112
if (auto name = decl->getIdentifier()) {

lib/Sema/TypeCheckType.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,7 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
869869
const_cast<clang::ClassTemplateDecl *>(classTemplateDecl),
870870
templateArguments);
871871
if (instantiatedDecl) {
872+
instantiatedDecl->setTemplateInstantiationType(result);
872873
return instantiatedDecl->getDeclaredInterfaceType();
873874
} else {
874875
diags.diagnose(loc, diag::cxx_class_instantiation_failed);

lib/Serialization/Deserialization.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5388,6 +5388,33 @@ class TypeDeserializer {
53885388
genericArgs.push_back(argTy.get());
53895389
}
53905390

5391+
if (auto clangDecl = nominal->getClangDecl()) {
5392+
nominal->dump();
5393+
if (auto ctd = dyn_cast<clang::ClassTemplateDecl>(clangDecl)) {
5394+
ctd->dump();
5395+
ctd->dump();
5396+
auto clangImporter = static_cast<ClangImporter *>(nominal->getASTContext().getClangModuleLoader());
5397+
auto genericParams = nominal->getGenericParams();
5398+
5399+
SmallVector<Type, 2> typesOfgenericArgs;
5400+
for (auto arg : *genericParams) {
5401+
typesOfgenericArgs.push_back(arg->getDeclaredInterfaceType());
5402+
}
5403+
5404+
SmallVector<clang::TemplateArgument, 2> templateArguments;
5405+
std::unique_ptr<TemplateInstantiationError> error =
5406+
ctx.getClangTemplateArguments(
5407+
ctd->getTemplateParameters(), typesOfgenericArgs,
5408+
templateArguments);
5409+
5410+
auto instantiation = clangImporter->instantiateCXXClassTemplate(
5411+
const_cast<clang::ClassTemplateDecl *>(ctd), templateArguments);
5412+
5413+
instantiation->setTemplateInstantiationType(BoundGenericType::get(nominal, parentTy, genericArgs));
5414+
return instantiation->getDeclaredInterfaceType();
5415+
}
5416+
}
5417+
53915418
return BoundGenericType::get(nominal, parentTy, genericArgs);
53925419
}
53935420

lib/Serialization/Serialization.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,12 +1886,12 @@ void Serializer::writeCrossReference(const Decl *D) {
18861886
if (auto ctsd = dyn_cast<clang::ClassTemplateSpecializationDecl>(
18871887
D->getClangDecl())) {
18881888
abbrCode = DeclTypeAbbrCodes[XRefClangTemplateInstantiationLayout::Code];
1889-
auto clangTypeID = addClangTypeRef(ctsd->getTypeForDecl());
1889+
// auto clangTypeID = addClangTypeRef(ctsd->getTypeForDecl());
18901890

1891-
XRefClangTemplateInstantiationLayout::emitRecord(
1892-
Out, ScratchRecord, abbrCode, clangTypeID);
1891+
// XRefClangTemplateInstantiationLayout::emitRecord(
1892+
// Out, ScratchRecord, abbrCode, clangTypeID);
18931893

1894-
return;
1894+
// return;
18951895
}
18961896
}
18971897

@@ -2218,6 +2218,13 @@ static void collectDependenciesFromType(llvm::SmallSetVector<Type, 4> &seen,
22182218
return;
22192219
if (contextDependsOn(nominal, excluding))
22202220
return;
2221+
if (auto clangDecl = nominal->getClangDecl()) {
2222+
auto &clangASTContext = nominal->getClangDecl()->getASTContext();
2223+
if (auto ctsd = dyn_cast<clang::ClassTemplateSpecializationDecl>(clangDecl)) {
2224+
seen.insert(dyn_cast<StructDecl>(nominal)->getTemplateInstantiationType());
2225+
return;
2226+
}
2227+
}
22212228
seen.insert(nominal->getDeclaredInterfaceType());
22222229
});
22232230
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import ClassTemplateInNamespace
22

3-
public func receiveShip(_ i: inout Space.Ship<Bool>) {}
3+
public func receiveShip(_ i: inout Space.Ship<Yolo>) {}
44

5-
public func returnShip() -> Space.Ship<Bool> {
6-
return Space.Ship<Bool>()
5+
public func returnShip() -> Space.Ship<Yolo> {
6+
return Space.Ship<Yolo>()
77
}
88

9-
public func receiveShipWithEngine(_ i: inout Space.Ship<Engine.Turbojet>) {}
9+
// public func receiveShipWithEngine(_ i: inout Space.Ship<Engine.Turbojet>) {}
1010

11-
public func returnShipWithEngine() -> Space.Ship<Engine.Turbojet> {
12-
return Space.Ship<Engine.Turbojet>()
13-
}
11+
// public func returnShipWithEngine() -> Space.Ship<Engine.Turbojet> {
12+
// return Space.Ship<Engine.Turbojet>()
13+
// }

test/Interop/Cxx/templates/Inputs/class-template-in-namespace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#ifndef TEST_INTEROP_CXX_TEMPLATES_INPUTS_CLASS_TEMPLATE_IN_NAMESPACE_H
22
#define TEST_INTEROP_CXX_TEMPLATES_INPUTS_CLASS_TEMPLATE_IN_NAMESPACE_H
33

4+
struct Yolo {};
5+
46
namespace Space {
57

68
template <class T> struct Ship {T t;};
79

8-
using Orbiter = Ship<int>;
9-
1010
} // namespace Space
1111

1212
namespace Engine {

0 commit comments

Comments
 (0)