Skip to content

[cxx-interop] Use more correct type names in C++ template parameters #68620

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2817,15 +2817,16 @@ namespace {
// conformances to Swift protocols from the Cxx module.
auto clangModule = Impl.getClangOwningModule(result->getClangNode());
if (clangModule && requiresCPlusPlus(clangModule)) {
auto nominalDecl = cast<NominalTypeDecl>(result);
conformToCxxIteratorIfNeeded(Impl, nominalDecl, decl);
conformToCxxSequenceIfNeeded(Impl, nominalDecl, decl);
conformToCxxConvertibleToBoolIfNeeded(Impl, nominalDecl, decl);
conformToCxxSetIfNeeded(Impl, nominalDecl, decl);
conformToCxxDictionaryIfNeeded(Impl, nominalDecl, decl);
conformToCxxPairIfNeeded(Impl, nominalDecl, decl);
conformToCxxOptionalIfNeeded(Impl, nominalDecl, decl);
conformToCxxVectorIfNeeded(Impl, nominalDecl, decl);
if (auto nominalDecl = dyn_cast<NominalTypeDecl>(result)) {
conformToCxxIteratorIfNeeded(Impl, nominalDecl, decl);
conformToCxxSequenceIfNeeded(Impl, nominalDecl, decl);
conformToCxxConvertibleToBoolIfNeeded(Impl, nominalDecl, decl);
conformToCxxSetIfNeeded(Impl, nominalDecl, decl);
conformToCxxDictionaryIfNeeded(Impl, nominalDecl, decl);
conformToCxxPairIfNeeded(Impl, nominalDecl, decl);
conformToCxxOptionalIfNeeded(Impl, nominalDecl, decl);
conformToCxxVectorIfNeeded(Impl, nominalDecl, decl);
}
}

if (auto *ntd = dyn_cast<NominalTypeDecl>(result))
Expand Down
6 changes: 3 additions & 3 deletions lib/ClangImporter/ImportName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2217,7 +2217,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
version, givenName);
if (!isa<clang::ClassTemplatePartialSpecializationDecl>(D)) {
auto getSwiftBuiltinTypeName =
[&](const clang::BuiltinType *builtin) -> std::optional<StringRef> {
[&](const clang::BuiltinType *builtin) -> std::optional<std::string> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dangling pointer issue got exposed by this patch

Type swiftType = nullptr;
switch (builtin->getKind()) {
case clang::BuiltinType::Void:
Expand All @@ -2240,8 +2240,8 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
}

if (swiftType) {
if (auto nominal = swiftType->getAs<NominalType>()) {
return nominal->getDecl()->getNameStr();
if (swiftType->is<NominalType>()) {
return swiftType->getStringAsComponent();
}
}
return std::nullopt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// CHECK-NEXT: @available(*, unavailable, message: "virtual functions are not yet available in Swift")
// CHECK-NEXT: mutating func foo()

// CHECK: struct Derived<Int32> {
// CHECK: struct Derived<CInt> {
// CHECK: @available(*, unavailable, message: "virtual functions are not yet available in Swift")
// CHECK: mutating func foo()
// CHECK: }
Expand Down
12 changes: 6 additions & 6 deletions test/Interop/Cxx/namespace/class-inline-namespace-irgen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ extension Parent.TypedefInInlineChild {
return ""
}
}
// CHECK: define hidden swiftcc {{.*}} @"$sSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbV4testE6stringSSvg"()
// CHECK: define hidden swiftcc {{.*}} @"$sSo6ParentO11InlineChildO0034TemplateInInlineChildCChar_ckBDjAbV4testE6stringSSvg"()

extension Parent.InInlineChild {
func doSomething() {
Expand All @@ -70,22 +70,22 @@ extension Parent.InlineChild.InSecondInlineChild {
}
// define hidden swiftcc {{.*}} @"$sSo6ParentO11InlineChildO06SecondbC0O02IndbC0V4testE1ySivg"()

// CHECK: define hidden swiftcc {{.*}} @"$s4test3useySSSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbVF"()
// CHECK: call swiftcc {{.*}} @"$sSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbV4testE6stringSSvg"
// CHECK: define hidden swiftcc {{.*}} @"$s4test3useySSSo6ParentO11InlineChildO0034TemplateInInlineChildCChar_ckBDjAbVF"()
// CHECK: call swiftcc {{.*}} @"$sSo6ParentO11InlineChildO0034TemplateInInlineChildCChar_ckBDjAbV4testE6stringSSvg"
func use(_ x: Parent.TypedefInInlineChild) -> String {
let s = x.string
return s
}

// CHECK: define hidden swiftcc {{.*}} @"$s4test4use2ySSSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbVF"()
// CHECK: call swiftcc {{.*}} @"$sSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbV4testE6stringSSvg"
// CHECK: define hidden swiftcc {{.*}} @"$s4test4use2ySSSo6ParentO11InlineChildO0034TemplateInInlineChildCChar_ckBDjAbVF"()
// CHECK: call swiftcc {{.*}} @"$sSo6ParentO11InlineChildO0034TemplateInInlineChildCChar_ckBDjAbV4testE6stringSSvg"
func use2(_ x: Parent.InlineChild.TypedefInInlineChild) -> String {
let s = x.string
return s
}

// define swiftcc void @"$s4testAAyySo6ParentO11InlineChildO02IncD0VF"()
// CHECK: alloca %TSo6ParentO11InlineChildO0033TemplateInInlineChildInt8_ehGIixbV
// CHECK: alloca %TSo6ParentO11InlineChildO0034TemplateInInlineChildCChar_ckBDjAbV
// CHECK: call {{.*}} @{{_ZN6Parent11InlineChild21TemplateInInlineChildIcEC|"\?\?0\?\$TemplateInInlineChild@D@InlineChild@Parent@@QEAA@XZ"}}
// CHECK: call swiftcc void @"$sSo6ParentO11InlineChildO02InbC0V4testE11doSomethingyyF"(
// CHECK: call swiftcc {{.*}} @"$sSo6ParentO11InlineChildO06SecondbC0O02IndbC0V4testE1xSivg"(
Expand Down
26 changes: 13 additions & 13 deletions test/Interop/Cxx/namespace/templates-module-interface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,59 @@
// CHECK: enum TemplatesNS1 {
// CHECK-NEXT: enum TemplatesNS2 {
// CHECK-NEXT: static func forwardDeclaredFunctionTemplate<T>(_: T) -> UnsafePointer<CChar>!
// CHECK-NEXT: struct ForwardDeclaredClassTemplate<Int8> {
// CHECK-NEXT: struct ForwardDeclaredClassTemplate<CChar> {
// CHECK-NEXT: init()
// CHECK-NEXT: mutating func basicMember() -> UnsafePointer<CChar>!
// CHECK-NEXT: }
// CHECK-NEXT: @available(*, unavailable, message: "Un-specialized class templates are not currently supported. Please use a specialization of this type.")
// CHECK-NEXT: struct ForwardDeclaredClassTemplate<> {
// CHECK-NEXT: }
// CHECK-NEXT: static func forwardDeclaredFunctionTemplateOutOfLine<T>(_: T) -> UnsafePointer<CChar>!
// CHECK-NEXT: struct ForwardDeclaredClassTemplateOutOfLine<Int8> {
// CHECK-NEXT: struct ForwardDeclaredClassTemplateOutOfLine<CChar> {
// CHECK-NEXT: init()
// CHECK-NEXT: mutating func basicMember() -> UnsafePointer<CChar>!
// CHECK-NEXT: }
// CHECK-NEXT: @available(*, unavailable, message: "Un-specialized class templates are not currently supported. Please use a specialization of this type.")
// CHECK-NEXT: struct ForwardDeclaredClassTemplateOutOfLine<> {
// CHECK-NEXT: }
// CHECK-NEXT: typealias BasicClassTemplateChar = TemplatesNS1.TemplatesNS3.BasicClassTemplate<Int8>
// CHECK-NEXT: typealias BasicClassTemplateChar = TemplatesNS1.TemplatesNS3.BasicClassTemplate<CChar>
// CHECK-NEXT: static func takesClassTemplateFromSibling(_: TemplatesNS1.TemplatesNS2.BasicClassTemplateChar) -> UnsafePointer<CChar>!
// CHECK-NEXT: }
// CHECK-NEXT: static func basicFunctionTemplate<T>(_: T) -> UnsafePointer<CChar>!
// CHECK-NEXT: struct BasicClassTemplate<Int8> {
// CHECK-NEXT: struct BasicClassTemplate<CChar> {
// CHECK-NEXT: init()
// CHECK-NEXT: mutating func basicMember() -> UnsafePointer<CChar>!
// CHECK-NEXT: }
// CHECK-NEXT: @available(*, unavailable, message: "Un-specialized class templates are not currently supported. Please use a specialization of this type.")
// CHECK-NEXT: struct BasicClassTemplate<> {
// CHECK-NEXT: }
// CHECK-NEXT: typealias BasicClassTemplateChar = TemplatesNS1.BasicClassTemplate<Int8>
// CHECK-NEXT: typealias BasicClassTemplateChar = TemplatesNS1.BasicClassTemplate<CChar>
// CHECK-NEXT: static func basicFunctionTemplateDefinedInDefs<T>(_: T) -> UnsafePointer<CChar>!
// CHECK-NEXT: @available(*, unavailable, message: "Un-specialized class templates are not currently supported. Please use a specialization of this type.")
// CHECK-NEXT: struct BasicClassTemplateDefinedInDefs<> {
// CHECK-NEXT: }
// CHECK-NEXT: typealias UseTemplate = TemplatesNS4.HasSpecialization<Int8>
// CHECK-NEXT: typealias UseSpecialized = TemplatesNS4.HasSpecialization<Int32>
// CHECK-NEXT: typealias UseTemplate = TemplatesNS4.HasSpecialization<CChar>
// CHECK-NEXT: typealias UseSpecialized = TemplatesNS4.HasSpecialization<CInt>
// CHECK-NEXT: enum TemplatesNS3 {
// CHECK-NEXT: struct BasicClassTemplate<Int8> {
// CHECK-NEXT: struct BasicClassTemplate<CChar> {
// CHECK-NEXT: init()
// CHECK-NEXT: }
// CHECK-NEXT: @available(*, unavailable, message: "Un-specialized class templates are not currently supported. Please use a specialization of this type.")
// CHECK-NEXT: struct BasicClassTemplate<> {
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: struct ForwardDeclaredClassTemplate<Int8> {
// CHECK-NEXT: struct ForwardDeclaredClassTemplate<CChar> {
// CHECK-NEXT: init()
// CHECK-NEXT: mutating func basicMember() -> UnsafePointer<CChar>!
// CHECK-NEXT: }
// CHECK-NEXT: typealias ForwardDeclaredClassTemplateChar = TemplatesNS1.TemplatesNS2.ForwardDeclaredClassTemplate<Int8>
// CHECK-NEXT: typealias ForwardDeclaredClassTemplateChar = TemplatesNS1.TemplatesNS2.ForwardDeclaredClassTemplate<CChar>
// CHECK-NEXT: }
// CHECK-NEXT: typealias ForwardDeclaredClassTemplateOutOfLineChar = TemplatesNS1.TemplatesNS2.ForwardDeclaredClassTemplateOutOfLine<Int8>
// CHECK-NEXT: typealias ForwardDeclaredClassTemplateOutOfLineChar = TemplatesNS1.TemplatesNS2.ForwardDeclaredClassTemplateOutOfLine<CChar>
// CHECK-NEXT: enum TemplatesNS4 {
// CHECK-NEXT: struct HasSpecialization<Int8> {
// CHECK-NEXT: struct HasSpecialization<CChar> {
// CHECK-NEXT: init()
// CHECK-NEXT: }
// CHECK-NEXT: struct HasSpecialization<Int32> {
// CHECK-NEXT: struct HasSpecialization<CInt> {
// CHECK-NEXT: init()
// CHECK-NEXT: }
// CHECK-NEXT: @available(*, unavailable, message: "Un-specialized class templates are not currently supported. Please use a specialization of this type.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

// CHECK: enum TemplatesNS1 {
// CHECK: static func basicFunctionTemplateDefinedInDefs<T>(_: T) -> UnsafePointer<CChar>!
// CHECK: struct BasicClassTemplateDefinedInDefs<Int8> {
// CHECK: struct BasicClassTemplateDefinedInDefs<CChar> {
// CHECK: init()
// CHECK: mutating func basicMember() -> UnsafePointer<CChar>!
// CHECK: }
// CHECK: }

// CHECK: typealias BasicClassTemplateDefinedInDefsChar = TemplatesNS1.BasicClassTemplateDefinedInDefs<Int8>
// CHECK: typealias BasicClassTemplateDefinedInDefsChar = TemplatesNS1.BasicClassTemplateDefinedInDefs<CChar>
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
// RUN: %target-swift-ide-test -print-module -module-to-print=TemplatesWithForwardDecl -I %S/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s

// CHECK: enum NS1 {
// CHECK-NEXT: struct ForwardDeclared<Int32> {
// CHECK-NEXT: struct ForwardDeclared<CInt> {
// CHECK-NEXT: init()
// CHECK-NEXT: }
// CHECK-NEXT: @available(*, unavailable, message: "Un-specialized class templates are not currently supported. Please use a specialization of this type.")
// CHECK-NEXT: struct ForwardDeclared<T> {
// CHECK-NEXT: }
// CHECK-NEXT: struct Decl<Int32> {
// CHECK-NEXT: struct Decl<CInt> {
// CHECK-NEXT: init()
// CHECK-NEXT: init(fwd: NS1.ForwardDeclared<Int32>)
// CHECK-NEXT: init(fwd: NS1.ForwardDeclared<CInt>)
// CHECK-NEXT: typealias MyInt = Int32
// CHECK-NEXT: var fwd: NS1.ForwardDeclared<Int32>
// CHECK-NEXT: static let intValue: NS1.Decl<Int32>.MyInt
// CHECK-NEXT: var fwd: NS1.ForwardDeclared<CInt>
// CHECK-NEXT: static let intValue: NS1.Decl<CInt>.MyInt
// CHECK-NEXT: }
// CHECK-NEXT: @available(*, unavailable, message: "Un-specialized class templates are not currently supported. Please use a specialization of this type.")
// CHECK-NEXT: struct Decl<T> {
// CHECK-NEXT: }
// CHECK-NEXT: typealias di = NS1.Decl<Int32>
// CHECK-NEXT: typealias di = NS1.Decl<CInt>
// CHECK-NEXT: }
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import CxxStdlib

// CHECK: @"\01L_selector(UTF8String)"
// CHECK: @objc_msgSend
// CHECK: call swiftcc void @"$sSo3stdO3__1O0067basic_stringInt8char_traitsInt8allocatorInt8_FABErpaBGcqaGHerapGgqaV9CxxStdlibEyAFSPys4Int8VGSgcfC"
// CHECK: call swiftcc void @"$sSo3stdO3__1O0071basic_stringCCharchar_traitsCCharallocatorCChar_mHGHsqaGJcraCCfsaqChraaV9CxxStdlibEyAFSPys4Int8VGSgcfC"

let ObjCStr: NSString = "hello"
let CxxStr = std.string(ObjCStr.utf8String) // Should not crash here
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@

// CHECK: struct TemplatedArray<T> {
// CHECK: }
// CHECK: struct TemplatedArray<Double> {
// CHECK: struct TemplatedArray<CDouble> {
// CHECK: subscript(i: Int32) -> Double

// CHECK: @available(*, unavailable, message: "use subscript")
Expand All @@ -103,7 +103,7 @@
// CHECK: @available(*, unavailable, message: "use subscript")
// CHECK: func __operatorSubscriptConst(_ i: Int32) -> UnsafePointer<Double>
// CHECK: }
// CHECK: typealias TemplatedDoubleArray = TemplatedArray<Double>
// CHECK: typealias TemplatedDoubleArray = TemplatedArray<CDouble>


// CHECK: struct TemplatedSubscriptArray {
Expand Down Expand Up @@ -140,12 +140,12 @@

// CHECK: struct TemplatedArrayByVal<T> {
// CHECK: }
// CHECK: struct TemplatedArrayByVal<Double> {
// CHECK: struct TemplatedArrayByVal<CDouble> {
// CHECK: subscript(i: Int32) -> Double { mutating get }
// CHECK: @available(*, unavailable, message: "use subscript")
// CHECK: mutating func __operatorSubscriptConst(_ i: Int32) -> Double
// CHECK: }
// CHECK: typealias TemplatedDoubleArrayByVal = TemplatedArrayByVal<Double>
// CHECK: typealias TemplatedDoubleArrayByVal = TemplatedArrayByVal<CDouble>

// CHECK: struct TemplatedByVal<T> {
// CHECK-NEXT: }
Expand Down
8 changes: 4 additions & 4 deletions test/Interop/Cxx/stdlib/libcxx-module-interface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@

// CHECK-IOSFWD: enum std {
// CHECK-IOSFWD: enum __1 {
// CHECK-IOSFWD: struct basic_string<Int8, char_traits<Int8>, allocator<Int8>> : CxxRandomAccessCollection {
// CHECK-IOSFWD: struct basic_string<CChar, char_traits<CChar>, allocator<CChar>> : CxxRandomAccessCollection {
// CHECK-IOSFWD: typealias value_type = CChar
// CHECK-IOSFWD: }
// CHECK-IOSFWD: struct basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>> : CxxRandomAccessCollection {
// CHECK-IOSFWD: struct basic_string<CWideChar, char_traits<CWideChar>, allocator<CWideChar>> : CxxRandomAccessCollection {
// CHECK-IOSFWD: typealias value_type = CWideChar
// CHECK-IOSFWD: }
// CHECK-IOSFWD: typealias string = std.__1.basic_string<Int8, char_traits<Int8>, allocator<Int8>>
// CHECK-IOSFWD: typealias wstring = std.__1.basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>>
// CHECK-IOSFWD: typealias string = std.__1.basic_string<CChar, char_traits<CChar>, allocator<CChar>>
// CHECK-IOSFWD: typealias wstring = std.__1.basic_string<CWideChar, char_traits<CWideChar>, allocator<CWideChar>>
// CHECK-IOSFWD: }
// CHECK-IOSFWD: }

Expand Down
12 changes: 6 additions & 6 deletions test/Interop/Cxx/stdlib/libstdcxx-module-interface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@
// REQUIRES: OS=linux-gnu

// CHECK-STD: enum std {
// CHECK-STRING: struct basic_string<Int8, char_traits<Int8>, allocator<Int8>> : CxxRandomAccessCollection {
// CHECK-STRING: typealias value_type = std.char_traits<Int8>.char_type
// CHECK-STRING: struct basic_string<CChar, char_traits<CChar>, allocator<CChar>> : CxxRandomAccessCollection {
// CHECK-STRING: typealias value_type = std.char_traits<CChar>.char_type
// CHECK-STRING: }
// CHECK-STRING: struct basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>> : CxxRandomAccessCollection {
// CHECK-STRING: typealias value_type = std.char_traits<Scalar>.char_type
// CHECK-STRING: struct basic_string<CWideChar, char_traits<CWideChar>, allocator<CWideChar>> : CxxRandomAccessCollection {
// CHECK-STRING: typealias value_type = std.char_traits<CWideChar>.char_type
// CHECK-STRING: }

// CHECK-TO-STRING: static func to_string(_ __val: Int32) -> std{{(.__cxx11)?}}.string
// CHECK-TO-STRING: static func to_wstring(_ __val: Int32) -> std{{(.__cxx11)?}}.wstring

// CHECK-SIZE-T: typealias size_t = Int

// CHECK-STRING: typealias string = std{{(.__cxx11)?}}.basic_string<Int8, char_traits<Int8>, allocator<Int8>>
// CHECK-STRING: typealias wstring = std{{(.__cxx11)?}}.basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>>
// CHECK-STRING: typealias string = std{{(.__cxx11)?}}.basic_string<CChar, char_traits<CChar>, allocator<CChar>>
// CHECK-STRING: typealias wstring = std{{(.__cxx11)?}}.basic_string<CWideChar, char_traits<CWideChar>, allocator<CWideChar>>
// CHECK-STD: }
8 changes: 4 additions & 4 deletions test/Interop/Cxx/stdlib/msvcprt-module-interface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
// CHECK-STRING: typealias size_t = size_t
// CHECK-STRING: static func to_string(_ _Val: Int32) -> std.string
// CHECK-STRING: static func to_wstring(_ _Val: Int32) -> std.wstring
// CHECK-STRING: struct basic_string<Int8, char_traits<Int8>, allocator<Int8>> : CxxRandomAccessCollection {
// CHECK-STRING: struct basic_string<CChar, char_traits<CChar>, allocator<CChar>> : CxxRandomAccessCollection {
// CHECK-STRING: typealias value_type = CChar
// CHECK-STRING: }
// CHECK-STRING: struct basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>> : CxxRandomAccessCollection {
// CHECK-STRING: struct basic_string<CWideChar, char_traits<CWideChar>, allocator<CWideChar>> : CxxRandomAccessCollection {
// CHECK-STRING: typealias value_type = CWideChar
// CHECK-STRING: }
// CHECK-STRING: typealias string = std.basic_string<Int8, char_traits<Int8>, allocator<Int8>>
// CHECK-STRING: typealias wstring = std.basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>>
// CHECK-STRING: typealias string = std.basic_string<CChar, char_traits<CChar>, allocator<CChar>>
// CHECK-STRING: typealias wstring = std.basic_string<CWideChar, char_traits<CWideChar>, allocator<CWideChar>>
// CHECK-STRING: }

Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
// CHECK: typealias RawIterator = SimpleCollectionReadOnly.iterator
// CHECK: }

// CHECK: struct HasInheritedTemplatedConstRACIterator<Int32> : CxxRandomAccessCollection {
// CHECK: typealias Element = InheritedTemplatedConstRACIterator<Int32>.Pointee
// CHECK: typealias Iterator = CxxIterator<HasInheritedTemplatedConstRACIterator<Int32>>
// CHECK: typealias RawIterator = InheritedTemplatedConstRACIterator<Int32>
// CHECK: struct HasInheritedTemplatedConstRACIterator<CInt> : CxxRandomAccessCollection {
// CHECK: typealias Element = InheritedTemplatedConstRACIterator<CInt>.Pointee
// CHECK: typealias Iterator = CxxIterator<HasInheritedTemplatedConstRACIterator<CInt>>
// CHECK: typealias RawIterator = InheritedTemplatedConstRACIterator<CInt>
// CHECK: }

// CHECK: struct HasInheritedTemplatedConstRACIteratorOutOfLineOps<Int32> : CxxRandomAccessCollection {
// CHECK: typealias Element = InheritedTemplatedConstRACIteratorOutOfLineOps<Int32>.Pointee
// CHECK: typealias Iterator = CxxIterator<HasInheritedTemplatedConstRACIteratorOutOfLineOps<Int32>>
// CHECK: typealias RawIterator = InheritedTemplatedConstRACIteratorOutOfLineOps<Int32>
// CHECK: struct HasInheritedTemplatedConstRACIteratorOutOfLineOps<CInt> : CxxRandomAccessCollection {
// CHECK: typealias Element = InheritedTemplatedConstRACIteratorOutOfLineOps<CInt>.Pointee
// CHECK: typealias Iterator = CxxIterator<HasInheritedTemplatedConstRACIteratorOutOfLineOps<CInt>>
// CHECK: typealias RawIterator = InheritedTemplatedConstRACIteratorOutOfLineOps<CInt>
// CHECK: }
Loading