diff --git a/lib/ClangImporter/ClangDerivedConformances.cpp b/lib/ClangImporter/ClangDerivedConformances.cpp index aadc021d67f83..c54a3ecd1e995 100644 --- a/lib/ClangImporter/ClangDerivedConformances.cpp +++ b/lib/ClangImporter/ClangDerivedConformances.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "ClangDerivedConformances.h" +#include "ImporterImpl.h" #include "swift/AST/ConformanceLookup.h" #include "swift/AST/ParameterList.h" #include "swift/AST/PrettyStackTrace.h" @@ -33,8 +34,7 @@ lookupDirectWithoutExtensions(NominalTypeDecl *decl, Identifier id) { TinyPtrVector result; if (id.isOperator()) { - auto underlyingId = - ctx.getIdentifier(getPrivateOperatorName(std::string(id))); + auto underlyingId = getOperatorName(ctx, id); TinyPtrVector underlyingFuncs = evaluateOrDefault( ctx.evaluator, ClangRecordMemberLookup({decl, underlyingId}), {}); for (auto it : underlyingFuncs) { diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 07348ddd3b33e..ade853a2fa111 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -4748,9 +4748,8 @@ bool ClangImporter::Implementation::lookupValue(SwiftLookupTable &table, // If CXXInterop is enabled we need to check the modified operator name as // well if (SwiftContext.LangOpts.EnableCXXInterop) { - auto funcBaseName = - DeclBaseName(SwiftContext.getIdentifier(getPrivateOperatorName( - name.getBaseName().getIdentifier().str().str()))); + auto funcBaseName = DeclBaseName( + getOperatorName(SwiftContext, name.getBaseName().getIdentifier())); for (auto entry : table.lookupMemberOperators(funcBaseName)) { if (isVisibleClangEntry(entry)) { if (auto func = dyn_cast_or_null( diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp index 4c017ccfa36ca..ba072a640b6ad 100644 --- a/lib/ClangImporter/ImportName.cpp +++ b/lib/ClangImporter/ImportName.cpp @@ -62,19 +62,26 @@ using namespace importer; using clang::CompilerInstance; using clang::CompilerInvocation; -static const char *getOperatorName(clang::OverloadedOperatorKind Operator) { - switch (Operator) { +Identifier importer::getOperatorName(ASTContext &ctx, + clang::OverloadedOperatorKind op) { + switch (op) { case clang::OO_None: case clang::NUM_OVERLOADED_OPERATORS: - return nullptr; - + return Identifier{}; #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ case clang::OO_##Name: \ - return #Name; + return ctx.getIdentifier("__operator" #Name); #include "clang/Basic/OperatorKinds.def" } +} + +Identifier importer::getOperatorName(ASTContext &ctx, Identifier op) { +#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ + if (op.str() == Spelling) \ + return ctx.getIdentifier("__operator" #Name); +#include "clang/Basic/OperatorKinds.def" - llvm_unreachable("Invalid OverloadedOperatorKind!"); + return Identifier{}; } /// Determine whether the given Clang selector matches the given @@ -1960,10 +1967,11 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D, case clang::OverloadedOperatorKind::OO_GreaterEqual: case clang::OverloadedOperatorKind::OO_AmpAmp: case clang::OverloadedOperatorKind::OO_PipePipe: { - auto operatorName = isa(functionDecl) - ? "__operator" + std::string{getOperatorName(op)} - : clang::getOperatorSpelling(op); - baseName = swiftCtx.getIdentifier(operatorName).str(); + auto operatorName = + isa(functionDecl) + ? getOperatorName(swiftCtx, op) + : swiftCtx.getIdentifier(clang::getOperatorSpelling(op)); + baseName = operatorName.str(); isFunction = true; addDefaultArgNamesForClangFunction(functionDecl, argumentNames); if (auto cxxMethod = dyn_cast(functionDecl)) { diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index 46394d67ea129..458b426021af2 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -2047,14 +2047,19 @@ findAnonymousEnumForTypedef(const ASTContext &ctx, return std::nullopt; } -inline std::string getPrivateOperatorName(const std::string &OperatorToken) { -#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ - if (OperatorToken == Spelling) { \ - return "__operator" #Name; \ - }; -#include "clang/Basic/OperatorKinds.def" - return "None"; -} +/// Construct the imported Swift name for an imported Clang operator kind, +/// e.g., \c "__operatorPlus" for Clang::OO_Plus. +/// +/// Returns an empty identifier (internally, a nullptr) when \a op does not +/// represent an actual operator, i.e., OO_None or NUM_OVERLOADED_OPERATORS. +Identifier getOperatorName(ASTContext &ctx, clang::OverloadedOperatorKind op); + +/// Construct the imported Swift name corresponding to an operator identifier, +/// e.g., \c "__operatorPlus" for \c "+". +/// +/// Returns an empty identifier (internally, a nullptr) when \a op does not +/// correspond to an overloaded C++ operator. +Identifier getOperatorName(ASTContext &ctx, Identifier op); bool hasOwnedValueAttr(const clang::RecordDecl *decl); bool hasUnsafeAPIAttr(const clang::Decl *decl);