Skip to content

Commit bf1dbc6

Browse files
authored
Merge pull request #85694 from Xazax-hun/const-frts-collision
[cxx-interop] Do not drop CV qualifiers during printing template names
2 parents 96dca43 + cd4e3cc commit bf1dbc6

7 files changed

+96
-36
lines changed

lib/ClangImporter/ClangClassTemplateNamePrinter.cpp

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ struct TemplateInstantiationNamePrinter
5858
return VisitType(type);
5959
}
6060

61+
void emitWithCVQualifiers(llvm::raw_svector_ostream &buffer,
62+
clang::QualType type) {
63+
if (type.isConstQualified())
64+
buffer << "__cxxConst<";
65+
if (type.isVolatileQualified())
66+
buffer << "__cxxVolatile<";
67+
68+
buffer << Visit(type.getTypePtr());
69+
70+
if (type.isVolatileQualified())
71+
buffer << ">";
72+
if (type.isConstQualified())
73+
buffer << ">";
74+
}
75+
6176
std::string VisitTagType(const clang::TagType *type) {
6277
auto tagDecl = type->getAsTagDecl();
6378
if (auto namedArg = dyn_cast_or_null<clang::NamedDecl>(tagDecl)) {
@@ -103,42 +118,47 @@ struct TemplateInstantiationNamePrinter
103118
} else {
104119
buffer << "__cxxRRef<";
105120
}
106-
buffer << Visit(type->getPointeeType().getTypePtr()) << ">";
121+
122+
emitWithCVQualifiers(buffer, type->getPointeeType());
123+
124+
buffer << ">";
107125
return buffer.str().str();
108126
}
109127

110128
std::string VisitPointerType(const clang::PointerType *type) {
111-
std::string pointeeResult = Visit(type->getPointeeType().getTypePtr());
112-
113-
enum class TagTypeDecorator { None, UnsafePointer, UnsafeMutablePointer };
129+
clang::QualType pointee = type->getPointeeType();
130+
std::string pointeeResult = Visit(pointee.getTypePtr());
114131

115132
// If this is a pointer to foreign reference type, we should not wrap
116133
// it in Unsafe(Mutable)?Pointer, since it will be imported as a class
117134
// in Swift.
118135
bool isReferenceType = false;
119-
if (auto tagDecl = type->getPointeeType()->getAsTagDecl()) {
136+
if (auto tagDecl = pointee->getAsTagDecl()) {
120137
if (auto *rd = dyn_cast<clang::RecordDecl>(tagDecl))
121138
isReferenceType = recordHasReferenceSemantics(rd, importerImpl);
122139
}
123140

124-
TagTypeDecorator decorator;
125-
if (!isReferenceType)
126-
decorator = type->getPointeeType().isConstQualified()
127-
? TagTypeDecorator::UnsafePointer
128-
: TagTypeDecorator::UnsafeMutablePointer;
129-
else
130-
decorator = TagTypeDecorator::None;
131-
132141
llvm::SmallString<128> storage;
133142
llvm::raw_svector_ostream buffer(storage);
134-
if (decorator != TagTypeDecorator::None)
135-
buffer << (decorator == TagTypeDecorator::UnsafePointer
136-
? "UnsafePointer"
137-
: "UnsafeMutablePointer")
138-
<< '<';
139-
buffer << pointeeResult;
140-
if (decorator != TagTypeDecorator::None)
143+
144+
if (pointee.isVolatileQualified())
145+
buffer << "__cxxVolatile<";
146+
147+
if (!isReferenceType) {
148+
buffer << (pointee.isConstQualified() ? "UnsafePointer<"
149+
: "UnsafeMutablePointer<");
150+
buffer << pointeeResult;
141151
buffer << '>';
152+
} else {
153+
if (pointee.isConstQualified())
154+
buffer << "__cxxConst<";
155+
buffer << pointeeResult;
156+
if (pointee.isConstQualified())
157+
buffer << ">";
158+
}
159+
160+
if (pointee.isVolatileQualified())
161+
buffer << ">";
142162

143163
return buffer.str().str();
144164
}
@@ -166,14 +186,23 @@ struct TemplateInstantiationNamePrinter
166186
}
167187

168188
std::string VisitArrayType(const clang::ArrayType *type) {
169-
return (Twine("[") + Visit(type->getElementType().getTypePtr()) + "]")
170-
.str();
189+
llvm::SmallString<128> storage;
190+
llvm::raw_svector_ostream buffer(storage);
191+
buffer << "[";
192+
emitWithCVQualifiers(buffer, type->getElementType());
193+
buffer << "]";
194+
return buffer.str().str();
171195
}
172196

173197
std::string VisitConstantArrayType(const clang::ConstantArrayType *type) {
174-
return (Twine("Vector<") + Visit(type->getElementType().getTypePtr()) +
175-
", " + std::to_string(type->getSExtSize()) + ">")
176-
.str();
198+
llvm::SmallString<128> storage;
199+
llvm::raw_svector_ostream buffer(storage);
200+
buffer << "Vector<";
201+
emitWithCVQualifiers(buffer, type->getElementType());
202+
buffer << ", ";
203+
buffer << type->getSExtSize();
204+
buffer << ">";
205+
return buffer.str().str();
177206
}
178207
};
179208

