Skip to content

Commit ec6fc4d

Browse files
authored
Merge pull request #9989 from ahoppen/introduce-special-declnames
Introduce special decl names
2 parents 8a32202 + 2dd670b commit ec6fc4d

34 files changed

+491
-151
lines changed

include/swift/AST/Identifier.h

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ enum class DeclRefKind {
5151
/// ASTContext. It just wraps a nul-terminated "const char*".
5252
class Identifier {
5353
friend class ASTContext;
54+
friend class DeclBaseName;
55+
5456
const char *Pointer;
5557

5658
/// Constructor, only accessible by ASTContext, which handles the uniquing.
@@ -207,14 +209,39 @@ namespace swift {
207209
/// Wrapper that may either be an Identifier or a special name
208210
/// (e.g. for subscripts)
209211
class DeclBaseName {
212+
public:
213+
enum class Kind: uint8_t {
214+
Normal,
215+
Subscript
216+
};
217+
218+
private:
219+
/// In a special DeclName represenenting a subscript, this opaque pointer
220+
/// is used as the data of the base name identifier.
221+
/// This is an implementation detail that should never leak outside of
222+
/// DeclName.
223+
static void *SubscriptIdentifierData;
224+
210225
Identifier Ident;
211226

212227
public:
213228
DeclBaseName() : DeclBaseName(Identifier()) {}
214229

215230
DeclBaseName(Identifier I) : Ident(I) {}
216231

217-
bool isSpecial() const { return false; }
232+
static DeclBaseName createSubscript() {
233+
return DeclBaseName(Identifier((const char *)SubscriptIdentifierData));
234+
}
235+
236+
Kind getKind() const {
237+
if (Ident.get() == SubscriptIdentifierData) {
238+
return Kind::Subscript;
239+
} else {
240+
return Kind::Normal;
241+
}
242+
}
243+
244+
bool isSpecial() const { return getKind() != Kind::Normal; }
218245

219246
/// Return the identifier backing the name. Assumes that the name is not
220247
/// special.
@@ -238,12 +265,17 @@ class DeclBaseName {
238265
StringRef userFacingName() const {
239266
if (empty())
240267
return "_";
241-
return getIdentifier().str();
268+
269+
switch (getKind()) {
270+
case Kind::Normal:
271+
return getIdentifier().str();
272+
case Kind::Subscript:
273+
return "subscript";
274+
}
242275
}
243276

244277
int compare(DeclBaseName other) const {
245-
// TODO: Sort special names cleverly
246-
return getIdentifier().compare(other.getIdentifier());
278+
return userFacingName().compare(other.userFacingName());
247279
}
248280

249281
bool operator==(StringRef Str) const {

include/swift/AST/KnownIdentifiers.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ IDENTIFIER(simd)
9090
IDENTIFIER(some)
9191
IDENTIFIER(storage)
9292
IDENTIFIER(stringValue)
93-
IDENTIFIER(subscript)
9493
IDENTIFIER(super)
9594
IDENTIFIER(superDecoder)
9695
IDENTIFIER(superEncoder)

include/swift/Serialization/ModuleFile.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,11 @@ class ModuleFile : public LazyMemberLoader {
740740
/// Returns the type with the given ID, deserializing it if needed.
741741
llvm::Expected<Type> getTypeChecked(serialization::TypeID TID);
742742

743-
/// Returns the identifier with the given ID, deserializing it if needed.
743+
/// Returns the base name with the given ID, deserializing it if needed.
744+
DeclBaseName getDeclBaseName(serialization::IdentifierID IID);
745+
746+
/// Convenience method to retrieve the identifier backing the name with
747+
/// given ID. Asserts that the name with this ID is not special.
744748
Identifier getIdentifier(serialization::IdentifierID IID);
745749

746750
/// Returns the decl with the given ID, deserializing it if needed.

include/swift/Serialization/ModuleFormat.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
5454
/// in source control, you should also update the comment to briefly
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.
57-
const uint16_t VERSION_MINOR = 349; // Last change: '@autoclosure' and '@noescape' no longer decl attributes.
57+
const uint16_t VERSION_MINOR = 350; // Last change: special decl names
5858

5959
using DeclID = PointerEmbeddedInt<unsigned, 31>;
6060
using DeclIDField = BCFixed<31>;
@@ -342,18 +342,27 @@ using OptionalTypeKindField = BCFixed<2>;
342342

343343
// These IDs must \em not be renumbered or reordered without incrementing
344344
// VERSION_MAJOR.
345-
enum SpecialModuleID : uint8_t {
345+
enum class DeclNameKind: uint8_t {
346+
Normal,
347+
Subscript
348+
};
349+
350+
// These IDs must \em not be renumbered or reordered without incrementing
351+
// VERSION_MAJOR.
352+
enum SpecialIdentifierID : uint8_t {
346353
/// Special IdentifierID value for the Builtin module.
347354
BUILTIN_MODULE_ID = 0,
348355
/// Special IdentifierID value for the current module.
349356
CURRENT_MODULE_ID,
350357
/// Special value for the module for imported Objective-C headers.
351358
OBJC_HEADER_MODULE_ID,
359+
/// Special value for the special subscript name
360+
SUBSCRIPT_ID,
352361

353-
/// The number of special modules. This value should never be encoded;
362+
/// The number of special Identifier IDs. This value should never be encoded;
354363
/// it should only be used to count the number of names above. As such, it
355364
/// is correct and necessary to add new values above this one.
356-
NUM_SPECIAL_MODULES
365+
NUM_SPECIAL_IDS
357366
};
358367

359368
// These IDs must \em not be renumbered or reordered without incrementing

lib/AST/ASTMangler.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,15 @@ void ASTMangler::appendDeclName(const ValueDecl *decl) {
540540
break;
541541
}
542542
} else if (decl->hasName()) {
543-
// TODO: Handle special names
544-
appendIdentifier(decl->getBaseName().getIdentifier().str());
543+
// FIXME: Should a mangled subscript name contain the string "subscript"?
544+
switch (decl->getBaseName().getKind()) {
545+
case DeclBaseName::Kind::Normal:
546+
appendIdentifier(decl->getBaseName().getIdentifier().str());
547+
break;
548+
case DeclBaseName::Kind::Subscript:
549+
appendIdentifier("subscript");
550+
break;
551+
}
545552
} else {
546553
assert(AllowNamelessEntities && "attempt to mangle unnamed decl");
547554
// Fall back to an unlikely name, so that we still generate a valid

lib/AST/Identifier.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "llvm/Support/ConvertUTF.h"
2121
using namespace swift;
2222

23+
void *DeclBaseName::SubscriptIdentifierData =
24+
&DeclBaseName::SubscriptIdentifierData;
2325

2426
raw_ostream &llvm::operator<<(raw_ostream &OS, Identifier I) {
2527
if (I.get() == nullptr)

lib/ClangImporter/ClangImporter.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2974,7 +2974,7 @@ void ClangImporter::Implementation::lookupValue(
29742974
auto &clangCtx = getClangASTContext();
29752975
auto clangTU = clangCtx.getTranslationUnitDecl();
29762976

2977-
for (auto entry : table.lookup(name.getBaseIdentifier().str(), clangTU)) {
2977+
for (auto entry : table.lookup(name.getBaseName(), clangTU)) {
29782978
// If the entry is not visible, skip it.
29792979
if (!isVisibleClangEntry(clangCtx, entry)) continue;
29802980

@@ -3070,7 +3070,7 @@ void ClangImporter::Implementation::lookupVisibleDecls(
30703070

30713071
// Look for namespace-scope entities with each base name.
30723072
for (auto baseName : baseNames) {
3073-
lookupValue(table, SwiftContext.getIdentifier(baseName), consumer);
3073+
lookupValue(table, baseName.toDeclBaseName(SwiftContext), consumer);
30743074
}
30753075
}
30763076

@@ -3079,9 +3079,8 @@ void ClangImporter::Implementation::lookupObjCMembers(
30793079
DeclName name,
30803080
VisibleDeclConsumer &consumer) {
30813081
auto &clangCtx = getClangASTContext();
3082-
auto baseName = name.getBaseIdentifier().str();
30833082

3084-
for (auto clangDecl : table.lookupObjCMembers(baseName)) {
3083+
for (auto clangDecl : table.lookupObjCMembers(name.getBaseName())) {
30853084
// If the entry is not visible, skip it.
30863085
if (!isVisibleClangEntry(clangCtx, clangDecl)) continue;
30873086

@@ -3121,7 +3120,7 @@ void ClangImporter::Implementation::lookupAllObjCMembers(
31213120

31223121
// Look for Objective-C members with each base name.
31233122
for (auto baseName : baseNames) {
3124-
lookupObjCMembers(table, SwiftContext.getIdentifier(baseName), consumer);
3123+
lookupObjCMembers(table, baseName.toDeclBaseName(SwiftContext), consumer);
31253124
}
31263125
}
31273126

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5410,7 +5410,7 @@ SwiftDeclConverter::getImplicitProperty(ImportedName importedName,
54105410
Impl.findLookupTable(*getClangSubmoduleForDecl(accessor));
54115411
assert(lookupTable && "No lookup table?");
54125412
bool foundAccessor = false;
5413-
for (auto entry : lookupTable->lookup(propertyName.str(),
5413+
for (auto entry : lookupTable->lookup(SerializedSwiftName(propertyName),
54145414
importedName.getEffectiveContext())) {
54155415
auto decl = entry.dyn_cast<clang::NamedDecl *>();
54165416
if (!decl)
@@ -6246,7 +6246,7 @@ SwiftDeclConverter::importSubscript(Decl *decl,
62466246
// Build the subscript declaration.
62476247
auto &C = Impl.SwiftContext;
62486248
auto bodyParams = getterThunk->getParameterList(1)->clone(C);
6249-
DeclName name(C, C.Id_subscript, {Identifier()});
6249+
DeclName name(C, DeclBaseName::createSubscript(), {Identifier()});
62506250
auto subscript = Impl.createDeclWithClangNode<SubscriptDecl>(
62516251
getter->getClangNode(), getOverridableAccessibility(dc), name,
62526252
decl->getLoc(), bodyParams, decl->getLoc(),

0 commit comments

Comments
 (0)