Skip to content

Commit a3caacd

Browse files
committed
[Macros] Initial implementation of conformance macros.
1 parent fedf86f commit a3caacd

27 files changed

+265
-8
lines changed

include/swift/AST/MacroDeclaration.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ enum class MacroRole: uint32_t {
5252
/// An attached macro that generates declarations that are peers
5353
/// of the declaration the macro is attached to.
5454
Peer = 0x20,
55+
/// An attached macro that adds conformances to the declaration the
56+
/// macro is attached to.
57+
Conformance = 0x40,
5558
};
5659

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

include/swift/AST/TypeCheckRequests.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3848,6 +3848,26 @@ class ExpandAccessorMacros
38483848
bool isCached() const { return true; }
38493849
};
38503850

3851+
/// Expand all conformance macros attached to the given declaration.
3852+
///
3853+
/// Produces the set of macro expansion buffer IDs.
3854+
class ExpandConformanceMacros
3855+
: public SimpleRequest<ExpandConformanceMacros,
3856+
ArrayRef<unsigned>(NominalTypeDecl *),
3857+
RequestFlags::Cached> {
3858+
public:
3859+
using SimpleRequest::SimpleRequest;
3860+
3861+
private:
3862+
friend SimpleRequest;
3863+
3864+
ArrayRef<unsigned> evaluate(Evaluator &evaluator,
3865+
NominalTypeDecl *nominal) const;
3866+
3867+
public:
3868+
bool isCached() const { return true; }
3869+
};
3870+
38513871
/// Expand all member attribute macros attached to the given
38523872
/// declaration.
38533873
///

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,9 @@ SWIFT_REQUEST(TypeChecker, ExpandMemberAttributeMacros,
437437
SWIFT_REQUEST(TypeChecker, ExpandAccessorMacros,
438438
ArrayRef<unsigned>(AbstractStorageDecl *),
439439
Cached, NoLocationInfo)
440+
SWIFT_REQUEST(TypeChecker, ExpandConformanceMacros,
441+
ArrayRef<unsigned>(NominalTypeDecl *),
442+
Cached, NoLocationInfo)
440443
SWIFT_REQUEST(TypeChecker, ExpandSynthesizedMemberMacroRequest,
441444
ArrayRef<unsigned>(Decl *),
442445
Cached, NoLocationInfo)

include/swift/Basic/SourceManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ class GeneratedSourceInfo {
5050
/// The expansion of an attached peer macro.
5151
PeerMacroExpansion,
5252

53+
/// The expansion of an attached conformance macro.
54+
ConformanceMacroExpansion,
55+
5356
/// A new function body that is replacing an existing function body.
5457
ReplacedFunctionBody,
5558

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ NODE(ClangType)
4949
CONTEXT_NODE(Class)
5050
NODE(ClassMetadataBaseOffset)
5151
NODE(ConcreteProtocolConformance)
52+
NODE(ConformanceAttachedMacroExpansion)
5253
CONTEXT_NODE(Constructor)
5354
NODE(CoroutineContinuationPrototype)
5455
CONTEXT_NODE(Deallocator)

lib/AST/ASTMangler.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3771,7 +3771,8 @@ void ASTMangler::appendMacroExpansionContext(
37713771
case GeneratedSourceInfo::AccessorMacroExpansion:
37723772
case GeneratedSourceInfo::MemberAttributeMacroExpansion:
37733773
case GeneratedSourceInfo::MemberMacroExpansion:
3774-
case GeneratedSourceInfo::PeerMacroExpansion: {
3774+
case GeneratedSourceInfo::PeerMacroExpansion:
3775+
case GeneratedSourceInfo::ConformanceMacroExpansion: {
37753776
auto decl = ASTNode::getFromOpaqueValue(generatedSourceInfo->astNode)
37763777
.get<Decl *>();
37773778
auto attr = generatedSourceInfo->attachedMacroCustomAttr;
@@ -3793,6 +3794,10 @@ void ASTMangler::appendMacroExpansionContext(
37933794
role = MacroRole::Peer;
37943795
break;
37953796

3797+
case GeneratedSourceInfo::ConformanceMacroExpansion:
3798+
role = MacroRole::Conformance;
3799+
break;
3800+
37963801
default:
37973802
llvm_unreachable("Unhandled macro role");
37983803
}
@@ -3851,6 +3856,10 @@ void ASTMangler::appendMacroExpansionOperator(
38513856
case MacroRole::Peer:
38523857
appendOperator("fMp", Index(discriminator));
38533858
break;
3859+
3860+
case MacroRole::Conformance:
3861+
appendOperator("fMc", Index(discriminator));
3862+
break;
38543863
}
38553864
}
38563865

lib/AST/ASTScopeCreation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ ASTSourceFileScope::ASTSourceFileScope(SourceFile *SF,
259259
case MacroRole::Accessor:
260260
case MacroRole::MemberAttribute:
261261
case MacroRole::Peer:
262+
case MacroRole::Conformance:
262263
parentLoc = expansion.getStartLoc();
263264
break;
264265
case MacroRole::Member: {

lib/AST/Decl.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,13 +383,14 @@ DeclAttributes Decl::getSemanticAttrs() const {
383383
void Decl::visitAuxiliaryDecls(AuxiliaryDeclCallback callback) const {
384384
auto &ctx = getASTContext();
385385
auto *mutableThis = const_cast<Decl *>(this);
386+
SourceManager &sourceMgr = ctx.SourceMgr;
387+
auto *moduleDecl = getModuleContext();
388+
386389
auto peerBuffers =
387390
evaluateOrDefault(ctx.evaluator,
388391
ExpandPeerMacroRequest{mutableThis},
389392
{});
390393

391-
SourceManager &sourceMgr = ctx.SourceMgr;
392-
auto *moduleDecl = getModuleContext();
393394
for (auto bufferID : peerBuffers) {
394395
auto startLoc = sourceMgr.getLocForBufferStart(bufferID);
395396
auto *sourceFile = moduleDecl->getSourceFileContainingLocation(startLoc);
@@ -398,6 +399,20 @@ void Decl::visitAuxiliaryDecls(AuxiliaryDeclCallback callback) const {
398399
}
399400
}
400401

402+
if (auto *nominal = dyn_cast<NominalTypeDecl>(mutableThis)) {
403+
auto conformanceBuffers =
404+
evaluateOrDefault(ctx.evaluator,
405+
ExpandConformanceMacros{nominal},
406+
{});
407+
for (auto bufferID : conformanceBuffers) {
408+
auto startLoc = sourceMgr.getLocForBufferStart(bufferID);
409+
auto *sourceFile = moduleDecl->getSourceFileContainingLocation(startLoc);
410+
for (auto *extension : sourceFile->getTopLevelDecls()) {
411+
callback(extension);
412+
}
413+
}
414+
}
415+
401416
// FIXME: fold VarDecl::visitAuxiliaryDecls into this.
402417
}
403418

@@ -9810,6 +9825,9 @@ StringRef swift::getMacroRoleString(MacroRole role) {
98109825

98119826
case MacroRole::Peer:
98129827
return "peer";
9828+
9829+
case MacroRole::Conformance:
9830+
return "conformance";
98139831
}
98149832
}
98159833

@@ -9856,7 +9874,8 @@ static MacroRoles attachedMacroRoles = (MacroRoles() |
98569874
MacroRole::Accessor |
98579875
MacroRole::MemberAttribute |
98589876
MacroRole::Member |
9859-
MacroRole::Peer);
9877+
MacroRole::Peer |
9878+
MacroRole::Conformance);
98609879

98619880
bool swift::isFreestandingMacro(MacroRoles contexts) {
98629881
return bool(contexts & freestandingMacroRoles);
@@ -10035,6 +10054,7 @@ MacroDiscriminatorContext MacroDiscriminatorContext::getParentOf(
1003510054
case GeneratedSourceInfo::MemberAttributeMacroExpansion:
1003610055
case GeneratedSourceInfo::MemberMacroExpansion:
1003710056
case GeneratedSourceInfo::PeerMacroExpansion:
10057+
case GeneratedSourceInfo::ConformanceMacroExpansion:
1003810058
case GeneratedSourceInfo::PrettyPrinted:
1003910059
case GeneratedSourceInfo::ReplacedFunctionBody:
1004010060
return origDC;

lib/AST/DiagnosticEngine.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1313,7 +1313,8 @@ std::vector<Diagnostic> DiagnosticEngine::getGeneratedSourceBufferNotes(
13131313
case GeneratedSourceInfo::AccessorMacroExpansion:
13141314
case GeneratedSourceInfo::MemberAttributeMacroExpansion:
13151315
case GeneratedSourceInfo::MemberMacroExpansion:
1316-
case GeneratedSourceInfo::PeerMacroExpansion: {
1316+
case GeneratedSourceInfo::PeerMacroExpansion:
1317+
case GeneratedSourceInfo::ConformanceMacroExpansion: {
13171318
SourceRange origRange = expansionNode.getSourceRange();
13181319
DeclName macroName;
13191320
if (auto customAttr = generatedInfo->attachedMacroCustomAttr) {

lib/AST/Module.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,9 @@ Optional<MacroRole> SourceFile::getFulfilledMacroRole() const {
931931
case GeneratedSourceInfo::PeerMacroExpansion:
932932
return MacroRole::Peer;
933933

934+
case GeneratedSourceInfo::ConformanceMacroExpansion:
935+
return MacroRole::Conformance;
936+
934937
case GeneratedSourceInfo::ReplacedFunctionBody:
935938
case GeneratedSourceInfo::PrettyPrinted:
936939
return None;

0 commit comments

Comments
 (0)