Skip to content

Commit bc64ff2

Browse files
committed
[ASTGen] Generate MacroDecl
1 parent 52cff19 commit bc64ff2

File tree

6 files changed

+314
-4
lines changed

6 files changed

+314
-4
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,17 @@ class ASTContext;
3838
struct ASTNode;
3939
class DeclAttributes;
4040
class DeclBaseName;
41+
class DeclName;
4142
class DeclNameLoc;
4243
class DeclNameRef;
4344
class DiagnosticArgument;
4445
class DiagnosticEngine;
4546
class Identifier;
4647
class IfConfigClauseRangeInfo;
4748
struct LabeledStmtInfo;
49+
enum class MacroRole : uint32_t;
50+
class MacroIntroducedDeclName;
51+
enum class MacroIntroducedDeclNameKind;
4852
class ProtocolConformanceRef;
4953
class RegexLiteralPatternFeature;
5054
class RegexLiteralPatternFeatureKind;
@@ -59,6 +63,7 @@ struct BridgedASTType;
5963
class BridgedCanType;
6064
class BridgedASTContext;
6165
struct BridgedSubstitutionMap;
66+
class BridgedParameterList;
6267

6368
//===----------------------------------------------------------------------===//
6469
// MARK: Identifier
@@ -114,6 +119,20 @@ SWIFT_NAME("BridgedDeclBaseName.createIdentifier(_:)")
114119
BridgedDeclBaseName
115120
BridgedDeclBaseName_createIdentifier(BridgedIdentifier identifier);
116121

