Skip to content

Commit ba507ab

Browse files
authored
Merge pull request #85203 from DougGregor/clang-decl-asmname
2 parents a426679 + f1ad1be commit ba507ab

File tree

95 files changed

+904
-756
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+904
-756
lines changed

include/swift/AST/Attr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3126,8 +3126,8 @@ class ExternAttr : public DeclAttribute {
31263126
}
31273127

31283128
/// Returns the C name of the given declaration.
3129-
/// \p forDecl is the func decl that the attribute belongs to.
3130-
StringRef getCName(const FuncDecl *forDecl) const;
3129+
/// \p forDecl is the decl that the attribute belongs to.
3130+
StringRef getCName(const ValueDecl *forDecl) const;
31313131

31323132
/// Find an ExternAttr with the given kind in the given DeclAttributes.
31333133
static const ExternAttr *find(const DeclAttributes &attrs, ExternKind kind);

include/swift/AST/DiagnosticsIRGen.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,9 @@ NOTE(maybe_missing_parameter, none,
117117
"%select{constraint|parameter}0",
118118
(bool, const clang::NamedDecl *))
119119

120+
ERROR(ir_function_redefinition_external,none,
121+
"multiple definitions of symbol '%0'",
122+
(StringRef))
123+
120124
#define UNDEFINE_DIAGNOSTIC_MACROS
121125
#include "DefineDiagnosticMacros.h"

