Skip to content

Commit c707643

Browse files
authored
Merge pull request swiftlang#63059 from hborla/synthesized-member-macros
[Macros] Initial support for synthesized member macros.
2 parents b01330e + 14f1172 commit c707643

24 files changed

+463
-63
lines changed

include/swift/AST/Decl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ namespace swift {
8080
class GenericSignature;
8181
class GenericTypeParamDecl;
8282
class GenericTypeParamType;
83+
class MacroDecl;
8384
class MacroDefinition;
8485
class ModuleDecl;
8586
class NamedPattern;
@@ -856,6 +857,13 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
856857
/// attribute macro expansion.
857858
DeclAttributes getSemanticAttrs() const;
858859

860+
using MacroCallback = llvm::function_ref<void(CustomAttr *, MacroDecl *)>;
861+
862+
/// Iterate over each attached macro with the given role, invoking the
863+
/// given callback with each macro custom attribute and corresponding macro
864+
/// declaration.
865+
void forEachAttachedMacro(MacroRole role, MacroCallback) const;
866+
859867
/// Returns the innermost enclosing decl with an availability annotation.
860868
const Decl *getInnermostDeclWithAvailability() const;
861869

include/swift/AST/MacroDeclaration.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ enum class MacroRole: uint32_t {
3535
/// An attached macro that generates attributes for the
3636
/// members inside the declaration.
3737
MemberAttribute = 0x08,
38+
/// An attached macro that generates synthesized members
39+
/// inside the declaration.
40+
SynthesizedMembers = 0x10,
3841
};
3942

4043
/// The contexts in which a particular macro declaration can be used.

include/swift/AST/SourceFile.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,13 @@ class SourceFile final : public FileUnit {
511511
/// macro.
512512
CustomAttr *getAttachedMacroAttribute() const;
513513

514+
/// For source files created to hold the source code created by expanding
515+
/// an attached macro, this is the macro role that the expansion fulfills.
516+
///
517+
/// \Returns the fulfilled macro role, or \c None if this source file is not
518+
/// for a macro expansion.
519+
Optional<MacroRole> getFulfilledMacroRole() const;
520+
514521
/// When this source file is enclosed within another source file, for example
515522
/// because it describes a macro expansion, return the source file it was
516523
/// enclosed in.

include/swift/AST/TypeCheckRequests.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3856,6 +3856,23 @@ class ExpandMemberAttributeMacros
38563856
bool isCached() const { return true; }
38573857
};
38583858

3859+
/// Expand synthesized member macros attached to the given declaration.
3860+
class ExpandSynthesizedMemberMacroRequest
3861+
: public SimpleRequest<ExpandSynthesizedMemberMacroRequest,
3862+
bool(Decl *),
3863+
RequestFlags::Cached> {
3864+
public:
3865+
using SimpleRequest::SimpleRequest;
3866+
3867+
private:
3868+
friend SimpleRequest;
3869+
3870+
bool evaluate(Evaluator &evaluator, Decl *decl) const;
3871+
3872+
public:
3873+
bool isCached() const { return true; }
3874+
};
3875+
38593876
/// Resolve an external macro given its module and type name.
38603877
class ExternalMacroDefinitionRequest
38613878
: public SimpleRequest<ExternalMacroDefinitionRequest,

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,9 @@ SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionDeclRequest,
458458
SWIFT_REQUEST(TypeChecker, ExpandMemberAttributeMacros,
459459
bool(Decl *),
460460
Cached, NoLocationInfo)
461+
SWIFT_REQUEST(TypeCHecker, ExpandSynthesizedMemberMacroRequest,
462+
bool(Decl *),
463+
Cached, NoLocationInfo)
461464
SWIFT_REQUEST(TypeChecker, SynthesizeRuntimeMetadataAttrGenerator,
462465
Expr *(CustomAttr *, ValueDecl *),
463466
Cached, NoLocationInfo)

include/swift/Basic/SourceManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class GeneratedSourceInfo {
4444
/// The expansion of a member attribute attached macro.
4545
MemberAttributeMacroExpansion,
4646

47+
/// The expansion of a synthesized member macro.
48+
SynthesizedMemberMacroExpansion,
49+
4750
/// A new function body that is replacing an existing function body.
4851
ReplacedFunctionBody,
4952

lib/AST/ASTScopeCreation.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,28 @@ ASTSourceFileScope::ASTSourceFileScope(SourceFile *SF,
248248
ScopeCreator *scopeCreator)
249249
: SF(SF), scopeCreator(scopeCreator) {
250250
if (auto enclosingSF = SF->getEnclosingSourceFile()) {
251-
SourceLoc parentLoc = SF->getMacroExpansion().getStartLoc();
251+
SourceLoc parentLoc;
252+
auto macroRole = SF->getFulfilledMacroRole();
253+
auto expansion = SF->getMacroExpansion();
254+
255+
// Determine the parent source location based on the macro role.
256+
switch (*macroRole) {
257+
case MacroRole::Expression:
258+
case MacroRole::FreestandingDeclaration:
259+
case MacroRole::Accessor:
260+
case MacroRole::MemberAttribute:
261+
parentLoc = expansion.getStartLoc();
262+
break;
263+
case MacroRole::SynthesizedMembers: {
264+
// For synthesized member macros, take the end loc of the
265+
// enclosing declaration (before the closing brace), because
266+
// the macro expansion is inside this scope.
267+
auto *decl = expansion.getAsDeclContext()->getAsDecl();
268+
parentLoc = decl->getEndLoc();
269+
break;
270+
}
271+
}
272+
252273
if (auto parentScope = findStartingScopeForLookup(enclosingSF, parentLoc)) {
253274
parentAndWasExpanded.setPointer(const_cast<ASTScopeImpl *>(parentScope));
254275
}

lib/AST/ASTVerifier.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3654,12 +3654,13 @@ class Verifier : public ASTWalker {
36543654
void checkSourceRanges(Decl *D) {
36553655
PrettyStackTraceDecl debugStack("verifying ranges", D);
36563656
const auto SR = D->getSourceRange();
3657+
3658+
// We don't care about source ranges on implicitly-generated
3659+
// decls.
3660+
if (D->isImplicit())
3661+
return;
3662+
36573663
if (!SR.isValid()) {
3658-
// We don't care about source ranges on implicitly-generated
3659-
// decls.
3660-
if (D->isImplicit())
3661-
return;
3662-
36633664
Out << "invalid source range for decl: ";
36643665
D->print(Out);
36653666
Out << "\n";

lib/AST/Decl.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,28 @@ DeclAttributes Decl::getSemanticAttrs() const {
374374
return getAttrs();
375375
}
376376

377+
void Decl::forEachAttachedMacro(MacroRole role,
378+
MacroCallback macroCallback) const {
379+
auto *dc = getDeclContext();
380+
auto &ctx = dc->getASTContext();
381+
382+
for (auto customAttrConst : getSemanticAttrs().getAttributes<CustomAttr>()) {
383+
auto customAttr = const_cast<CustomAttr *>(customAttrConst);
384+
auto *macroDecl = evaluateOrDefault(
385+
ctx.evaluator,
386+
ResolveAttachedMacroRequest{customAttr, dc},
387+
nullptr);
388+
389+
if (!macroDecl)
390+
continue;
391+
392+
if (!macroDecl->getMacroRoles().contains(role))
393+
continue;
394+
395+
macroCallback(customAttr, macroDecl);
396+
}
397+
}
398+
377399
const Decl *Decl::getInnermostDeclWithAvailability() const {
378400
const Decl *enclosingDecl = this;
379401
// Find the innermost enclosing declaration with an @available annotation.
@@ -9703,6 +9725,9 @@ StringRef swift::getMacroRoleString(MacroRole role) {
97039725

97049726
case MacroRole::MemberAttribute:
97059727
return "memberAttributes";
9728+
9729+
case MacroRole::SynthesizedMembers:
9730+
return "synthesizedMembers";
97069731
}
97079732
}
97089733

@@ -9745,8 +9770,10 @@ static MacroRoles freestandingMacroRoles =
97459770
(MacroRoles() |
97469771
MacroRole::Expression |
97479772
MacroRole::FreestandingDeclaration);
9748-
static MacroRoles attachedMacroRoles = (MacroRoles() | MacroRole::Accessor |
9749-
MacroRole::MemberAttribute);
9773+
static MacroRoles attachedMacroRoles = (MacroRoles() |
9774+
MacroRole::Accessor |
9775+
MacroRole::MemberAttribute |
9776+
MacroRole::SynthesizedMembers);
97509777

97519778
bool swift::isFreestandingMacro(MacroRoles contexts) {
97529779
return bool(contexts & freestandingMacroRoles);

lib/AST/DiagnosticEngine.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1314,7 +1314,8 @@ std::vector<Diagnostic> DiagnosticEngine::getGeneratedSourceBufferNotes(
13141314
case GeneratedSourceInfo::ExpressionMacroExpansion:
13151315
case GeneratedSourceInfo::FreestandingDeclMacroExpansion:
13161316
case GeneratedSourceInfo::AccessorMacroExpansion:
1317-
case GeneratedSourceInfo::MemberAttributeMacroExpansion: {
1317+
case GeneratedSourceInfo::MemberAttributeMacroExpansion:
1318+
case GeneratedSourceInfo::SynthesizedMemberMacroExpansion: {
13181319
SourceRange origRange = expansionNode.getSourceRange();
13191320
DeclName macroName;
13201321
if (auto customAttr = generatedInfo->attachedMacroCustomAttr) {

0 commit comments

Comments
 (0)