Skip to content

Commit 018a78b

Browse files
committed
[Macros] Mangle attached macros for accessors
Attached macro mangles for accessors were using a fallback case that triggers an assertion in +Asserts builds, and conflicting manglings is non-Asserts builds. Provide a custom mangling for these cases that's embedded in the identifier. This is a narrow hack to eliminate an assertion. We are considering a different approach for the long term that uses entity manglings with a placeholder type, which will be more flexible long-term.
1 parent e5d9ae2 commit 018a78b

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4062,7 +4062,42 @@ std::string ASTMangler::mangleAttachedMacroExpansion(
40624062
// dependencies.
40634063
const Decl *attachedTo = decl;
40644064
DeclBaseName attachedToName;
4065-
if (auto valueDecl = dyn_cast<ValueDecl>(decl)) {
4065+
if (auto accessor = dyn_cast<AccessorDecl>(decl)) {
4066+
auto storage = accessor->getStorage();
4067+
appendContextOf(storage);
4068+
4069+
// Introduce an identifier mangling that includes var/subscript, accessor
4070+
// kind, and static.
4071+
// FIXME: THIS IS A HACK. We need something different.
4072+
{
4073+
llvm::SmallString<16> name;
4074+
{
4075+
llvm::raw_svector_ostream out(name);
4076+
out << storage->getName().getBaseName().userFacingName()
4077+
<< "__";
4078+
if (isa<VarDecl>(storage)) {
4079+
out << "v";
4080+
} else {
4081+
assert(isa<SubscriptDecl>(storage));
4082+
out << "i";
4083+
}
4084+
4085+
out << getCodeForAccessorKind(accessor->getAccessorKind());
4086+
if (storage->isStatic())
4087+
out << "Z";
4088+
}
4089+
4090+
attachedToName = decl->getASTContext().getIdentifier(name);
4091+
}
4092+
4093+
appendDeclName(storage, attachedToName);
4094+
4095+
// For member attribute macros, the attribute is attached to the enclosing
4096+
// declaration.
4097+
if (role == MacroRole::MemberAttribute) {
4098+
attachedTo = storage->getDeclContext()->getAsDecl();
4099+
}
4100+
} else if (auto valueDecl = dyn_cast<ValueDecl>(decl)) {
40664101
appendContextOf(valueDecl);
40674102

40684103
// Mangle the name, replacing special names with their user-facing names.

lib/AST/Decl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10529,6 +10529,9 @@ DeclContext *
1052910529
MacroDiscriminatorContext::getInnermostMacroContext(DeclContext *dc) {
1053010530
switch (dc->getContextKind()) {
1053110531
case DeclContextKind::SubscriptDecl:
10532+
// For a subscript, return its parent context.
10533+
return getInnermostMacroContext(dc->getParent());
10534+
1053210535
case DeclContextKind::EnumElementDecl:
1053310536
case DeclContextKind::AbstractFunctionDecl:
1053410537
case DeclContextKind::SerializedLocal:

test/Macros/macro_expand_attributes.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,15 @@ struct OldStorage {
111111
// The deprecation warning below comes from the deprecation attribute
112112
// introduced by @wrapStoredProperties on OldStorage.
113113
_ = OldStorage(x: 5).x // expected-warning{{'x' is deprecated: hands off my data}}
114+
115+
@wrapStoredProperties(#"available(*, deprecated, message: "hands off my data")"#)
116+
class C2: P {
117+
var x: Int = 0
118+
var y: Int = 0
119+
120+
var squareOfLength: Int {
121+
return x*x + y*y // expected-warning 4{{hands off my data}}
122+
}
123+
124+
var blah: Int { squareOfLength }
125+
}

0 commit comments

Comments
 (0)