Skip to content

Commit f8c2692

Browse files
committed
Introduce special decl names
Special DeclNames represent names that do not have an identifier in the surface language. This implies serializing the information about whether a name is special together with its identifier (if it is not special) in both the module file and the swift lookup table.
1 parent 2e512cb commit f8c2692

29 files changed

+424
-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)