Skip to content

Commit 821bfdb

Browse files
authored
Merge pull request #15201 from slavapestov/special-init-name
Use a special DeclBaseName for `init`
2 parents 4850d54 + 34fd4ae commit 821bfdb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+279
-113
lines changed

include/swift/AST/Identifier.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ class DeclBaseName {
215215
enum class Kind: uint8_t {
216216
Normal,
217217
Subscript,
218+
Constructor,
218219
Destructor
219220
};
220221

@@ -224,6 +225,8 @@ class DeclBaseName {
224225
/// This is an implementation detail that should never leak outside of
225226
/// DeclName.
226227
static void *SubscriptIdentifierData;
228+
/// As above, for special constructor DeclNames.
229+
static void *ConstructorIdentifierData;
227230
/// As above, for special destructor DeclNames.
228231
static void *DestructorIdentifierData;
229232

@@ -238,13 +241,19 @@ class DeclBaseName {
238241
return DeclBaseName(Identifier((const char *)SubscriptIdentifierData));
239242
}
240243

244+
static DeclBaseName createConstructor() {
245+
return DeclBaseName(Identifier((const char *)ConstructorIdentifierData));
246+
}
247+
241248
static DeclBaseName createDestructor() {
242249
return DeclBaseName(Identifier((const char *)DestructorIdentifierData));
243250
}
244251

245252
Kind getKind() const {
246253
if (Ident.get() == SubscriptIdentifierData) {
247254
return Kind::Subscript;
255+
} else if (Ident.get() == ConstructorIdentifierData) {
256+
return Kind::Constructor;
248257
} else if (Ident.get() == DestructorIdentifierData) {
249258
return Kind::Destructor;
250259
} else {
@@ -282,6 +291,8 @@ class DeclBaseName {
282291
return getIdentifier().str();
283292
case Kind::Subscript:
284293
return "subscript";
294+
case Kind::Constructor:
295+
return "init";
285296
case Kind::Destructor:
286297
return "deinit";
287298
}

include/swift/AST/KnownIdentifiers.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ IDENTIFIER(forKey)
6161
IDENTIFIER(from)
6262
IDENTIFIER(fromRaw)
6363
IDENTIFIER(hashValue)
64-
IDENTIFIER(init)
6564
IDENTIFIER(initialize)
6665
IDENTIFIER(initStorage)
6766
IDENTIFIER(initialValue)

include/swift/Parse/Parser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1427,7 +1427,8 @@ ParsedDeclName parseDeclName(StringRef name) LLVM_READONLY;
14271427
DeclName formDeclName(ASTContext &ctx,
14281428
StringRef baseName,
14291429
ArrayRef<StringRef> argumentLabels,
1430-
bool isFunctionName);
1430+
bool isFunctionName,
1431+
bool isInitializer);
14311432

14321433
/// Parse a stringified Swift declaration name, e.g. "init(frame:)".
14331434
DeclName parseDeclName(ASTContext &ctx, StringRef name);

include/swift/Serialization/ModuleFormat.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
5757
/// Don't worry about adhering to the 80-column limit for this line.
58-
const uint16_t VERSION_MINOR = 402; // Last change: effects(releasenone)
58+
const uint16_t VERSION_MINOR = 403; // Last change: `init` special name
5959

6060
using DeclIDField = BCFixed<31>;
6161

@@ -380,6 +380,7 @@ using OptionalTypeKindField = BCFixed<2>;
380380
enum class DeclNameKind: uint8_t {
381381
Normal,
382382
Subscript,
383+
Constructor,
383384
Destructor
384385
};
385386

@@ -394,6 +395,8 @@ enum SpecialIdentifierID : uint8_t {
394395
OBJC_HEADER_MODULE_ID,
395396
/// Special value for the special subscript name
396397
SUBSCRIPT_ID,
398+
/// Special value for the special constructor name
399+
CONSTRUCTOR_ID,
397400
/// Special value for the special destructor name
398401
DESTRUCTOR_ID,
399402

lib/AST/Decl.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2773,7 +2773,7 @@ void ClassDecl::addImplicitDestructor() {
27732773

27742774
bool ClassDecl::hasMissingDesignatedInitializers() const {
27752775
auto *mutableThis = const_cast<ClassDecl *>(this);
2776-
(void)mutableThis->lookupDirect(getASTContext().Id_init,
2776+
(void)mutableThis->lookupDirect(DeclBaseName::createConstructor(),
27772777
/*ignoreNewExtensions*/true);
27782778
return Bits.ClassDecl.HasMissingDesignatedInitializers;
27792779
}
@@ -2821,11 +2821,10 @@ bool ClassDecl::inheritsSuperclassInitializers(LazyResolver *resolver) {
28212821

28222822
// Look at all of the initializers of the subclass to gather the initializers
28232823
// they override from the superclass.
2824-
auto &ctx = getASTContext();
28252824
llvm::SmallPtrSet<ConstructorDecl *, 4> overriddenInits;
28262825
if (resolver)
28272826
resolver->resolveImplicitConstructors(this);
2828-
for (auto member : lookupDirect(ctx.Id_init)) {
2827+
for (auto member : lookupDirect(DeclBaseName::createConstructor())) {
28292828
auto ctor = dyn_cast<ConstructorDecl>(member);
28302829
if (!ctor)
28312830
continue;
@@ -2855,7 +2854,7 @@ bool ClassDecl::inheritsSuperclassInitializers(LazyResolver *resolver) {
28552854
// Note: This should be treated as a lookup for intra-module dependency
28562855
// purposes, but a subclass already depends on its superclasses and any
28572856
// extensions for many other reasons.
2858-
for (auto member : superclassDecl->lookupDirect(ctx.Id_init)) {
2857+
for (auto member : superclassDecl->lookupDirect(DeclBaseName::createConstructor())) {
28592858
if (AvailableAttr::isUnavailable(member))
28602859
continue;
28612860

@@ -5195,6 +5194,8 @@ ConstructorDecl::ConstructorDecl(DeclName Name, SourceLoc ConstructorLoc,
51955194
Bits.ConstructorDecl.HasStubImplementation = 0;
51965195
Bits.ConstructorDecl.InitKind = static_cast<unsigned>(CtorInitializerKind::Designated);
51975196
Bits.ConstructorDecl.Failability = static_cast<unsigned>(Failability);
5197+
5198+
assert(Name.getBaseName() == DeclBaseName::createConstructor());
51985199
}
51995200

52005201
void ConstructorDecl::setParameterLists(ParamDecl *selfDecl,
@@ -5441,7 +5442,7 @@ ConstructorDecl::getDelegatingOrChainedInitKind(DiagnosticEngine *diags,
54415442
} else if (auto *CRE = dyn_cast<ConstructorRefCallExpr>(Callee)) {
54425443
arg = CRE->getArg();
54435444
} else if (auto *dotExpr = dyn_cast<UnresolvedDotExpr>(Callee)) {
5444-
if (dotExpr->getName().getBaseName() != "init")
5445+
if (dotExpr->getName().getBaseName() != DeclBaseName::createConstructor())
54455446
return { true, E };
54465447

54475448
arg = dotExpr->getBase();

lib/AST/Identifier.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ using namespace swift;
2222

2323
void *DeclBaseName::SubscriptIdentifierData =
2424
&DeclBaseName::SubscriptIdentifierData;
25+
void *DeclBaseName::ConstructorIdentifierData =
26+
&DeclBaseName::ConstructorIdentifierData;
2527
void *DeclBaseName::DestructorIdentifierData =
2628
&DeclBaseName::DestructorIdentifierData;
2729

lib/AST/NameLookup.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ bool swift::removeOverriddenDecls(SmallVectorImpl<ValueDecl*> &decls) {
8383
if (decls.empty())
8484
return false;
8585

86-
ASTContext &ctx = decls.front()->getASTContext();
8786
llvm::SmallPtrSet<ValueDecl*, 8> overridden;
8887
for (auto decl : decls) {
8988
while (auto overrides = decl->getOverriddenDecl()) {
@@ -95,7 +94,7 @@ bool swift::removeOverriddenDecls(SmallVectorImpl<ValueDecl*> &decls) {
9594
// C.init overrides B.init overrides A.init, but only C.init and
9695
// A.init are in the chain. Make sure we still remove A.init from the
9796
// set in this case.
98-
if (decl->getFullName().getBaseName() == ctx.Id_init) {
97+
if (decl->getFullName().getBaseName() == DeclBaseName::createConstructor()) {
9998
/// FIXME: Avoid the possibility of an infinite loop by fixing the root
10099
/// cause instead (incomplete circularity detection).
101100
assert(decl != overrides && "Circular class inheritance?");
@@ -1367,7 +1366,7 @@ TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect(
13671366
// that appears to special-case initializers (clang-imported initializer
13681367
// sorting, implicit initializer synthesis), so for the time being we have to
13691368
// turn it off for them entirely.
1370-
if (name.getBaseName() == ctx.Id_init)
1369+
if (name.getBaseName() == DeclBaseName::createConstructor())
13711370
useNamedLazyMemberLoading = false;
13721371

13731372
DEBUG(llvm::dbgs() << getNameStr() << ".lookupDirect(" << name << ")"
@@ -1753,7 +1752,7 @@ bool DeclContext::lookupQualified(Type type,
17531752

17541753
// Make sure we've resolved implicit members, if we need them.
17551754
if (typeResolver) {
1756-
if (member.getBaseName() == ctx.Id_init)
1755+
if (member.getBaseName() == DeclBaseName::createConstructor())
17571756
typeResolver->resolveImplicitConstructors(current);
17581757

17591758
typeResolver->resolveImplicitMember(current, member);
@@ -1782,7 +1781,7 @@ bool DeclContext::lookupQualified(Type type,
17821781
// current class permits inheritance. Even then, only find complete
17831782
// object initializers.
17841783
bool visitSuperclass = true;
1785-
if (member.getBaseName() == ctx.Id_init) {
1784+
if (member.getBaseName() == DeclBaseName::createConstructor()) {
17861785
if (classDecl->inheritsSuperclassInitializers(typeResolver))
17871786
onlyCompleteObjectInits = true;
17881787
else

lib/ClangImporter/IAMInference.cpp

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ class IAMInference {
212212
IAMResult importAsTypeID(const clang::QualType typeIDTy,
213213
EffectiveClangContext effectiveDC) {
214214
++SuccessImportAsTypeID;
215-
return {formDeclName("typeID"), IAMAccessorKind::Getter, effectiveDC};
215+
return {formDeclName("typeID", /*isInitializer=*/false),
216+
IAMAccessorKind::Getter, effectiveDC};
216217
}
217218

218219
// Init
@@ -245,7 +246,7 @@ class IAMInference {
245246

246247
assert(didDrop != 0 && "specifier not present?");
247248
}
248-
return {formDeclName("init", params, prefix), effectiveDC};
249+
return {formDeclName("init", true, params, prefix), effectiveDC};
249250
}
250251

251252
// Instance computed property
@@ -259,7 +260,8 @@ class IAMInference {
259260
propSpec == "Get" ? IAMAccessorKind::Getter : IAMAccessorKind::Setter;
260261
assert(kind == IAMAccessorKind::Getter || pairedAccessor && "no set-only");
261262

262-
return {formDeclName(name), kind, selfIdx, effectiveDC};
263+
return {formDeclName(name, /*isInitializer=*/false),
264+
kind, selfIdx, effectiveDC};
263265
}
264266

265267
// Instance method
@@ -268,14 +270,15 @@ class IAMInference {
268270
ArrayRef<const clang::ParmVarDecl *> nonSelfParams,
269271
EffectiveClangContext effectiveDC) {
270272
++SuccessImportAsInstanceMethod;
271-
return {formDeclName(name, nonSelfParams), selfIdx, effectiveDC};
273+
return {formDeclName(name, /*isInitializer=*/false, nonSelfParams),
274+
selfIdx, effectiveDC};
272275
}
273276

274277
// Static stored property
275278
IAMResult importAsStaticProperty(StringRef name,
276279
EffectiveClangContext effectiveDC) {
277280
++SuccessImportAsStaticProperty;
278-
return {formDeclName(name), effectiveDC};
281+
return {formDeclName(name, /*isInitializer=*/false), effectiveDC};
279282
}
280283

281284
// Static computed property
@@ -289,7 +292,8 @@ class IAMInference {
289292
propSpec == "Get" ? IAMAccessorKind::Getter : IAMAccessorKind::Setter;
290293
assert(kind == IAMAccessorKind::Getter || pairedAccessor && "no set-only");
291294

292-
return {formDeclName(name), kind, effectiveDC};
295+
return {formDeclName(name, /*isInitializer=*/false),
296+
kind, effectiveDC};
293297
}
294298

295299
// Static method
@@ -298,7 +302,8 @@ class IAMInference {
298302
ArrayRef<const clang::ParmVarDecl *> nonSelfParams,
299303
EffectiveClangContext effectiveDC) {
300304
++SuccessImportAsStaticMethod;
301-
return {formDeclName(name, nonSelfParams), effectiveDC};
305+
return {formDeclName(name, /*isInitializer=*/false, nonSelfParams),
306+
effectiveDC};
302307
}
303308

304309
Identifier getIdentifier(StringRef str) {
@@ -379,18 +384,20 @@ class IAMInference {
379384
return clangLookupFunction(pairName);
380385
}
381386

382-
Identifier getHumbleIdentifier(StringRef name) {
387+
DeclBaseName getHumbleBaseName(StringRef name, bool isInitializer) {
383388
// Lower-camel-case the incoming name
384389
NameBuffer buf;
385390
formHumbleCamelName(name, buf);
391+
if (isInitializer && buf == "init")
392+
return DeclBaseName::createConstructor();
386393
return getIdentifier(buf);
387394
}
388395

389-
DeclName formDeclName(StringRef baseName) {
390-
return {getHumbleIdentifier(baseName)};
396+
DeclName formDeclName(StringRef baseName, bool isInitializer) {
397+
return {getHumbleBaseName(baseName, isInitializer)};
391398
}
392399

393-
DeclName formDeclName(StringRef baseName,
400+
DeclName formDeclName(StringRef baseName, bool isInitializer,
394401
ArrayRef<const clang::ParmVarDecl *> params,
395402
StringRef firstPrefix = "") {
396403

@@ -402,7 +409,7 @@ class IAMInference {
402409
// We need to form an argument label, despite there being no argument
403410
NameBuffer paramName;
404411
formHumbleCamelName(firstPrefix, paramName);
405-
return {context, getHumbleIdentifier(baseName),
412+
return {context, getHumbleBaseName(baseName, isInitializer),
406413
getIdentifier(paramName)};
407414
}
408415

@@ -426,7 +433,9 @@ class IAMInference {
426433
SmallVector<Identifier, 8> argLabels;
427434
for (auto str : argStrs)
428435
argLabels.push_back(getIdentifier(str));
429-
DEBUG((beforeOmit = {context, getHumbleIdentifier(baseName), argLabels}));
436+
DEBUG((beforeOmit = {context,
437+
getHumbleBaseName(baseName, isInitializer),
438+
argLabels}));
430439
}
431440

432441
SmallVector<OmissionTypeName, 8> paramTypeNames;
@@ -435,16 +444,18 @@ class IAMInference {
435444
clangSema.getASTContext(), param->getType()));
436445
}
437446

438-
auto humbleBaseName = getHumbleIdentifier(baseName);
439-
baseName = humbleBaseName.str();
447+
auto humbleBaseName = getHumbleBaseName(baseName, isInitializer);
448+
baseName = humbleBaseName.userFacingName();
440449
bool didOmit =
441450
omitNeedlessWords(baseName, argStrs, "", "", "", paramTypeNames, false,
442451
false, nullptr, scratch);
443452
SmallVector<Identifier, 8> argLabels;
444453
for (auto str : argStrs)
445454
argLabels.push_back(getIdentifier(str));
446455

447-
DeclName ret = {context, getHumbleIdentifier(baseName), argLabels};
456+
DeclName ret(context,
457+
getHumbleBaseName(baseName, isInitializer),
458+
argLabels);
448459

449460
if (didOmit) {
450461
++OmitNumTimes;

lib/ClangImporter/ImportDecl.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ makeEnumRawValueConstructor(ClangImporter::Implementation &Impl,
444444

445445
auto paramPL = ParameterList::createWithoutLoc(param);
446446

447-
DeclName name(C, C.Id_init, paramPL);
447+
DeclName name(C, DeclBaseName::createConstructor(), paramPL);
448448
auto *ctorDecl =
449449
new (C) ConstructorDecl(name, enumDecl->getLoc(),
450450
OTK_Optional, /*FailabilityLoc=*/SourceLoc(),
@@ -1167,7 +1167,7 @@ createDefaultConstructor(ClangImporter::Implementation &Impl,
11671167
auto emptyPL = ParameterList::createEmpty(context);
11681168

11691169
// Create the constructor.
1170-
DeclName name(context, context.Id_init, emptyPL);
1170+
DeclName name(context, DeclBaseName::createConstructor(), emptyPL);
11711171
auto constructor = new (context) ConstructorDecl(
11721172
name, structDecl->getLoc(), OTK_None, /*FailabilityLoc=*/SourceLoc(),
11731173
/*Throws=*/false, /*ThrowsLoc=*/SourceLoc(), selfDecl, emptyPL,
@@ -1282,7 +1282,7 @@ createValueConstructor(ClangImporter::Implementation &Impl,
12821282
ParameterList::create(context, valueParameters)};
12831283

12841284
// Create the constructor
1285-
DeclName name(context, context.Id_init, paramLists[1]);
1285+
DeclName name(context, DeclBaseName::createConstructor(), paramLists[1]);
12861286
auto constructor = new (context) ConstructorDecl(
12871287
name, structDecl->getLoc(), OTK_None, /*FailabilityLoc=*/SourceLoc(),
12881288
/*Throws=*/false, /*ThrowsLoc=*/SourceLoc(), selfDecl, paramLists[1],
@@ -2264,7 +2264,7 @@ namespace {
22642264

22652265
bool isFactoryInit(ImportedName &name) {
22662266
return name &&
2267-
name.getDeclName().getBaseName() == Impl.SwiftContext.Id_init &&
2267+
name.getDeclName().getBaseName() == DeclBaseName::createConstructor() &&
22682268
(name.getInitKind() == CtorInitializerKind::Factory ||
22692269
name.getInitKind() == CtorInitializerKind::ConvenienceFactory);
22702270
}
@@ -3521,7 +3521,7 @@ namespace {
35213521
DeclName name = accessorInfo ? DeclName() : importedName.getDeclName();
35223522
if (importedName.importAsMember()) {
35233523
// Handle initializers.
3524-
if (name.getBaseName() == Impl.SwiftContext.Id_init) {
3524+
if (name.getBaseName() == DeclBaseName::createConstructor()) {
35253525
assert(!accessorInfo);
35263526
return importGlobalAsInitializer(decl, name, dc,
35273527
importedName.getInitKind(),
@@ -7234,7 +7234,7 @@ void SwiftDeclConverter::importInheritedConstructors(
72347234
// If we have a superclass, import from it.
72357235
if (auto superclassClangDecl = superclass->getClangDecl()) {
72367236
if (isa<clang::ObjCInterfaceDecl>(superclassClangDecl)) {
7237-
inheritConstructors(superclass->lookupDirect(Impl.SwiftContext.Id_init),
7237+
inheritConstructors(superclass->lookupDirect(DeclBaseName::createConstructor()),
72387238
kind);
72397239
}
72407240
}

lib/ClangImporter/ImportName.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1712,7 +1712,8 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
17121712
}
17131713
}
17141714

1715-
result.declName = formDeclName(swiftCtx, baseName, argumentNames, isFunction);
1715+
result.declName = formDeclName(swiftCtx, baseName, argumentNames, isFunction,
1716+
isInitializer);
17161717
return result;
17171718
}
17181719

0 commit comments

Comments
 (0)