From 22cc6b08868fbea79f2ff7a45dfdcfbabf209686 Mon Sep 17 00:00:00 2001 From: John Hui Date: Wed, 2 Apr 2025 11:15:18 -0700 Subject: [PATCH] [NFC] promote getOperatorName() to a non-static function This function is useful in other parts of ClangImporter to ensure consistent name mangling. This patch also removes getPrivateOperatorName(), and converts uses of it to an overload of getOperatorName(). This change should eliminate many unnecessary constructions of temporary std::strings. --- .../ClangDerivedConformances.cpp | 4 +-- lib/ClangImporter/ClangImporter.cpp | 5 ++-- lib/ClangImporter/ImportName.cpp | 28 ++++++++++++------- lib/ClangImporter/ImporterImpl.h | 21 ++++++++------ 4 files changed, 35 insertions(+), 23 deletions(-) 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);