Skip to content

Commit d427696

Browse files
authored
Allow @_silgen_name to be used on globals and add a @_silgen_name(raw: ...) version that skips mangling (#66540)
Attribute @_silgen_name is today only allowed to be used on functions, this change allows usage on globals as well. The motivation for that is to be able to "forward declare" globals just like it's today possible to do with functions (for the cases where it's not practical or convenient to use a bridging header). Separately, this change also adds a @_silgen_name(raw: ...) syntax, which simply avoids mangling the name (by using the \01 name prefix that LLVM uses). The motivation for that is to be able to reference the "magic Darwin linker symbols" that can be used to look up section bounds (in the current dylib/module) -- those symbols don't use the underscore prefix in their mangled names.
1 parent 6cd5975 commit d427696

File tree

15 files changed

+151
-21
lines changed

15 files changed

+151
-21
lines changed

docs/ReferenceGuides/UnderscoredAttributes.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -856,14 +856,15 @@ By default, SourceKit hides underscored protocols from the generated
856856
swiftinterface (for all modules, not just the standard library), but this
857857
attribute can be used to override that behavior for the standard library.
858858

859-
## `@_silgen_name("cName")`
859+
## `@_silgen_name([raw: ]"cName")`
860860

861-
Changes the symbol name for a function, similar to an ASM label in C,
862-
except that the platform symbol mangling (leading underscore on Darwin)
863-
is maintained.
861+
Changes the symbol name for a function or a global, similar to an ASM label in
862+
C. Unlike ASM labels in C, the platform symbol mangling (leading underscore on
863+
Darwin) is maintained, unless "raw:" is used, in which case the name provided is
864+
expected to already be mangled.
864865

865866
Since this has label-like behavior, it may not correspond to any declaration;
866-
if so, it is assumed that the function is implemented in C.
867+
if so, it is assumed that the function/global is implemented in C.
867868

868869
A function defined by `@_silgen_name` is assumed to use the Swift ABI.
869870

