Skip to content

Commit fedb6a8

Browse files
committed
Clang importer: give importFullName a richer result type.
Capture the imported name, as well as some information about it, in the result of importFullName. Some of the clients need this information.
1 parent ec91244 commit fedb6a8

File tree

6 files changed

+85
-62
lines changed

6 files changed

+85
-62
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ void ClangImporter::Implementation::addEntryToLookupTable(
727727
if (!suppressDecl) {
728728
// If we have a name to import as, add this entry to the table.
729729
clang::DeclContext *effectiveContext;
730-
if (DeclName name = importFullName(named, nullptr, &effectiveContext)) {
730+
if (DeclName name = importFullName(named, &effectiveContext)) {
731731
table.addEntry(name, named, effectiveContext);
732732
}
733733
}
@@ -1573,7 +1573,7 @@ StringRef ClangImporter::Implementation::getEnumConstantNamePrefix(
15731573
// Account for the enum being imported using
15741574
// __attribute__((swift_private)). This is a little ad hoc, but it's a
15751575
// rare case anyway.
1576-
Identifier enumName = importFullName(decl).getBaseName();
1576+
Identifier enumName = importFullName(decl).Imported.getBaseName();
15771577
StringRef enumNameStr = enumName.str();
15781578
if (enumNameStr.startswith("__") && !checkPrefix.startswith("__"))
15791579
enumNameStr = enumNameStr.drop_front(2);
@@ -1596,14 +1596,15 @@ StringRef ClangImporter::Implementation::getEnumConstantNamePrefix(
15961596
return commonPrefix;
15971597
}
15981598

1599-
DeclName ClangImporter::Implementation::importFullName(
1600-
const clang::NamedDecl *D,
1601-
bool *hasCustomName,
1602-
clang::DeclContext **effectiveContext) {
1599+
auto ClangImporter::Implementation::importFullName(
1600+
const clang::NamedDecl *D,
1601+
clang::DeclContext **effectiveContext) -> ImportedName {
1602+
ImportedName result;
1603+
16031604
// Objective-C categories and extensions don't have names, despite
16041605
// being "named" declarations.
16051606
if (isa<clang::ObjCCategoryDecl>(D))
1606-
return { };
1607+
return result;
16071608

16081609
// Compute the effective context, if requested.
16091610
if (effectiveContext) {
@@ -1641,36 +1642,29 @@ DeclName ClangImporter::Implementation::importFullName(
16411642

16421643
// If we have a swift_name attribute, use that.
16431644
if (auto *nameAttr = D->getAttr<clang::SwiftNameAttr>()) {
1644-
if (hasCustomName)
1645-
*hasCustomName = true;
1646-
16471645
// If we have an Objective-C method that is being mapped to an
16481646
// initializer (e.g., a factory method whose name doesn't fit the
16491647
// convention for factory methods), make sure that it can be
16501648
// imported as an initializer.
16511649
if (auto method = dyn_cast<clang::ObjCMethodDecl>(D)) {
16521650
unsigned initPrefixLength;
1653-
CtorInitializerKind kind;
16541651
if (nameAttr->getName().startswith("init(") &&
1655-
!shouldImportAsInitializer(method, initPrefixLength, kind))
1652+
!shouldImportAsInitializer(method, initPrefixLength, result.InitKind))
16561653
return { };
16571654
}
16581655

1659-
return parseDeclName(SwiftContext, nameAttr->getName());
1656+
result.HasCustomName = true;
1657+
result.Imported = parseDeclName(SwiftContext, nameAttr->getName());
1658+
return result;
16601659
}
16611660

1662-
// We don't have a customized name.
1663-
if (hasCustomName)
1664-
*hasCustomName = false;
1665-
16661661
// For empty names, there is nothing to do.
1667-
if (D->getDeclName().isEmpty()) return { };
1662+
if (D->getDeclName().isEmpty()) return result;
16681663

16691664
/// Whether the result is a function name.
16701665
bool isFunction = false;
16711666
bool isInitializer = false;
16721667
unsigned initializerPrefixLen;
1673-
CtorInitializerKind initKind;
16741668
StringRef baseName;
16751669
SmallVector<StringRef, 4> argumentNames;
16761670
SmallString<16> selectorSplitScratch;
@@ -1682,7 +1676,7 @@ DeclName ClangImporter::Implementation::importFullName(
16821676
case clang::DeclarationName::CXXOperatorName:
16831677
case clang::DeclarationName::CXXUsingDirective:
16841678
// Handling these is part of C++ interoperability.
1685-
return { };
1679+
return result;
16861680

16871681
case clang::DeclarationName::Identifier:
16881682
// Map the identifier.
@@ -1694,7 +1688,7 @@ DeclName ClangImporter::Implementation::importFullName(
16941688
case clang::DeclarationName::ObjCZeroArgSelector: {
16951689
auto objcMethod = cast<clang::ObjCMethodDecl>(D);
16961690
isInitializer = shouldImportAsInitializer(objcMethod, initializerPrefixLen,
1697-
initKind);
1691+
result.InitKind);
16981692

16991693
// Map the Objective-C selector directly.
17001694
auto selector = D->getDeclName().getObjCSelector();
@@ -1902,27 +1896,32 @@ DeclName ClangImporter::Implementation::importFullName(
19021896

19031897
// We cannot import when the base name is not an identifier.
19041898
if (!Lexer::isIdentifier(baseName))
1905-
return { };
1899+
return result;
19061900

19071901
// Get the identifier for the base name.
19081902
Identifier baseNameId = SwiftContext.getIdentifier(baseName);
19091903

1910-
// If we have a non-function name, just return the base name.
1911-
if (!isFunction) return baseNameId;
1904+
// For functions, we need to form a complete name.
1905+
if (isFunction) {
1906+
// Convert the argument names.
1907+
SmallVector<Identifier, 4> argumentNameIds;
1908+
for (auto argName : argumentNames) {
1909+
if (argumentNames.empty() || !Lexer::isIdentifier(argName)) {
1910+
argumentNameIds.push_back(Identifier());
1911+
continue;
1912+
}
19121913

1913-
// Convert the argument names.
1914-
SmallVector<Identifier, 4> argumentNameIds;
1915-
for (auto argName : argumentNames) {
1916-
if (argumentNames.empty() || !Lexer::isIdentifier(argName)) {
1917-
argumentNameIds.push_back(Identifier());
1918-
continue;
1914+
argumentNameIds.push_back(SwiftContext.getIdentifier(argName));
19191915
}
19201916

1921-
argumentNameIds.push_back(SwiftContext.getIdentifier(argName));
1917+
// Build the result.
1918+
result.Imported = DeclName(SwiftContext, baseNameId, argumentNameIds);
1919+
} else {
1920+
// For non-functions, just use the base name.
1921+
result.Imported = baseNameId;
19221922
}
19231923

1924-
// Build the result.
1925-
return DeclName(SwiftContext, baseNameId, argumentNameIds);
1924+
return result;
19261925
}
19271926

19281927
Identifier

lib/ClangImporter/ImportDecl.cpp

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -970,14 +970,14 @@ makeBitFieldAccessors(ClangImporter::Implementation &Impl,
970970
static Identifier getClangDeclName(ClangImporter::Implementation &Impl,
971971
const clang::TagDecl *decl) {
972972
// Import the name of this declaration.
973-
Identifier name = Impl.importFullName(decl).getBaseName();
973+
Identifier name = Impl.importFullName(decl).Imported.getBaseName();
974974
if (!name.empty()) return name;
975975

976976
// If that didn't succeed, check whether this is an anonymous tag declaration
977977
// with a corresponding typedef-name declaration.
978978
if (decl->getDeclName().isEmpty()) {
979979
if (auto *typedefForAnon = decl->getTypedefNameForAnonDecl())
980-
return Impl.importFullName(typedefForAnon).getBaseName();
980+
return Impl.importFullName(typedefForAnon).Imported.getBaseName();
981981
}
982982

983983
if (!decl->isRecord())
@@ -1427,7 +1427,7 @@ namespace {
14271427
}
14281428

14291429
Decl *VisitTypedefNameDecl(const clang::TypedefNameDecl *Decl) {
1430-
auto Name = Impl.importFullName(Decl).getBaseName();
1430+
auto Name = Impl.importFullName(Decl).Imported.getBaseName();
14311431
if (Name.empty())
14321432
return nullptr;
14331433

@@ -1742,7 +1742,7 @@ namespace {
17421742
const clang::EnumDecl *clangEnum,
17431743
EnumDecl *theEnum) {
17441744
auto &context = Impl.SwiftContext;
1745-
auto name = Impl.importFullName(decl).getBaseName();
1745+
auto name = Impl.importFullName(decl).Imported.getBaseName();
17461746
if (name.empty())
17471747
return nullptr;
17481748

@@ -1795,7 +1795,7 @@ namespace {
17951795
Decl *importOptionConstant(const clang::EnumConstantDecl *decl,
17961796
const clang::EnumDecl *clangEnum,
17971797
NominalTypeDecl *theStruct) {
1798-
auto name = Impl.importFullName(decl).getBaseName();
1798+
auto name = Impl.importFullName(decl).Imported.getBaseName();
17991799
if (name.empty())
18001800
return nullptr;
18011801

@@ -1820,7 +1820,7 @@ namespace {
18201820
EnumElementDecl *original,
18211821
const clang::EnumDecl *clangEnum,
18221822
NominalTypeDecl *importedEnum) {
1823-
auto name = Impl.importFullName(alias).getBaseName();
1823+
auto name = Impl.importFullName(alias).Imported.getBaseName();
18241824
if (name.empty())
18251825
return nullptr;
18261826

@@ -2376,7 +2376,7 @@ namespace {
23762376
Decl *VisitEnumConstantDecl(const clang::EnumConstantDecl *decl) {
23772377
auto clangEnum = cast<clang::EnumDecl>(decl->getDeclContext());
23782378

2379-
auto name = Impl.importFullName(decl).getBaseName();
2379+
auto name = Impl.importFullName(decl).Imported.getBaseName();
23802380
if (name.empty())
23812381
return nullptr;
23822382

@@ -2471,7 +2471,7 @@ namespace {
24712471
return nullptr;
24722472
}
24732473
}
2474-
auto name = Impl.importFullName(decl).getBaseName();
2474+
auto name = Impl.importFullName(decl).Imported.getBaseName();
24752475
if (name.empty())
24762476
return nullptr;
24772477

@@ -2502,11 +2502,13 @@ namespace {
25022502
return nullptr;
25032503

25042504
// Determine the name of the function.
2505-
bool hasCustomName;
2506-
DeclName name = Impl.importFullName(decl, &hasCustomName);
2507-
if (!name)
2505+
auto importedName = Impl.importFullName(decl);
2506+
if (!importedName)
25082507
return nullptr;
25092508

2509+
DeclName name = importedName.Imported;
2510+
bool hasCustomName = importedName.HasCustomName;
2511+
25102512
// Import the function type. If we have parameters, make sure their names
25112513
// get into the resulting function type.
25122514
SmallVector<Pattern *, 4> bodyPatterns;
@@ -2577,7 +2579,7 @@ namespace {
25772579

25782580
Decl *VisitFieldDecl(const clang::FieldDecl *decl) {
25792581
// Fields are imported as variables.
2580-
auto name = Impl.importFullName(decl).getBaseName();
2582+
auto name = Impl.importFullName(decl).Imported.getBaseName();
25812583
if (name.empty())
25822584
return nullptr;
25832585

@@ -2623,7 +2625,7 @@ namespace {
26232625
return nullptr;
26242626

26252627
// Variables are imported as... variables.
2626-
auto name = Impl.importFullName(decl).getBaseName();
2628+
auto name = Impl.importFullName(decl).Imported.getBaseName();
26272629
if (name.empty())
26282630
return nullptr;
26292631

@@ -2797,7 +2799,9 @@ namespace {
27972799
switch (Impl.getFactoryAsInit(objcClass, decl)) {
27982800
case FactoryAsInitKind::AsInitializer:
27992801
if (decl->hasAttr<clang::SwiftNameAttr>()) {
2800-
initName = Impl.importFullName(decl, &hasCustomName);
2802+
auto importedName = Impl.importFullName(decl);
2803+
initName = importedName.Imported;
2804+
hasCustomName = importedName.HasCustomName;
28012805
break;
28022806
}
28032807
// FIXME: We probably should stop using this codepath. It won't ever
@@ -2908,7 +2912,9 @@ namespace {
29082912
bool hasCustomName;
29092913
if (auto *customNameAttr = decl->getAttr<clang::SwiftNameAttr>()) {
29102914
if (!customNameAttr->getName().startswith("init(")) {
2911-
name = Impl.importFullName(decl, &hasCustomName);
2915+
auto importedName = Impl.importFullName(decl);
2916+
name = importedName.Imported;
2917+
hasCustomName = importedName.HasCustomName;
29122918
}
29132919
}
29142920
if (!name) {
@@ -4781,7 +4787,7 @@ namespace {
47814787
}
47824788

47834789
Decl *VisitObjCProtocolDecl(const clang::ObjCProtocolDecl *decl) {
4784-
Identifier name = Impl.importFullName(decl).getBaseName();
4790+
Identifier name = Impl.importFullName(decl).Imported.getBaseName();
47854791
if (name.empty())
47864792
return nullptr;
47874793

@@ -4882,7 +4888,7 @@ namespace {
48824888
}
48834889

48844890
Decl *VisitObjCInterfaceDecl(const clang::ObjCInterfaceDecl *decl) {
4885-
auto name = Impl.importFullName(decl).getBaseName();
4891+
auto name = Impl.importFullName(decl).Imported.getBaseName();
48864892
if (name.empty())
48874893
return nullptr;
48884894

@@ -5098,7 +5104,7 @@ namespace {
50985104

50995105
Decl *VisitObjCPropertyDecl(const clang::ObjCPropertyDecl *decl,
51005106
DeclContext *dc) {
5101-
auto name = Impl.importFullName(decl).getBaseName();
5107+
auto name = Impl.importFullName(decl).Imported.getBaseName();
51025108
if (name.empty())
51035109
return nullptr;
51045110

@@ -6147,6 +6153,6 @@ ClangImporter::Implementation::getSpecialTypedefKind(clang::TypedefNameDecl *dec
61476153

61486154
Identifier
61496155
ClangImporter::getEnumConstantName(const clang::EnumConstantDecl *enumConstant){
6150-
return Impl.importFullName(enumConstant).getBaseName();
6156+
return Impl.importFullName(enumConstant).Imported.getBaseName();
61516157
}
61526158

lib/ClangImporter/ImportType.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,7 @@ Type ClangImporter::Implementation::importFunctionType(
14251425
}
14261426

14271427
// Figure out the name for this parameter.
1428-
Identifier bodyName = importFullName(param).getBaseName();
1428+
Identifier bodyName = importFullName(param).Imported.getBaseName();
14291429

14301430
// Retrieve the argument name.
14311431
Identifier name;
@@ -2427,7 +2427,7 @@ Type ClangImporter::Implementation::importMethodType(
24272427
}
24282428

24292429
// Figure out the name for this parameter.
2430-
Identifier bodyName = importFullName(param).getBaseName();
2430+
Identifier bodyName = importFullName(param).Imported.getBaseName();
24312431

24322432
// Figure out the name for this argument, which comes from the method name.
24332433
Identifier name;

lib/ClangImporter/ImporterImpl.h

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -744,23 +744,39 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
744744
/// \brief Converts the given Swift identifier for Clang.
745745
clang::DeclarationName exportName(Identifier name);
746746

747+
/// Describes a name that was imported from Clang.
748+
struct ImportedName {
749+
/// The imported name.
750+
DeclName Imported;
751+
752+
/// Whether this name was explicitly specified via a Clang
753+
/// swift_name attribute.
754+
bool HasCustomName = false;
755+
756+
/// For an initializer, the kind of initializer to import.
757+
CtorInitializerKind InitKind;
758+
759+
/// Produce just the imported name, for clients that don't care
760+
/// about the details.
761+
operator DeclName() const { return Imported; }
762+
763+
/// Whether any name was imported.
764+
explicit operator bool() const { return static_cast<bool>(Imported); }
765+
};
766+
747767
/// Imports the full name of the given Clang declaration into Swift.
748768
///
749769
/// Note that this may result in a name very different from the Clang name,
750770
/// so it should not be used when referencing Clang symbols.
751771
///
752772
/// \param D The Clang declaration whose name should be imported.
753773
///
754-
/// \param hasCustomName If non-null, will be set to indicate whether the
755-
/// name was provided directly via a C swift_name attribute.
756-
///
757774
/// \param effectiveContext If non-null, will be set to the effective
758775
/// Clang declaration context in which the declaration will be imported.
759776
/// This can differ from D's redeclaration context when the Clang importer
760777
/// introduces nesting, e.g., for enumerators within an NS_ENUM.
761-
DeclName importFullName(const clang::NamedDecl *D,
762-
bool *hasCustomName = nullptr,
763-
clang::DeclContext **effectiveContext = nullptr);
778+
ImportedName importFullName(const clang::NamedDecl *D,
779+
clang::DeclContext **effectiveContext = nullptr);
764780

765781
/// \brief Import the given Clang identifier into Swift.
766782
///

test/IDE/Inputs/swift_name_objc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ SWIFT_NAME(SomeClass)
2121
+ (instancetype)someClassWithDouble:(double)d;
2222
+ (instancetype)someClassWithTry:(BOOL)shouldTry;
2323
+ (NSObject *)buildWithObject:(NSObject *)object SWIFT_NAME(init(object:));
24-
24+
+ (instancetype)buildWithUnsignedChar:(unsigned char)uint8 SWIFT_NAME(init(uint8:));
2525
@property (readonly,nonatomic) float floatProperty;
2626
@property (readwrite,nonatomic) double doubleProperty;
2727
@end

test/IDE/dump_swift_lookup_tables_objc.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// CHECK-NEXT: doubleProperty --> doubleProperty{{$}}
1515
// CHECK-NEXT: extensionMethodWithX --> extensionMethodWithX(_:y:)
1616
// CHECK-NEXT: floatProperty --> floatProperty{{$}}
17-
// CHECK-NEXT: init --> init(float:), init(withDefault:), init(double:), init(withTry:){{$}}
17+
// CHECK-NEXT: init --> init(float:), init(withDefault:), init(double:), init(withTry:), init(uint8:){{$}}
1818
// CHECK-NEXT: instanceMethodWithX --> instanceMethodWithX(_:y:z:)
1919
// CHECK-NEXT: protoInstanceMethodWithX --> protoInstanceMethodWithX(_:y:)
2020
// CHECK-NEXT: setAccessibilityFloat --> setAccessibilityFloat(_:)
@@ -46,6 +46,8 @@
4646
// CHECK-NEXT: SNSomeClass: +[SNSomeClass someClassWithDouble:]
4747
// CHECK-NEXT: init(float:):
4848
// CHECK-NEXT: SNSomeClass: -[SNSomeClass initWithFloat:]
49+
// CHECK-NEXT: init(uint8:):
50+
// CHECK-NEXT: SNSomeClass: +[SNSomeClass buildWithUnsignedChar:]
4951
// CHECK-NEXT: init(withDefault:):
5052
// CHECK-NEXT: SNSomeClass: -[SNSomeClass initWithDefault]
5153
// CHECK-NEXT: init(withTry:):

0 commit comments

Comments
 (0)