@@ -197,17 +226,7 @@ struct TemplateArgumentPrinter
197226
llvm::raw_svector_ostream &buffer) {
198227
auto ty = arg.getAsType();
199228

200-
if (ty.isConstQualified())
201-
buffer << "__cxxConst<";
202-
if (ty.isVolatileQualified())
203-
buffer << "__cxxVolatile<";
204-
205-
buffer << typePrinter.Visit(ty.getTypePtr());
206-
207-
if (ty.isVolatileQualified())
208-
buffer << ">";
209-
if (ty.isConstQualified())
210-
buffer << ">";
229+
typePrinter.emitWithCVQualifiers(buffer, ty);
211230
}
212231

213232
void VisitIntegralTemplateArgument(const clang::TemplateArgument &arg,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
3+
template<class T>
4+
struct MagicWrapper {};
5+
6+
class __attribute__((swift_attr("import_reference")))
7+
__attribute__((swift_attr("retain:immortal")))
8+
__attribute__((swift_attr("release:immortal"))) Foo {};
9+
10+
using MagicWrapperFrt = MagicWrapper<Foo *>;
11+
using MagicWrapperConstFrt = MagicWrapper<const Foo *>;
12+
using MagicWrapperVolatileFrt = MagicWrapper<volatile Foo *>;
13+
using MagicWrapperVolatileFrtRef = MagicWrapper<volatile Foo &>;

test/Interop/Cxx/templates/Inputs/class-template-with-primitive-argument.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ struct DoubleWrapper {
1515
int getValuePlusArg(int arg) const { return m.getValuePlusArg(arg); }
1616
};
1717

18+
template <class T>
19+
struct EmptyWrapper {};
20+
1821
typedef MagicWrapper<int> WrappedMagicInt;
1922
typedef MagicWrapper<const int> WrappedMagicIntConst;
2023
typedef MagicWrapper<const long> WrappedMagicLongConst;
@@ -26,6 +29,8 @@ typedef MagicWrapper<long[]> WrappedMagicLongArr;
2629
typedef MagicWrapper<int[123]> WrappedMagicIntFixedSizeArr1;
2730
typedef MagicWrapper<int[124]> WrappedMagicIntFixedSizeArr2;
2831
typedef MagicWrapper<std::nullptr_t> WrappedMagicNullPtr;
32+
typedef MagicWrapper<const int[]> WrappedMagicConstIntArr;
33+
typedef EmptyWrapper<volatile int &> WrappedVolatileIntRef;
2934

3035
typedef DoubleWrapper<MagicWrapper<int>> DoubleWrappedInt;
3136
typedef DoubleWrapper<MagicWrapper<const int>> DoubleWrappedIntConst;

test/Interop/Cxx/templates/Inputs/module.modulemap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,8 @@ module ForwardDeclaredSpecialization {
187187
header "ForwardDeclaredSpecialization.h"
188188
requires cplusplus
189189
}
190+
191+
module ClassTemplateWithFrt {
192+
header "class-template-with-frt.h"
193+
requires cplusplus
194+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %target-swift-ide-test -print-module -module-to-print=ClassTemplateWithFrt -I %S/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s
2+
3+
// CHECK: typealias MagicWrapperFrt = MagicWrapper<Foo>
4+
// CHECK: typealias MagicWrapperConstFrt = MagicWrapper<__cxxConst<Foo>>
5+
// CHECK: typealias MagicWrapperVolatileFrt = MagicWrapper<__cxxVolatile<Foo>>
6+
// CHECK: typealias MagicWrapperVolatileFrtRef = MagicWrapper<__cxxLRef<__cxxVolatile<Foo>>>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-swift-emit-silgen %s -I %S/Inputs -enable-experimental-cxx-interop -disable-availability-checking
2+
3+
import ClassTemplateWithFrt
4+
5+
func f() {
6+
// Used to trigger error while emitting SIL.
7+
let _ = MagicWrapperFrt()
8+
let _ = MagicWrapperConstFrt()
9+
let _ = MagicWrapperVolatileFrtRef()
10+
}

test/Interop/Cxx/templates/class-template-with-primitive-argument-module-interface.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
// CHECK: typealias WrappedMagicIntFixedSizeArr1 = MagicWrapper<Vector<CInt, 123>>
1919
// CHECK: typealias WrappedMagicIntFixedSizeArr2 = MagicWrapper<Vector<CInt, 124>>
2020
// CHECK: typealias WrappedMagicNullPtr = MagicWrapper<__cxxNullPtrT>
21+
// CHECK: typealias WrappedMagicConstIntArr = MagicWrapper<__cxxConst<[CInt]>>
22+
// CHECK: typealias WrappedVolatileIntRef = EmptyWrapper<__cxxLRef<__cxxVolatile<CInt>>>
2123

2224
// CHECK: typealias DoubleWrappedInt = DoubleWrapper<MagicWrapper<CInt>>
2325
// CHECK: typealias DoubleWrappedIntConst = DoubleWrapper<MagicWrapper<__cxxConst<CInt>>>

0 commit comments

Comments
 (0)