Skip to content

Commit ac440c3

Browse files
[wasm] Accept multiple @_expose on a single function decl
But multiple @_expose with the same exposure kind are still invalid.
1 parent 6d378a3 commit ac440c3

File tree

6 files changed

+30
-7
lines changed

6 files changed

+30
-7
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ SIMPLE_DECL_ATTR(_alwaysEmitConformanceMetadata, AlwaysEmitConformanceMetadata,
398398
OnProtocol | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
399399
132)
400400
DECL_ATTR(_expose, Expose,
401-
OnFunc | OnNominalType | OnVar | OnConstructor | LongAttribute | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
401+
OnFunc | OnNominalType | OnVar | AllowMultipleAttributes | OnConstructor | LongAttribute | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
402402
133)
403403
SIMPLE_DECL_ATTR(_spiOnly, SPIOnly,
404404
OnImport | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,

lib/AST/SwiftNameTranslation.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ swift::cxx_translation::getNameForCxx(const ValueDecl *VD,
158158
CustomNamesOnly_t customNamesOnly) {
159159
ASTContext& ctx = VD->getASTContext();
160160

161-
if (const auto *Expose = VD->getAttrs().getAttribute<ExposeAttr>()) {
162-
if (Expose->getExposureKind() == ExposureKind::Cxx && !Expose->Name.empty())
163-
return Expose->Name;
161+
for (auto *EA : VD->getAttrs().getAttributes<ExposeAttr>()) {
162+
if (EA->getExposureKind() == ExposureKind::Cxx && !EA->Name.empty())
163+
return EA->Name;
164164
}
165165

166166
if (customNamesOnly)

lib/Parse/ParseDecl.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3088,10 +3088,19 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
30883088
else if (DK == DAK_CDecl)
30893089
Attributes.add(new (Context) CDeclAttr(AsmName.value(), AtLoc,
30903090
AttrRange, /*Implicit=*/false));
3091-
else if (DK == DAK_Expose)
3091+
else if (DK == DAK_Expose) {
3092+
for (auto *EA : Attributes.getAttributes<ExposeAttr>()) {
3093+
// A single declaration cannot have two @_exported attributes with
3094+
// the same exposure kind.
3095+
if (EA->getExposureKind() == ExpKind) {
3096+
diagnose(Loc, diag::duplicate_attribute, false);
3097+
break;
3098+
}
3099+
}
30923100
Attributes.add(new (Context) ExposeAttr(
30933101
AsmName ? AsmName.value() : StringRef(""), AtLoc, AttrRange,
30943102
ExpKind, /*Implicit=*/false));
3103+
}
30953104
else
30963105
llvm_unreachable("out of sync with switch");
30973106
}

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2825,7 +2825,7 @@ static bool hasExposeAttr(const ValueDecl *VD, bool isExtension = false) {
28252825
// Clang decls don't need to be explicitly exposed.
28262826
if (VD->hasClangNode())
28272827
return true;
2828-
if (auto *EA = VD->getAttrs().getAttribute<ExposeAttr>()) {
2828+
for (auto *EA : VD->getAttrs().getAttributes<ExposeAttr>()) {
28292829
if (EA->getExposureKind() == ExposureKind::Cxx)
28302830
return true;
28312831
}

lib/SIL/IR/SILFunctionBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ void SILFunctionBuilder::addFunctionAttributes(
218218
if (Attrs.hasAttribute<SILGenNameAttr>() || Attrs.hasAttribute<CDeclAttr>())
219219
F->setHasCReferences(true);
220220

221-
if (auto *EA = Attrs.getAttribute<ExposeAttr>()) {
221+
for (auto *EA : Attrs.getAttributes<ExposeAttr>()) {
222222
bool shouldExportDecl = true;
223223
if (Attrs.hasAttribute<CDeclAttr>()) {
224224
// If the function is marked with @cdecl, expose only C compatible

test/attr/attr_expose.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ struct ExposedStruct {
3333
@_expose(Cxx, "initWith")
3434
init(with y: Int) {}
3535
}
36+
@_expose(Cxx)
37+
@_expose(Cxx) // expected-error {{duplicate attribute}}
38+
func exposeToCxxCxx() {}
3639

3740
@_expose(wasm) func exposeToWasm() {}
3841
@_expose(wasm, "with_name") func wasmName() {}
@@ -47,3 +50,14 @@ func wasmNested() {
4750
func errorOnInnerExpose() {}
4851
}
4952

53+
@_expose(Cxx)
54+
@_expose(wasm)
55+
func exposeToCxxWasm() {}
56+
57+
@_expose(wasm)
58+
@_expose(Cxx)
59+
func exposeToWasmCxx() {}
60+
61+
@_expose(wasm)
62+
@_expose(wasm) // expected-error {{duplicate attribute}}
63+
func exposeToWasmWasm() {}

0 commit comments

Comments
 (0)