include/swift/SIL/SILDeclRef.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ struct SILDeclRef {
335335

336336
/// If the symbol has a specific name for use at the LLVM IR level,
337337
/// produce that name. This may be different than the mangled name in SIL.
338-
std::optional<StringRef> getAsmName() const;
338+
std::optional<std::string> getAsmName() const;
339339

340340
/// True if the SILDeclRef references a function.
341341
bool isFunc() const {

include/swift/SIL/SILFunction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1430,7 +1430,7 @@ class SILFunction
14301430

14311431
/// Return custom assembler name, otherwise empty.
14321432
StringRef asmName() const { return AsmName; }
1433-
void setAsmName(StringRef value) { AsmName = value; }
1433+
void setAsmName(StringRef value);
14341434

14351435
/// Return custom section name if @section was used, otherwise empty
14361436
StringRef section() const { return Section; }

include/swift/SIL/SILGlobalVariable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ class SILGlobalVariable
160160

161161
/// Return custom assembler name, otherwise empty.
162162
StringRef asmName() const { return AsmName; }
163-
void setAsmName(StringRef value) { AsmName = value; }
163+
void setAsmName(StringRef value);
164164

165165
/// Return custom section name if @section was used, otherwise empty
166166
StringRef section() const { return Section; }

include/swift/SIL/SILModule.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ class SILModule {
235235
llvm::StringMap<SILFunction *> FunctionTable;
236236
llvm::StringMap<SILFunction *> ZombieFunctionTable;
237237

238+
/// Lookup table for SIL functions by their asmnames, for those that
239+
/// have them.
240+
llvm::StringMap<SILFunction *> FunctionByAsmNameTable;
241+
238242
/// The list of SILFunctions in the module.
239243
FunctionListType functions;
240244

@@ -310,6 +314,9 @@ class SILModule {
310314
/// Lookup table for SIL Global Variables.
311315
llvm::StringMap<SILGlobalVariable *> GlobalVariableMap;
312316

317+
/// Lookup table for SIL Global Variables, indexed by their asmnames.
318+
llvm::StringMap<SILGlobalVariable *> GlobalVariableByAsmNameMap;
319+
313320
/// The list of SILGlobalVariables in the module.
314321
GlobalListType silGlobals;
315322

@@ -822,14 +829,20 @@ class SILModule {
822829
/// Look for a global variable by name.
823830
///
824831
/// \return null if this module has no such global variable
825-
SILGlobalVariable *lookUpGlobalVariable(StringRef name) const {
832+
SILGlobalVariable *lookUpGlobalVariable(StringRef name,
833+
bool byAsmName = false) const {
834+
if (byAsmName)
835+
return GlobalVariableByAsmNameMap.lookup(name);
836+
826837
return GlobalVariableMap.lookup(name);
827838
}
828839

829840
/// Look for a function by name.
830841
///
831842
/// \return null if this module has no such function
832-
SILFunction *lookUpFunction(StringRef name) const {
843+
SILFunction *lookUpFunction(StringRef name, bool byAsmName = false) const {
844+
if (byAsmName)
845+
return FunctionByAsmNameTable.lookup(name);
833846
return FunctionTable.lookup(name);
834847
}
835848

include/swift/Serialization/SerializedSILLoader.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@ class SerializedSILLoader {
6262

6363
SILFunction *lookupSILFunction(SILFunction *Callee, bool onlyUpdateLinkage);
6464
SILFunction *lookupSILFunction(StringRef Name,
65-
std::optional<SILLinkage> linkage);
66-
SILGlobalVariable *lookupSILGlobalVariable(StringRef Name);
65+
std::optional<SILLinkage> linkage,
66+
bool byAsmName = false);
67+
SILGlobalVariable *lookupSILGlobalVariable(StringRef Name,
68+
bool byAsmName = false);
6769
bool hasSILFunction(StringRef Name,
6870
std::optional<SILLinkage> linkage = std::nullopt);
6971
SILVTable *lookupVTable(const ClassDecl *C);

lib/AST/ASTMangler.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,19 @@ void ASTMangler::beginManglingWithAutoDiffOriginalFunction(
669669
beginManglingClangDecl(typedefType->getDecl());
670670
return;
671671
}
672+
673+
if (auto *EA = ExternAttr::find(afd->getAttrs(), ExternKind::C)) {
674+
beginManglingWithoutPrefix();
675+
appendOperator(EA->getCName(afd));
676+
return;
677+
}
678+
679+
if (afd->getAttrs().hasAttribute<CDeclAttr>()) {
680+
beginManglingWithoutPrefix();
681+
appendOperator(afd->getCDeclName());
682+
return;
683+
}
684+
672685
beginMangling();
673686
if (auto *cd = dyn_cast<ConstructorDecl>(afd))
674687
appendConstructorEntity(cd, /*isAllocating*/ !cd->isConvenienceInit());

lib/AST/Attr.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3273,11 +3273,11 @@ bool MacroRoleAttr::hasNameKind(MacroIntroducedDeclNameKind kind) const {
32733273
}) != getNames().end();
32743274
}
32753275

3276-
StringRef ExternAttr::getCName(const FuncDecl *D) const {
3276+
StringRef ExternAttr::getCName(const ValueDecl *D) const {
32773277
if (auto cName = this->Name)
32783278
return cName.value();
32793279
// If no name was specified, fall back on the Swift base name without mangling.
3280-
// Base name is always available and non-empty for FuncDecl.
3280+
// Base name is always available and non-empty for functions and variables.
32813281
return D->getBaseIdentifier().str();
32823282
}
32833283

lib/ClangImporter/SwiftDeclSynthesizer.cpp

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,34 +2066,91 @@ clang::CXXMethodDecl *SwiftDeclSynthesizer::synthesizeCXXForwardingMethod(
20662066

20672067
// Create a new method in the derived class that calls the base method.
20682068
clang::DeclarationName name = method->getNameInfo().getName();
2069+
std::string newName;
2070+
llvm::raw_string_ostream os(newName);
2071+
bool useExistingName = false;
20692072
if (name.isIdentifier()) {
2070-
std::string newName;
2071-
llvm::raw_string_ostream os(newName);
20722073
os << (forwardingMethodKind == ForwardingMethodKind::Virtual
20732074
? "__synthesizedVirtualCall_"
20742075
: "__synthesizedBaseCall_")
20752076
<< name.getAsIdentifierInfo()->getName();
2076-
name = clang::DeclarationName(
2077-
&ImporterImpl.getClangPreprocessor().getIdentifierTable().get(
2078-
os.str()));
2079-
} else if (name.getCXXOverloadedOperator() == clang::OO_Subscript) {
2080-
name = clang::DeclarationName(
2081-
&ImporterImpl.getClangPreprocessor().getIdentifierTable().get(
2082-
(forwardingMethodKind == ForwardingMethodKind::Virtual
2077+
} else {
2078+
switch (auto op = name.getCXXOverloadedOperator()) {
2079+
case clang::OO_Subscript:
2080+
os << (forwardingMethodKind == ForwardingMethodKind::Virtual
20832081
? "__synthesizedVirtualCall_operatorSubscript"
2084-
: "__synthesizedBaseCall_operatorSubscript")));
2085-
} else if (name.getCXXOverloadedOperator() == clang::OO_Star) {
2086-
name = clang::DeclarationName(
2087-
&ImporterImpl.getClangPreprocessor().getIdentifierTable().get(
2088-
(forwardingMethodKind == ForwardingMethodKind::Virtual
2082+
: "__synthesizedBaseCall_operatorSubscript");
2083+
if (forceConstQualifier)
2084+
os << "C";
2085+
break;
2086+
2087+
case clang::OO_Star:
2088+
os << (forwardingMethodKind == ForwardingMethodKind::Virtual
20892089
? "__synthesizedVirtualCall_operatorStar"
2090-
: "__synthesizedBaseCall_operatorStar")));
2091-
} else if (name.getCXXOverloadedOperator() == clang::OO_Call) {
2092-
assert(forwardingMethodKind != ForwardingMethodKind::Virtual);
2090+
: "__synthesizedBaseCall_operatorStar");
2091+
if (forceConstQualifier)
2092+
os << "C";
2093+
break;
2094+
2095+
case clang::OO_Call:
2096+
assert(forwardingMethodKind != ForwardingMethodKind::Virtual);
2097+
os << "__synthesizedBaseCall_operatorCall";
2098+
if (forceConstQualifier)
2099+
os << "C";
2100+
break;
2101+
2102+
case clang::OO_Plus:
2103+
case clang::OO_Minus:
2104+
case clang::OO_Slash:
2105+
case clang::OO_PlusEqual:
2106+
case clang::OO_MinusEqual:
2107+
case clang::OO_StarEqual:
2108+
case clang::OO_SlashEqual:
2109+
case clang::OO_Percent:
2110+
case clang::OO_Caret:
2111+
case clang::OO_Amp:
2112+
case clang::OO_Pipe:
2113+
case clang::OO_Tilde:
2114+
case clang::OO_Exclaim:
2115+
case clang::OO_Less:
2116+
case clang::OO_Greater:
2117+
case clang::OO_LessLess:
2118+
case clang::OO_GreaterGreater:
2119+
case clang::OO_EqualEqual:
2120+
case clang::OO_PlusPlus:
2121+
case clang::OO_ExclaimEqual:
2122+
case clang::OO_LessEqual:
2123+
case clang::OO_GreaterEqual:
2124+
case clang::OO_AmpAmp:
2125+
case clang::OO_PipePipe:
2126+
os << importer::getOperatorName(ImporterImpl.SwiftContext, op).str();
2127+
break;
2128+
2129+
default:
2130+
useExistingName = true;
2131+
break;
2132+
}
2133+
}
2134+
2135+
if (!useExistingName) {
2136+
// The created method is inside the derived class already. If that's
2137+
// different from the base class, also include the base class in the
2138+
// mangling to keep this separate from other similar functions cloned from
2139+
// other base classes.
2140+
if (derivedClass != baseClass) {
2141+
os << "_";
2142+
std::unique_ptr<clang::ItaniumMangleContext> mangler{
2143+
clang::ItaniumMangleContext::create(clangCtx, clangCtx.getDiagnostics())};
2144+
auto derivedType = clangCtx.getTypeDeclType(baseClass)
2145+
.getCanonicalType();
2146+
mangler->mangleCanonicalTypeName(derivedType, os);
2147+
}
2148+
20932149
name = clang::DeclarationName(
20942150
&ImporterImpl.getClangPreprocessor().getIdentifierTable().get(
2095-
"__synthesizedBaseCall_operatorCall"));
2151+
os.str()));
20962152
}
2153+
20972154
auto methodType = method->getType();
20982155
// Check if we need to drop the reference from the return type
20992156
// of the new method. This is needed when a synthesized `operator []`

0 commit comments

Comments
 (0)