Skip to content

Commit 7e30d54

Browse files
committed
[Clang importer] Map imported names via the user-facing name
Swift names provided via C attributes or API notes can be parsed as special names, such as `init` or `subscript`. However, doing so would cause the Clang importer to crash, because it assumes that these names are always identifiers. In these places, we actually want to treat them as identifiers, where special names are mapped back to their keywords. Introduce a function to do that, and use it consistently.
1 parent 35eb5cb commit 7e30d54

File tree

9 files changed

+64
-33
lines changed

9 files changed

+64
-33
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2989,7 +2989,7 @@ class DarwinLegacyFilterDeclConsumer : public swift::VisibleDeclConsumer {
29892989
if (clangModule->Name == "MacTypes") {
29902990
if (!VD->hasName() || VD->getBaseName().isSpecial())
29912991
return true;
2992-
return llvm::StringSwitch<bool>(VD->getBaseIdentifier().str())
2992+
return llvm::StringSwitch<bool>(VD->getBaseName().userFacingName())
29932993
.Cases("OSErr", "OSStatus", "OptionBits", false)
29942994
.Cases("FourCharCode", "OSType", false)
29952995
.Case("Boolean", false)
@@ -4981,7 +4981,7 @@ const clang::CXXMethodDecl *getCalledBaseCxxMethod(FuncDecl *baseMember) {
49814981
if (auto *v = ce->getCalledValue()) {
49824982
if (v->getModuleContext() ==
49834983
baseMember->getASTContext().TheBuiltinModule &&
4984-
v->getBaseIdentifier().is("reinterpretCast")) {
4984+
v->getBaseName().userFacingName() == "reinterpretCast") {
49854985
returnExpr = ce->getArgs()->get(0).getExpr();
49864986
}
49874987
}
@@ -6914,7 +6914,7 @@ bool ClangImporter::isUnsafeCXXMethod(const FuncDecl *func) {
69146914
return false;
69156915
if (!func->hasName())
69166916
return false;
6917-
auto id = func->getBaseIdentifier().str();
6917+
auto id = func->getBaseName().userFacingName();
69186918
return id.startswith("__") && id.endswith("Unsafe");
69196919
}
69206920

lib/ClangImporter/DWARFImporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ void ClangImporter::Implementation::lookupValueDWARF(
151151
return;
152152

153153
SmallVector<clang::Decl *, 4> decls;
154-
DWARFImporter->lookupValue(name.getBaseIdentifier().str(), llvm::None,
154+
DWARFImporter->lookupValue(name.getBaseName().userFacingName(), llvm::None,
155155
inModule.str(), decls);
156156
for (auto *clangDecl : decls) {
157157
auto *namedDecl = dyn_cast<clang::NamedDecl>(clangDecl);

lib/ClangImporter/ImportDecl.cpp

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ applyPropertyOwnership(VarDecl *prop,
813813
static bool isPrintLikeMethod(DeclName name, const DeclContext *dc) {
814814
if (!name || name.isSpecial() || name.isSimpleName())
815815
return false;
816-
if (name.getBaseIdentifier().str() != "print")
816+
if (name.getBaseName().userFacingName() != "print")
817817
return false;
818818
if (!dc->isTypeContext())
819819
return false;
@@ -1188,7 +1188,7 @@ namespace {
11881188

11891189
auto *enumDecl = Impl.createDeclWithClangNode<EnumDecl>(
11901190
decl, AccessLevel::Public, Impl.importSourceLoc(decl->getBeginLoc()),
1191-
importedName.getDeclName().getBaseIdentifier(),
1191+
importedName.getBaseIdentifier(Impl.SwiftContext),
11921192
Impl.importSourceLoc(decl->getLocation()), llvm::None, nullptr, dc);
11931193
// TODO: we only have this for the sid effect of calling
11941194
// "FirstDeclAndLazyMembers.setInt(true)".
@@ -1222,7 +1222,7 @@ namespace {
12221222
ImportedName importedName;
12231223
llvm::Optional<ImportedName> correctSwiftName;
12241224
std::tie(importedName, correctSwiftName) = importFullName(decl);
1225-
auto name = importedName.getDeclName().getBaseIdentifier();
1225+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
12261226
if (name.empty())
12271227
return nullptr;
12281228

@@ -1365,7 +1365,7 @@ namespace {
13651365
ImportedName importedName;
13661366
llvm::Optional<ImportedName> correctSwiftName;
13671367
std::tie(importedName, correctSwiftName) = importFullName(Decl);
1368-
auto Name = importedName.getDeclName().getBaseIdentifier();
1368+
auto Name = importedName.getBaseIdentifier(Impl.SwiftContext);
13691369
if (Name.empty())
13701370
return nullptr;
13711371

@@ -1599,7 +1599,7 @@ namespace {
15991599
if (!dc)
16001600
return nullptr;
16011601

1602-
auto name = importedName.getDeclName().getBaseIdentifier();
1602+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
16031603

16041604
// Create the enum declaration and record it.
16051605
ImportDiagnosticAdder addDiag(Impl, decl, decl->getLocation());
@@ -1959,7 +1959,7 @@ namespace {
19591959
if (unimported != constant && enumeratorDecl) {
19601960
ImportedName importedName =
19611961
Impl.importFullName(constant, getActiveSwiftVersion());
1962-
Identifier name = importedName.getDeclName().getBaseIdentifier();
1962+
Identifier name = importedName.getBaseIdentifier(Impl.SwiftContext);
19631963
if (name.empty()) {
19641964
// Clear the existing declaration so we don't try to process it
19651965
// twice later.
@@ -2167,7 +2167,7 @@ namespace {
21672167
}
21682168

21692169
// Create the struct declaration and record it.
2170-
auto name = importedName.getDeclName().getBaseIdentifier();
2170+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
21712171
NominalTypeDecl *result = nullptr;
21722172
// Try to find an already-imported struct. This case happens any time
21732173
// there are nested structs. The "Parent" struct will import the "Child"
@@ -3016,7 +3016,7 @@ namespace {
30163016
std::tie(importedName, correctSwiftName) = importFullName(decl);
30173017
if (!importedName) return nullptr;
30183018

3019-
auto name = importedName.getDeclName().getBaseIdentifier();
3019+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
30203020
if (name.empty())
30213021
return nullptr;
30223022

@@ -3087,7 +3087,7 @@ namespace {
30873087
std::tie(importedName, correctSwiftName) = importFullName(decl);
30883088
if (!importedName) return nullptr;
30893089

3090-
auto name = importedName.getDeclName().getBaseIdentifier();
3090+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
30913091

30923092
auto dc =
30933093
Impl.importDeclContextOf(decl, importedName.getEffectiveContext());
@@ -3570,8 +3570,7 @@ namespace {
35703570

35713571
Identifier bodyName =
35723572
Impl.importFullName(param, Impl.CurrentVersion)
3573-
.getDeclName()
3574-
.getBaseIdentifier();
3573+
.getBaseIdentifier(Impl.SwiftContext);
35753574
auto paramInfo = Impl.createDeclWithClangNode<ParamDecl>(
35763575
param, AccessLevel::Private, SourceLoc(), SourceLoc(),
35773576
Identifier(), Impl.importSourceLoc(param->getLocation()),
@@ -3809,7 +3808,7 @@ namespace {
38093808
return nullptr;
38103809
}
38113810

3812-
auto name = importedName.getDeclName().getBaseIdentifier();
3811+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
38133812

38143813
auto dc =
38153814
Impl.importDeclContextOf(decl, importedName.getEffectiveContext());
@@ -3897,7 +3896,7 @@ namespace {
38973896
std::tie(importedName, correctSwiftName) = importFullName(decl);
38983897
if (!importedName) return nullptr;
38993898

3900-
auto name = importedName.getDeclName().getBaseIdentifier();
3899+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
39013900
auto dc =
39023901
Impl.importDeclContextOf(decl, importedName.getEffectiveContext());
39033902
if (!dc)
@@ -3976,7 +3975,7 @@ namespace {
39763975
Decl *VisitClassTemplateDecl(const clang::ClassTemplateDecl *decl) {
39773976
ImportedName importedName;
39783977
std::tie(importedName, std::ignore) = importFullName(decl);
3979-
auto name = importedName.getDeclName().getBaseIdentifier();
3978+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
39803979
if (name.empty())
39813980
return nullptr;
39823981

@@ -4042,7 +4041,7 @@ namespace {
40424041
// Don't import something that doesn't have a name.
40434042
if (importedName.getDeclName().isSpecial())
40444043
return nullptr;
4045-
auto Name = importedName.getDeclName().getBaseIdentifier();
4044+
auto Name = importedName.getBaseIdentifier(Impl.SwiftContext);
40464045
if (Name.empty())
40474046
return nullptr;
40484047

@@ -4291,7 +4290,7 @@ namespace {
42914290

42924291
auto type = importedType.getType();
42934292
const auto access = getOverridableAccessLevel(dc);
4294-
auto ident = name.getDeclName().getBaseIdentifier();
4293+
auto ident = name.getBaseIdentifier(Impl.SwiftContext);
42954294
auto propDecl = Impl.createDeclWithClangNode<VarDecl>(decl, access,
42964295
/*IsStatic*/decl->isClassMethod(), VarDecl::Introducer::Var,
42974296
Impl.importSourceLoc(decl->getLocation()), ident, dc);
@@ -4987,7 +4986,7 @@ namespace {
49874986
return importCompatibilityTypeAlias(decl, importedName,
49884987
*correctSwiftName);
49894988

4990-
Identifier name = importedName.getDeclName().getBaseIdentifier();
4989+
Identifier name = importedName.getBaseIdentifier(Impl.SwiftContext);
49914990
bool hasKnownSwiftName = importedName.hasCustomName();
49924991

49934992
if (!decl->hasDefinition()) {
@@ -5150,7 +5149,7 @@ namespace {
51505149
return importCompatibilityTypeAlias(decl, importedName,
51515150
*correctSwiftName);
51525151

5153-
auto name = importedName.getDeclName().getBaseIdentifier();
5152+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
51545153
bool hasKnownSwiftName = importedName.hasCustomName();
51555154

51565155
if (!decl->hasDefinition()) {
@@ -5358,7 +5357,7 @@ namespace {
53585357
ImportedName importedName;
53595358
llvm::Optional<ImportedName> correctSwiftName;
53605359
std::tie(importedName, correctSwiftName) = importFullName(decl);
5361-
auto name = importedName.getDeclName().getBaseIdentifier();
5360+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
53625361
if (name.empty())
53635362
return nullptr;
53645363

@@ -5502,7 +5501,7 @@ namespace {
55025501

55035502
ImportedName importedName;
55045503
std::tie(importedName, std::ignore) = importFullName(decl);
5505-
auto name = importedName.getDeclName().getBaseIdentifier();
5504+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
55065505

55075506
if (name.empty()) return nullptr;
55085507
Decl *importedDecl =
@@ -5742,7 +5741,7 @@ Decl *SwiftDeclConverter::importCompatibilityTypeAlias(
57425741
// Create the type alias.
57435742
auto alias = Impl.createDeclWithClangNode<TypeAliasDecl>(
57445743
decl, AccessLevel::Public, Impl.importSourceLoc(decl->getBeginLoc()),
5745-
SourceLoc(), compatibilityName.getDeclName().getBaseIdentifier(),
5744+
SourceLoc(), compatibilityName.getBaseIdentifier(Impl.SwiftContext),
57465745
Impl.importSourceLoc(decl->getLocation()), /*generic params*/nullptr, dc);
57475746

57485747
auto *GTD = dyn_cast<GenericTypeDecl>(typeDecl);
@@ -5979,7 +5978,7 @@ Decl *SwiftDeclConverter::importEnumCase(const clang::EnumConstantDecl *decl,
59795978
ImportedName importedName;
59805979
llvm::Optional<ImportedName> correctSwiftName;
59815980
std::tie(importedName, correctSwiftName) = importFullName(decl);
5982-
auto name = importedName.getDeclName().getBaseIdentifier();
5981+
auto name = importedName.getBaseIdentifier(Impl.SwiftContext);
59835982
if (name.empty())
59845983
return nullptr;
59855984

@@ -6036,7 +6035,7 @@ SwiftDeclConverter::importOptionConstant(const clang::EnumConstantDecl *decl,
60366035
ImportedName nameInfo;
60376036
llvm::Optional<ImportedName> correctSwiftName;
60386037
std::tie(nameInfo, correctSwiftName) = importFullName(decl);
6039-
Identifier name = nameInfo.getDeclName().getBaseIdentifier();
6038+
Identifier name = nameInfo.getBaseIdentifier(Impl.SwiftContext);
60406039
if (name.empty())
60416040
return nullptr;
60426041

@@ -6260,7 +6259,7 @@ SwiftDeclConverter::getImplicitProperty(ImportedName importedName,
62606259
}
62616260

62626261
// Find the other accessor, if it exists.
6263-
auto propertyName = importedName.getDeclName().getBaseIdentifier();
6262+
auto propertyName = importedName.getBaseIdentifier(Impl.SwiftContext);
62646263
auto lookupTable =
62656264
Impl.findLookupTable(*getClangSubmoduleForDecl(accessor));
62666265
assert(lookupTable && "No lookup table?");
@@ -9448,8 +9447,7 @@ ClangImporter::Implementation::getSpecialTypedefKind(
94489447
Identifier
94499448
ClangImporter::getEnumConstantName(const clang::EnumConstantDecl *enumConstant){
94509449
return Impl.importFullName(enumConstant, Impl.CurrentVersion)
9451-
.getDeclName()
9452-
.getBaseIdentifier();
9450+
.getBaseIdentifier(Impl.SwiftContext);
94539451
}
94549452

94559453
// See swift/Basic/Statistic.h for declaration: this enables tracing

lib/ClangImporter/ImportName.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,6 +2393,14 @@ bool ClangImporter::shouldIgnoreMacro(StringRef Name,
23932393
return ::shouldIgnoreMacro(Name, Macro, Impl.getClangPreprocessor());
23942394
}
23952395

2396+
Identifier ImportedName::getBaseIdentifier(ASTContext &ctx) const {
2397+
auto baseName = declName.getBaseName();
2398+
if (!baseName.isSpecial())
2399+
return baseName.getIdentifier();
2400+
2401+
return ctx.getIdentifier(baseName.userFacingName());
2402+
}
2403+
23962404
Identifier
23972405
NameImporter::importMacroName(const clang::IdentifierInfo *clangIdentifier,
23982406
const clang::MacroInfo *macro) {

lib/ClangImporter/ImportName.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ class ImportedName {
304304
return llvm::None;
305305
}
306306

307+
/// Retrieve the base name as an identifier, including mapping special
308+
/// names like 'init' or 'subscript' to identifiers.
309+
Identifier getBaseIdentifier(ASTContext &ctx) const;
310+
307311
/// Whether this name was explicitly specified via a Clang
308312
/// swift_name attribute.
309313
bool hasCustomName() const { return info.hasCustomName; }

lib/ClangImporter/ImportType.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,8 +2468,7 @@ static ParamDecl *getParameterInfo(ClangImporter::Implementation *impl,
24682468
const bool isParamTypeImplicitlyUnwrapped) {
24692469
// Figure out the name for this parameter.
24702470
Identifier bodyName = impl->importFullName(param, impl->CurrentVersion)
2471-
.getDeclName()
2472-
.getBaseIdentifier();
2471+
.getBaseIdentifier(impl->SwiftContext);
24732472

24742473
// It doesn't actually matter which DeclContext we use, so just use the
24752474
// imported header unit.
@@ -3284,7 +3283,7 @@ ImportedType ClangImporter::Implementation::importAccessorParamsAndReturnType(
32843283
} else {
32853284
const clang::ParmVarDecl *param = clangDecl->parameters().front();
32863285
ImportedName fullBodyName = importFullName(param, CurrentVersion);
3287-
Identifier bodyName = fullBodyName.getDeclName().getBaseIdentifier();
3286+
Identifier bodyName = fullBodyName.getBaseIdentifier(SwiftContext);
32883287
SourceLoc nameLoc = importSourceLoc(param->getLocation());
32893288
Identifier argLabel = functionName.getDeclName().getArgumentNames().front();
32903289
auto paramInfo

test/ClangImporter/enum-renames.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -verify
2+
3+
import enums_using_attributes
4+
5+
func testEvent(event: Event) {
6+
if event == .`init` { print("Initialize") }
7+
if event == .reset { print("Reset") }
8+
}

test/Inputs/clang-importer-sdk/usr/include/enums_using_attributes.apinotes

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,11 @@ Tags:
44
EnumKind: none
55
- Name: UnknownOptionsThanksToAPINotes
66
EnumKind: none
7+
- Name: SystemEvent
8+
SwiftName: Event
9+
EnumExtensibility: open
10+
Enumerators:
11+
- Name: kEventInit
12+
SwiftName: init
13+
- Name: kEventReset
14+
SwiftName: reset

test/Inputs/clang-importer-sdk/usr/include/enums_using_attributes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,9 @@ typedef enum {
2626
typedef enum EnumByBoth {
2727
EnumByBothX
2828
} EnumByBoth;
29+
30+
31+
typedef enum {
32+
kEventInit,
33+
kEventReset
34+
} SystemEvent;

0 commit comments

Comments
 (0)