Skip to content

Commit ef53447

Browse files
committed
Merge remote-tracking branch 'origin/main' into rebranch
2 parents c13a728 + 7b78a1d commit ef53447

19 files changed

+435
-85
lines changed

include/swift/AST/DiagnosticsClangImporter.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ ERROR(foreign_reference_types_release_non_void_return_type, none,
270270
ERROR(foreign_reference_types_retain_release_not_a_function_decl, none,
271271
"specified %select{retain|release}0 function '%1' is not a function",
272272
(bool, StringRef))
273+
ERROR(foreign_reference_types_retain_release_not_an_instance_function, none,
274+
"specified %select{retain|release}0 function '%1' is a static function; expected an instance function",
275+
(bool, StringRef))
273276
ERROR(conforms_to_missing_dot, none,
274277
"expected module name and protocol name separated by '.' in protocol "
275278
"conformance; '%0' is invalid",

lib/ClangImporter/ClangImporter.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8010,10 +8010,27 @@ getRefParentDecls(const clang::RecordDecl *decl, ASTContext &ctx,
80108010
}
80118011

80128012
llvm::SmallVector<ValueDecl *, 1>
8013-
importer::getValueDeclsForName(
8014-
const clang::Decl *decl, ASTContext &ctx, StringRef name) {
8013+
importer::getValueDeclsForName(NominalTypeDecl *decl, StringRef name) {
8014+
// If the name is empty, don't try to find any decls.
8015+
if (name.empty())
8016+
return {};
8017+
8018+
auto &ctx = decl->getASTContext();
8019+
auto clangDecl = decl->getClangDecl();
80158020
llvm::SmallVector<ValueDecl *, 1> results;
8016-
auto *clangMod = decl->getOwningModule();
8021+
8022+
if (name.starts_with(".")) {
8023+
// Look for a member of decl instead of a global.
8024+
StringRef memberName = name.drop_front(1);
8025+
if (memberName.empty())
8026+
return {};
8027+
auto declName = DeclName(ctx.getIdentifier(memberName));
8028+
auto allResults = evaluateOrDefault(
8029+
ctx.evaluator, ClangRecordMemberLookup({decl, declName}), {});
8030+
return SmallVector<ValueDecl *, 1>(allResults.begin(), allResults.end());
8031+
}
8032+
8033+
auto *clangMod = clangDecl->getOwningModule();
80178034
if (clangMod && clangMod->isSubModule())
80188035
clangMod = clangMod->getTopLevelModule();
80198036
if (clangMod) {
@@ -8609,7 +8626,7 @@ CustomRefCountingOperationResult CustomRefCountingOperation::evaluate(
86098626
return {CustomRefCountingOperationResult::immortal, nullptr, name};
86108627

86118628
llvm::SmallVector<ValueDecl *, 1> results =
8612-
getValueDeclsForName(swiftDecl->getClangDecl(), ctx, name);
8629+
getValueDeclsForName(const_cast<ClassDecl*>(swiftDecl), name);
86138630
if (results.size() == 1)
86148631
return {CustomRefCountingOperationResult::foundOperation, results.front(),
86158632
name};

lib/ClangImporter/ImportDecl.cpp

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,6 +2789,7 @@ namespace {
27892789

27902790
enum class RetainReleaseOperationKind {
27912791
notAfunction,
2792+
notAnInstanceFunction,
27922793
invalidReturnType,
27932794
invalidParameters,
27942795
valid
@@ -2802,17 +2803,32 @@ namespace {
28022803
if (!operationFn)
28032804
return RetainReleaseOperationKind::notAfunction;
28042805

2805-
if (operationFn->getParameters()->size() != 1)
2806-
return RetainReleaseOperationKind::invalidParameters;
2806+
if (operationFn->isStatic())
2807+
return RetainReleaseOperationKind::notAnInstanceFunction;
28072808

2808-
Type paramType =
2809-
operationFn->getParameters()->get(0)->getInterfaceType();
2810-
// Unwrap if paramType is an OptionalType
2811-
if (Type optionalType = paramType->getOptionalObjectType()) {
2812-
paramType = optionalType;
2813-
}
2809+
if (operationFn->isInstanceMember()) {
2810+
if (operationFn->getParameters()->size() != 0)
2811+
return RetainReleaseOperationKind::invalidParameters;
2812+
} else {
2813+
if (operationFn->getParameters()->size() != 1)
2814+
return RetainReleaseOperationKind::invalidParameters;
2815+
}
2816+
2817+
Type paramType;
2818+
NominalTypeDecl *paramDecl = nullptr;
2819+
if (!operationFn->isInstanceMember()) {
2820+
paramType =
2821+
operationFn->getParameters()->get(0)->getInterfaceType();
2822+
// Unwrap if paramType is an OptionalType
2823+
if (Type optionalType = paramType->getOptionalObjectType()) {
2824+
paramType = optionalType;
2825+
}
28142826

2815-
swift::NominalTypeDecl *paramDecl = paramType->getAnyNominal();
2827+
paramDecl = paramType->getAnyNominal();
2828+
} else {
2829+
paramDecl = cast<NominalTypeDecl>(operationFn->getParent());
2830+
paramType = paramDecl->getDeclaredInterfaceType();
2831+
}
28162832

28172833
// The return type should be void (for release functions), or void
28182834
// or the parameter type (for retain functions).
@@ -2897,6 +2913,12 @@ namespace {
28972913
diag::foreign_reference_types_retain_release_not_a_function_decl,
28982914
false, retainOperation.name);
28992915
break;
2916+
case RetainReleaseOperationKind::notAnInstanceFunction:
2917+
Impl.diagnose(
2918+
loc,
2919+
diag::foreign_reference_types_retain_release_not_an_instance_function,
2920+
false, retainOperation.name);
2921+
break;
29002922
case RetainReleaseOperationKind::invalidReturnType:
29012923
Impl.diagnose(
29022924
loc,
@@ -2962,6 +2984,12 @@ namespace {
29622984
diag::foreign_reference_types_retain_release_not_a_function_decl,
29632985
true, releaseOperation.name);
29642986
break;
2987+
case RetainReleaseOperationKind::notAnInstanceFunction:
2988+
Impl.diagnose(
2989+
loc,
2990+
diag::foreign_reference_types_retain_release_not_an_instance_function,
2991+
true, releaseOperation.name);
2992+
break;
29652993
case RetainReleaseOperationKind::invalidReturnType:
29662994
Impl.diagnose(
29672995
loc,
@@ -3243,26 +3271,12 @@ namespace {
32433271

32443272
Decl *VisitClassTemplateSpecializationDecl(
32453273
const clang::ClassTemplateSpecializationDecl *decl) {
3246-
bool isPair = decl->getSpecializedTemplate()->isInStdNamespace() &&
3247-
decl->getSpecializedTemplate()->getName() == "pair";
3248-
3249-
// Before we go any further, check if we've already got tens of thousands
3250-
// of specializations. If so, it means we're likely instantiating a very
3251-
// deep/complex template, or we've run into an infinite loop. In either
3252-
// case, its not worth the compile time, so bail.
3253-
// TODO: this could be configurable at some point.
3254-
size_t specializationLimit = !isPair ? 1000 : 10000;
3255-
if (size_t(
3256-
llvm::size(decl->getSpecializedTemplate()->specializations())) >
3257-
specializationLimit) {
3258-
// Note: it would be nice to import a dummy unavailable struct,
3259-
// but we would then need to instantiate the template here,
3260-
// as we cannot import a struct without a definition. That would
3261-
// defeat the purpose. Also, we can't make the dummy
3262-
// struct simply unavailable, as that still makes the
3263-
// typelias that references it available.
3274+
// Importing std::conditional substantially increases compile times when
3275+
// building with libstdc++, i.e. on most Linux distros.
3276+
if (decl->isInStdNamespace() && decl->getIdentifier() &&
3277+
(decl->getName() == "conditional" || decl->getName() == "__or_" ||
3278+
decl->getName() == "_Expr"))
32643279
return nullptr;
3265-
}
32663280

32673281
// `decl->getDefinition()` can return nullptr before the call to sema and
32683282
// return its definition afterwards.

lib/ClangImporter/ImporterImpl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2202,7 +2202,7 @@ ImportedType findOptionSetEnum(clang::QualType type,
22022202
///
22032203
/// The name we're looking for is the Swift name.
22042204
llvm::SmallVector<ValueDecl *, 1>
2205-
getValueDeclsForName(const clang::Decl *decl, ASTContext &ctx, StringRef name);
2205+
getValueDeclsForName(NominalTypeDecl* decl, StringRef name);
22062206

22072207
} // end namespace importer
22082208
} // end namespace swift

lib/ClangImporter/SwiftDeclSynthesizer.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2948,8 +2948,7 @@ FuncDecl *SwiftDeclSynthesizer::findExplicitDestroy(
29482948
if (!destroyFuncName.consume_front("destroy:"))
29492949
continue;
29502950

2951-
auto decls = getValueDeclsForName(
2952-
clangType, nominal->getASTContext(), destroyFuncName);
2951+
auto decls = getValueDeclsForName(nominal, destroyFuncName);
29532952
for (auto decl : decls) {
29542953
auto func = dyn_cast<FuncDecl>(decl);
29552954
if (!func)

lib/IRGen/GenObjC.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,11 @@ void IRGenFunction::emitBlockRelease(llvm::Value *value) {
17241724

17251725
void IRGenFunction::emitForeignReferenceTypeLifetimeOperation(
17261726
ValueDecl *fn, llvm::Value *value, bool needsNullCheck) {
1727+
if (auto originalDecl = fn->getASTContext()
1728+
.getClangModuleLoader()
1729+
->getOriginalForClonedMember(fn))
1730+
fn = originalDecl;
1731+
17271732
assert(fn->getClangDecl() && isa<clang::FunctionDecl>(fn->getClangDecl()));
17281733

17291734
auto clangFn = cast<clang::FunctionDecl>(fn->getClangDecl());

stdlib/public/core/StringStorage.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
internal protocol _AbstractStringStorage: _NSCopying {
1818
var asString: String { get }
19+
var utf16: String.UTF16View { get }
1920
var count: Int { get }
2021
var isASCII: Bool { get }
2122
var start: UnsafePointer<UInt8> { get }
@@ -26,6 +27,7 @@ internal protocol _AbstractStringStorage: _NSCopying {
2627

2728
internal protocol _AbstractStringStorage {
2829
var asString: String { get }
30+
var utf16: String.UTF16View { get }
2931
var count: Int { get }
3032
var isASCII: Bool { get }
3133
var start: UnsafePointer<UInt8> { get }
@@ -295,6 +297,10 @@ final internal class __StringStorage
295297
get { String(_StringGuts(self)) }
296298
}
297299

300+
@inline(__always)
301+
final internal var utf16: String.UTF16View {
302+
String.UTF16View(_StringGuts(self))
303+
}
298304

299305
private init(_doNotCallMe: ()) {
300306
_internalInvariantFailure("Use the create method")
@@ -721,6 +727,11 @@ final internal class __SharedStringStorage
721727
return String(_StringGuts(self))
722728
}
723729
}
730+
731+
@inline(__always)
732+
final internal var utf16: String.UTF16View {
733+
String.UTF16View(_StringGuts(self))
734+
}
724735

725736
internal init(
726737
_mortal ptr: UnsafePointer<UInt8>,

stdlib/public/core/StringStorageBridge.swift

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,17 @@ extension String {
4343

4444
// ObjC interfaces.
4545
extension _AbstractStringStorage {
46+
4647
@inline(__always)
4748
@_effects(releasenone)
4849
internal func _getCharacters(
4950
_ buffer: UnsafeMutablePointer<UInt16>, _ aRange: _SwiftNSRange
5051
) {
51-
_precondition(aRange.location >= 0 && aRange.length >= 0,
52-
"Range out of bounds")
53-
// Note: `count` is counting UTF-8 code units, while `aRange` is measured in
54-
// UTF-16 offsets. This precondition is a necessary, but not sufficient test
55-
// for validity. (More precise checks are done in UTF16View._nativeCopy.)
56-
_precondition(aRange.location + aRange.length <= Int(count),
57-
"Range out of bounds")
58-
5952
let range = unsafe Range(
6053
_uncheckedBounds: (aRange.location, aRange.location+aRange.length))
61-
let str = asString
62-
unsafe str._copyUTF16CodeUnits(
54+
unsafe utf16._nativeCopy(
6355
into: UnsafeMutableBufferPointer(start: buffer, count: range.count),
64-
range: range)
56+
offsetRange: range)
6557
}
6658

6759
@inline(__always)
@@ -116,6 +108,26 @@ extension _AbstractStringStorage {
116108
return _cocoaLengthOfBytesInEncodingTrampoline(self, encoding)
117109
}
118110
}
111+
112+
// The caller info isn't useful here anyway because it's never client code,
113+
// so this makes sure that _character(at:) doesn't have inlined assertion bits
114+
@inline(never)
115+
internal func _characterAtIndexOutOfBounds() -> Never {
116+
_preconditionFailure("String index is out of bounds")
117+
}
118+
119+
@inline(__always)
120+
@_effects(readonly)
121+
internal func _character(at offset: Int) -> UInt16 {
122+
if _fastPath(isASCII) {
123+
if (_fastPath(offset < count && offset >= 0)) {
124+
return unsafe UInt16((start + offset).pointee)
125+
}
126+
_characterAtIndexOutOfBounds()
127+
} else {
128+
return utf16[nativeNonASCIIOffset: offset]
129+
}
130+
}
119131

120132
@_effects(readonly)
121133
internal func _nativeIsEqual<T:_AbstractStringStorage>(
@@ -176,7 +188,7 @@ extension _AbstractStringStorage {
176188
start: utf16Ptr,
177189
count: otherUTF16Length
178190
)
179-
return unsafe asString.utf16.elementsEqual(utf16Buffer) ? 1 : 0
191+
return unsafe utf16.elementsEqual(utf16Buffer) ? 1 : 0
180192
}
181193

182194
/*
@@ -197,7 +209,7 @@ extension __StringStorage {
197209
if isASCII {
198210
return count
199211
}
200-
return asString.utf16.count
212+
return utf16.count
201213
}
202214
}
203215

@@ -214,8 +226,7 @@ extension __StringStorage {
214226
@objc(characterAtIndex:)
215227
@_effects(readonly)
216228
final internal func character(at offset: Int) -> UInt16 {
217-
let str = asString
218-
return str.utf16[str._toUTF16Index(offset)]
229+
_character(at: offset)
219230
}
220231

221232
@objc(getCharacters:range:)
@@ -313,7 +324,7 @@ extension __SharedStringStorage {
313324
if isASCII {
314325
return count
315326
}
316-
return asString.utf16.count
327+
return utf16.count
317328
}
318329
}
319330

@@ -330,8 +341,7 @@ extension __SharedStringStorage {
330341
@objc(characterAtIndex:)
331342
@_effects(readonly)
332343
final internal func character(at offset: Int) -> UInt16 {
333-
let str = asString
334-
return str.utf16[str._toUTF16Index(offset)]
344+
_character(at: offset)
335345
}
336346

337347
@objc(getCharacters:range:)

0 commit comments

Comments
 (0)