include/swift/AST/Attr.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -491,16 +491,19 @@ class SimpleDeclAttr : public DeclAttribute {
491491
/// Defines the @_silgen_name attribute.
492492
class SILGenNameAttr : public DeclAttribute {
493493
public:
494-
SILGenNameAttr(StringRef Name, SourceLoc AtLoc, SourceRange Range, bool Implicit)
494+
SILGenNameAttr(StringRef Name, bool Raw, SourceLoc AtLoc, SourceRange Range, bool Implicit)
495495
: DeclAttribute(DAK_SILGenName, AtLoc, Range, Implicit),
496-
Name(Name) {}
496+
Name(Name), Raw(Raw) {}
497497

498-
SILGenNameAttr(StringRef Name, bool Implicit)
499-
: SILGenNameAttr(Name, SourceLoc(), SourceRange(), Implicit) {}
498+
SILGenNameAttr(StringRef Name, bool Raw, bool Implicit)
499+
: SILGenNameAttr(Name, Raw, SourceLoc(), SourceRange(), Implicit) {}
500500

501501
/// The symbol name.
502502
const StringRef Name;
503503

504+
/// If true, the name is not to be mangled (underscore prefix on Darwin)
505+
bool Raw;
506+
504507
static bool classof(const DeclAttribute *DA) {
505508
return DA->getKind() == DAK_SILGenName;
506509
}

include/swift/AST/DiagnosticsSIL.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,8 @@ ERROR(performance_unknown_callees,none,
340340
"called function is not known at compile time and can have unpredictable performance", ())
341341
ERROR(performance_callee_unavailable,none,
342342
"called function is not available in this module and can have unpredictable performance", ())
343-
ERROR(section_attr_on_non_const_global,none,
344-
"global variable must be a compile-time constant to use @_section attribute", ())
343+
ERROR(bad_attr_on_non_const_global,none,
344+
"global variable must be a compile-time constant to use %0 attribute", (StringRef))
345345
NOTE(performance_called_from,none,
346346
"called from here", ())
347347

lib/AST/Decl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6861,6 +6861,9 @@ bool VarDecl::isLazilyInitializedGlobal() const {
68616861
if (isDebuggerVar())
68626862
return false;
68636863

6864+
if (getAttrs().hasAttribute<SILGenNameAttr>())
6865+
return false;
6866+
68646867
// Top-level global variables in the main source file and in the REPL are not
68656868
// lazily initialized.
68666869
return !isTopLevelGlobal();

lib/Parse/ParseDecl.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2893,6 +2893,15 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
28932893
ParseSymbolName = consumeIf(tok::comma);
28942894
}
28952895

2896+
bool Raw = false;
2897+
if (DK == DAK_SILGenName) {
2898+
if (Tok.is(tok::identifier) && Tok.getText() == "raw") {
2899+
consumeToken(tok::identifier);
2900+
consumeToken(tok::colon);
2901+
Raw = true;
2902+
}
2903+
}
2904+
28962905
llvm::Optional<StringRef> AsmName;
28972906
if (ParseSymbolName) {
28982907
if (Tok.isNot(tok::string_literal)) {
@@ -2928,7 +2937,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
29282937

29292938
if (!DiscardAttribute) {
29302939
if (DK == DAK_SILGenName)
2931-
Attributes.add(new (Context) SILGenNameAttr(AsmName.value(), AtLoc,
2940+
Attributes.add(new (Context) SILGenNameAttr(AsmName.value(), Raw, AtLoc,
29322941
AttrRange, /*Implicit=*/false));
29332942
else if (DK == DAK_CDecl)
29342943
Attributes.add(new (Context) CDeclAttr(AsmName.value(), AtLoc,

lib/SILGen/SILGenFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1446,7 +1446,7 @@ void SILGenFunction::emitAsyncMainThreadStart(SILDeclRef entryPoint) {
14461446
{}, /*async*/ false, /*throws*/ false, {}, emptyParams,
14471447
getASTContext().getNeverType(), moduleDecl);
14481448
drainQueueFuncDecl->getAttrs().add(new (getASTContext()) SILGenNameAttr(
1449-
"swift_task_asyncMainDrainQueue", /*implicit*/ true));
1449+
"swift_task_asyncMainDrainQueue", /*raw*/ false, /*implicit*/ true));
14501450
}
14511451

14521452
SILFunction *drainQueueSILFunc = SGM.getFunction(

lib/SILGen/SILGenGlobalVariable.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ SILGlobalVariable *SILGenModule::getSILGlobalVariable(VarDecl *gDecl,
3131
auto SILGenName = gDecl->getAttrs().getAttribute<SILGenNameAttr>();
3232
if (SILGenName && !SILGenName->Name.empty()) {
3333
mangledName = SILGenName->Name.str();
34+
if (SILGenName->Raw) {
35+
mangledName = "\1" + mangledName;
36+
}
3437
} else {
3538
Mangle::ASTMangler NewMangler;
3639
mangledName = NewMangler.mangleGlobalVariableFull(gDecl);
@@ -45,6 +48,13 @@ SILGlobalVariable *SILGenModule::getSILGlobalVariable(VarDecl *gDecl,
4548
formalLinkage = getDeclLinkage(gDecl);
4649
auto silLinkage = getSILLinkage(formalLinkage, forDef);
4750

51+
if (gDecl->getAttrs().hasAttribute<SILGenNameAttr>()) {
52+
silLinkage = SILLinkage::DefaultForDeclaration;
53+
if (! gDecl->hasInitialValue()) {
54+
forDef = NotForDefinition;
55+
}
56+
}
57+
4858
// Check if it is already created, and update linkage if necessary.
4959
if (auto gv = M.lookUpGlobalVariable(mangledName)) {
5060
// Update the SILLinkage here if this is a definition.

lib/SILGen/SILGenProlog.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,8 +1373,8 @@ SILValue SILGenFunction::emitMainExecutor(SILLocation loc) {
13731373
ctx.TheExecutorType,
13741374
getModule().getSwiftModule());
13751375
getMainExecutorFuncDecl->getAttrs().add(
1376-
new (ctx)
1377-
SILGenNameAttr("swift_task_getMainExecutor", /*implicit*/ true));
1376+
new (ctx) SILGenNameAttr("swift_task_getMainExecutor", /*raw*/ false,
1377+
/*implicit*/ true));
13781378
}
13791379

13801380
auto fn = SGM.getFunction(

lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -481,11 +481,22 @@ class PerformanceDiagnosticsPass : public SILModuleTransform {
481481

482482
PerformanceDiagnostics diagnoser(*module, getAnalysis<BasicCalleeAnalysis>());
483483

484-
// Check that @_section is only on constant globals
484+
// Check that @_section, @_silgen_name is only on constant globals
485485
for (SILGlobalVariable &g : module->getSILGlobals()) {
486-
if (!g.getStaticInitializerValue() && g.getSectionAttr())
487-
module->getASTContext().Diags.diagnose(
488-
g.getDecl()->getLoc(), diag::section_attr_on_non_const_global);
486+
if (!g.getStaticInitializerValue()) {
487+
if (g.getSectionAttr()) {
488+
module->getASTContext().Diags.diagnose(
489+
g.getDecl()->getLoc(), diag::bad_attr_on_non_const_global,
490+
"@_section");
491+
}
492+
493+
auto *decl = g.getDecl();
494+
if (decl && g.isDefinition() && decl->getAttrs().hasAttribute<SILGenNameAttr>()) {
495+
module->getASTContext().Diags.diagnose(
496+
g.getDecl()->getLoc(), diag::bad_attr_on_non_const_global,
497+
"@_silgen_name");
498+
}
499+
}
489500
}
490501

491502
bool annotatedFunctionsFound = false;

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2315,6 +2315,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23152315
if (!var->hasStorage())
23162316
return;
23172317

2318+
if (var->getAttrs().hasAttribute<SILGenNameAttr>())
2319+
return;
2320+
23182321
if (var->isInvalid() || PBD->isInvalid())
23192322
return;
23202323

0 commit comments

Comments
 (0)