122+
class BridgedDeclName {
123+
void *_Nonnull opaque;
124+
125+
public:
126+
BRIDGED_INLINE BridgedDeclName(swift::DeclName name);
127+
128+
BRIDGED_INLINE swift::DeclName unbridged() const;
129+
};
130+
131+
SWIFT_NAME("BridgedDeclName.createParsed(_:baseName:paramList:)")
132+
BridgedDeclName BridgedDeclName_createParsed(BridgedASTContext cContext,
133+
BridgedDeclBaseName cBaseName,
134+
BridgedParameterList cParamList);
135+
117136
class BridgedDeclNameRef {
118137
void *_Nonnull opaque;
119138

@@ -681,6 +700,51 @@ BridgedMainTypeAttr BridgedMainTypeAttr_createParsed(BridgedASTContext cContext,
681700
BridgedSourceLoc cAtLoc,
682701
BridgedSourceLoc cNameLoc);
683702

703+
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedMacroSyntax {
704+
BridgedMacroSyntaxFreestanding,
705+
BridgedMacroSyntaxAttached,
706+
};
707+
708+
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedMacroIntroducedDeclNameKind {
709+
BridgedMacroIntroducedDeclNameKindNamed,
710+
BridgedMacroIntroducedDeclNameKindOverloaded,
711+
BridgedMacroIntroducedDeclNameKindPrefixed,
712+
BridgedMacroIntroducedDeclNameKindSuffixed,
713+
BridgedMacroIntroducedDeclNameKindArbitrary,
714+
};
715+
716+
BRIDGED_INLINE swift::MacroIntroducedDeclNameKind
717+
unbridge(BridgedMacroIntroducedDeclNameKind kind);
718+
719+
struct BridgedMacroIntroducedDeclName {
720+
BridgedMacroIntroducedDeclNameKind kind;
721+
BridgedDeclName name;
722+
723+
BRIDGED_INLINE swift::MacroIntroducedDeclName unbridged() const;
724+
};
725+
726+
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedMacroRole {
727+
#define MACRO_ROLE(Name, Description) BridgedMacroRole##Name,
728+
#include "swift/Basic/MacroRoles.def"
729+
BridgedMacroRoleNone,
730+
};
731+
732+
BRIDGED_INLINE swift::MacroRole unbridge(BridgedMacroRole cRole);
733+
734+
SWIFT_NAME("BridgedMacroRole.init(from:)")
735+
BridgedMacroRole BridgedMacroRole_fromString(BridgedStringRef str);
736+
737+
SWIFT_NAME("getter:BridgedMacroRole.isAttached(self:)")
738+
BRIDGED_INLINE bool BridgedMacroRole_isAttached(BridgedMacroRole role);
739+
740+
SWIFT_NAME("BridgedMacroRoleAttr.createParsed(_:atLoc:range:syntax:lParenLoc:"
741+
"role:names:conformances:rParenLoc:)")
742+
BridgedMacroRoleAttr BridgedMacroRoleAttr_createParsed(
743+
BridgedASTContext cContext, BridgedSourceLoc cAtLoc,
744+
BridgedSourceRange cRange, BridgedMacroSyntax cSyntax,
745+
BridgedSourceLoc cLParenLoc, BridgedMacroRole cRole, BridgedArrayRef cNames,
746+
BridgedArrayRef cConformances, BridgedSourceLoc cRParenLoc);
747+
684748
SWIFT_NAME(
685749
"BridgedSwiftNativeObjCRuntimeBaseAttr.createParsed(_:atLoc:range:name:)")
686750
BridgedSwiftNativeObjCRuntimeBaseAttr
@@ -980,6 +1044,16 @@ BridgedAssociatedTypeDecl BridgedAssociatedTypeDecl_createParsed(
9801044
BridgedNullableTypeRepr opaqueDefaultType,
9811045
BridgedNullableTrailingWhereClause genericWhereClause);
9821046

1047+
SWIFT_NAME(
1048+
"BridgedMacroDecl.createParsed(_:declContext:macroKeywordLoc:name:nameLoc:"
1049+
"genericParamList:paramList:arrowLoc:resultType:definition:)")
1050+
BridgedMacroDecl BridgedMacroDecl_createParsed(
1051+
BridgedASTContext cContext, BridgedDeclContext cDeclContext,
1052+
BridgedSourceLoc cMacroLoc, BridgedIdentifier cName,
1053+
BridgedSourceLoc cNameLoc, BridgedNullableGenericParamList cGenericParams,
1054+
BridgedParameterList cParams, BridgedSourceLoc cArrowLoc,
1055+
BridgedNullableTypeRepr cResultType, BridgedNullableExpr cDefinition);
1056+
9831057
SWIFT_NAME("BridgedMacroExpansionDecl.createParsed(_:poundLoc:macroNameRef:"
9841058
"macroNameLoc:leftAngleLoc:genericArgs:rightAngleLoc:args:)")
9851059
BridgedMacroExpansionDecl BridgedMacroExpansionDecl_createParsed(

include/swift/AST/ASTBridgingImpl.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/AST/Decl.h"
1919
#include "swift/AST/Expr.h"
2020
#include "swift/AST/IfConfigClauseRangeInfo.h"
21+
#include "swift/AST/MacroDeclaration.h"
2122
#include "swift/AST/ProtocolConformance.h"
2223
#include "swift/AST/ProtocolConformanceRef.h"
2324
#include "swift/AST/SourceFile.h"
@@ -48,6 +49,17 @@ swift::DeclBaseName BridgedDeclBaseName::unbridged() const {
4849
return swift::DeclBaseName(Ident.unbridged());
4950
}
5051

52+
//===----------------------------------------------------------------------===//
53+
// MARK: BridgedDeclName
54+
//===----------------------------------------------------------------------===//
55+
56+
BridgedDeclName::BridgedDeclName(swift::DeclName name)
57+
: opaque(name.getOpaqueValue()) {}
58+
59+
swift::DeclName BridgedDeclName::unbridged() const {
60+
return swift::DeclName::getFromOpaqueValue(opaque);
61+
}
62+
5163
//===----------------------------------------------------------------------===//
5264
// MARK: BridgedDeclNameRef
5365
//===----------------------------------------------------------------------===//
@@ -355,6 +367,45 @@ BridgedConformance BridgedConformanceArray::getAt(SwiftInt index) const {
355367
return pcArray.unbridged<swift::ProtocolConformanceRef>()[index];
356368
}
357369

370+
//===----------------------------------------------------------------------===//
371+
// MARK: Macros
372+
//===----------------------------------------------------------------------===//
373+
374+
swift::MacroRole unbridge(BridgedMacroRole cRole) {
375+
switch (cRole) {
376+
#define MACRO_ROLE(Name, Description) \
377+
case BridgedMacroRole##Name: \
378+
return swift::MacroRole::Name;
379+
#include "swift/Basic/MacroRoles.def"
380+
case BridgedMacroRoleNone:
381+
break;
382+
}
383+
assert(false && "invalid macro role");
384+
}
385+
386+
swift::MacroIntroducedDeclNameKind
387+
unbridge(BridgedMacroIntroducedDeclNameKind kind) {
388+
switch (kind) {
389+
#define CASE(ID) \
390+
case BridgedMacroIntroducedDeclNameKind##ID: \
391+
return swift::MacroIntroducedDeclNameKind::ID;
392+
CASE(Named)
393+
CASE(Overloaded)
394+
CASE(Prefixed)
395+
CASE(Suffixed)
396+
CASE(Arbitrary)
397+
}
398+
}
399+
400+
bool BridgedMacroRole_isAttached(BridgedMacroRole role) {
401+
return isAttachedMacro(unbridge(role));
402+
}
403+
404+
swift::MacroIntroducedDeclName
405+
BridgedMacroIntroducedDeclName::unbridged() const {
406+
return swift::MacroIntroducedDeclName(unbridge(kind), name.unbridged());
407+
}
408+
358409
//===----------------------------------------------------------------------===//
359410
// MARK: BridgedSubstitutionMap
360411
//===----------------------------------------------------------------------===//

lib/AST/Bridging/DeclAttributeBridging.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,44 @@ BridgedInlineAttr BridgedInlineAttr_createParsed(BridgedASTContext cContext,
266266
InlineAttr(cAtLoc.unbridged(), cRange.unbridged(), unbridged(cKind));
267267
}
268268

269+
BridgedMacroRole BridgedMacroRole_fromString(BridgedStringRef str) {
270+
// Match the role string to the known set of roles.
271+
auto role =
272+
llvm::StringSwitch<std::optional<BridgedMacroRole>>(str.unbridged())
273+
#define MACRO_ROLE(Name, Description) .Case(Description, BridgedMacroRole##Name)
274+
#include "swift/Basic/MacroRoles.def"
275+
.Default(std::nullopt);
276+
return role.has_value() ? *role : BridgedMacroRoleNone;
277+
}
278+
279+
MacroSyntax unbridge(BridgedMacroSyntax cSyntax) {
280+
switch (cSyntax) {
281+
case BridgedMacroSyntaxAttached:
282+
return MacroSyntax::Attached;
283+
case BridgedMacroSyntaxFreestanding:
284+
return MacroSyntax::Freestanding;
285+
}
286+
}
287+
288+
BridgedMacroRoleAttr BridgedMacroRoleAttr_createParsed(
289+
BridgedASTContext cContext, BridgedSourceLoc cAtLoc,
290+
BridgedSourceRange cRange, BridgedMacroSyntax cSyntax,
291+
BridgedSourceLoc cLParenLoc, BridgedMacroRole cRole, BridgedArrayRef cNames,
292+
BridgedArrayRef cConformances, BridgedSourceLoc cRParenLoc) {
293+
SmallVector<MacroIntroducedDeclName, 2> names;
294+
for (auto &n : cNames.unbridged<BridgedMacroIntroducedDeclName>())
295+
names.push_back(n.unbridged());
296+
297+
SmallVector<TypeExpr *, 2> conformances;
298+
for (auto &t : cConformances.unbridged<BridgedTypeExpr>())
299+
conformances.push_back(t.unbridged());
300+
301+
return MacroRoleAttr::create(
302+
cContext.unbridged(), cAtLoc.unbridged(), cRange.unbridged(),
303+
unbridge(cSyntax), cLParenLoc.unbridged(), unbridge(cRole), names,
304+
conformances, cRParenLoc.unbridged(), /*implicit=*/false);
305+
}
306+
269307
BridgedMainTypeAttr
270308
BridgedMainTypeAttr_createParsed(BridgedASTContext cContext,
271309
BridgedSourceLoc cAtLoc,

lib/AST/Bridging/DeclBridging.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,22 @@ BridgedDestructorDecl_createParsed(BridgedASTContext cContext,
304304
return decl;
305305
}
306306

307+
BridgedMacroDecl BridgedMacroDecl_createParsed(
308+
BridgedASTContext cContext, BridgedDeclContext cDeclContext,
309+
BridgedSourceLoc cMacroLoc, BridgedIdentifier cName,
310+
BridgedSourceLoc cNameLoc, BridgedNullableGenericParamList cGenericParams,
311+
BridgedParameterList cParams, BridgedSourceLoc cArrowLoc,
312+
BridgedNullableTypeRepr cResultType, BridgedNullableExpr cDefinition) {
313+
ASTContext &context = cContext.unbridged();
314+
auto *params = cParams.unbridged();
315+
DeclName fullName = DeclName(context, cName.unbridged(), params);
316+
return new (context)
317+
MacroDecl(cMacroLoc.unbridged(), fullName, cNameLoc.unbridged(),
318+
cGenericParams.unbridged(), params, cArrowLoc.unbridged(),
319+
cResultType.unbridged(), cDefinition.unbridged(),
320+
cDeclContext.unbridged());
321+
}
322+
307323
BridgedTypeAliasDecl BridgedTypeAliasDecl_createParsed(
308324
BridgedASTContext cContext, BridgedDeclContext cDeclContext,
309325
BridgedSourceLoc cAliasKeywordLoc, BridgedIdentifier cName,

lib/ASTGen/Sources/ASTGen/DeclAttrs.swift

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ extension ASTGenVisitor {
135135
case .mainType:
136136
return self.generateMainTypeAttr(attribute: node)?.asDeclAttribute
137137
case .macroRole:
138-
fatalError("unimplemented")
138+
return self.generateMacroRoleAttr(attribute: node, attrName: attrName)?.asDeclAttribute
139139
case .noExistentials:
140140
fatalError("unimplemented")
141141
case .noObjCBridging:
@@ -674,6 +674,116 @@ extension ASTGenVisitor {
674674
)
675675
}
676676

677+
func generateMacroIntroducedDeclName(expr: ExprSyntax) -> BridgedMacroIntroducedDeclName? {
678+
fatalError("unimplemented")
679+
}
680+
681+
func generateMacroIntroducedConformance(expr: ExprSyntax) -> BridgedTypeExpr? {
682+
fatalError("unimplemented")
683+
}
684+
685+
func generateMacroRoleAttr(attribute node: AttributeSyntax, attrName: SyntaxText) -> BridgedMacroRoleAttr? {
686+
// '@freestanding' or '@attached'.
687+
assert(attrName == "freestanding" || attrName == "attached")
688+
let syntax: BridgedMacroSyntax =
689+
attrName == "freestanding" ? .freestanding : .attached;
690+
let isAttached = syntax == .attached
691+
692+
// Start consuming arguments.
693+
guard
694+
var args = node.arguments?.as(LabeledExprListSyntax.self)?[...]
695+
else {
696+
// TODO: Diagnose.
697+
return nil
698+
}
699+
700+
// Macro role.
701+
let role = self.generateConsumingPlainIdentifierAttrOption(args: &args) {
702+
BridgedMacroRole(from: $0.rawText.bridged)
703+
}
704+
guard let role = role else {
705+
return nil
706+
}
707+
guard role != .none else {
708+
// TODO: Diagnose.
709+
return nil
710+
}
711+
if role.isAttached != isAttached {
712+
// TODO: Diagnose.
713+
return nil
714+
}
715+
716+
var names: [BridgedMacroIntroducedDeclName] = []
717+
var conformances: [BridgedTypeExpr] = []
718+
719+
enum ArgState {
720+
case inNames
721+
case inConformances
722+
case inInvalid
723+
}
724+
// We assume we're in 'names:' arguments.
725+
var argState: ArgState = .inNames
726+
// Seen at 'names:' argument label.
727+
var seenNames = false
728+
// Seen at 'conformances:' argument label.
729+
var seenConformances = false
730+
731+
LOOP: while let arg = args.popFirst() {
732+
// Argument state.
733+
if let label = arg.label {
734+
switch label {
735+
case .identifier("names"):
736+
argState = .inNames
737+
if seenNames {
738+
// TODO: Diagnose duplicated 'names:'.
739+
}
740+
seenNames = true
741+
case .identifier("conformances"):
742+
argState = .inConformances
743+
if seenConformances {
744+
// TODO: Diagnose duplicated 'conformances:'.
745+
}
746+
seenConformances = true
747+
default:
748+
// Invalid label.
749+
// TODO: Diagnose `no argument with label '\(label)'`.
750+
argState = .inInvalid
751+
}
752+
} else if argState == .inNames && !seenNames {
753+
// E.g. `@attached(member, named(foo))` this is missing 'names:'
754+
// TODO: Diagnose to insert 'names:'
755+
seenNames = true
756+
}
757+
758+
// Argument values.
759+
switch argState {
760+
case .inNames:
761+
if let name = self.generateMacroIntroducedDeclName(expr: arg.expression) {
762+
names.append(name)
763+
}
764+
case .inConformances:
765+
if let conformance = self.generateMacroIntroducedConformance(expr: arg.expression) {
766+
conformances.append(conformance)
767+
}
768+
case .inInvalid:
769+
// Ignore the value.
770+
break
771+
}
772+
}
773+
774+
return .createParsed(
775+
self.ctx,
776+
atLoc: self.generateSourceLoc(node.atSign),
777+
range: self.generateSourceRange(node),
778+
syntax: syntax,
779+
lParenLoc: self.generateSourceLoc(node.leftParen),
780+
role: role,
781+
names: names.lazy.bridgedArray(in: self),
782+
conformances: conformances.lazy.bridgedArray(in: self),
783+
rParenLoc: self.generateSourceLoc(node.rightParen)
784+
)
785+
}
786+
677787
func generateNonSendableAttr(attribute node: AttributeSyntax) -> BridgedNonSendableAttr? {
678788
let kind: BridgedNonSendableKind? = self.generateSingleAttrOption(
679789
attribute: node,

0 commit comments

Comments
 (0)