Skip to content

[ASTGen] Update for specialized attribute kind removal #80351

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 75 additions & 91 deletions lib/ASTGen/Sources/ASTGen/DeclAttrs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -436,24 +436,25 @@ extension ASTGenVisitor {
/// @_alignment(8)
/// ```
func generateAlignmentAttr(attribute node: AttributeSyntax) -> BridgedAlignmentAttr? {
guard
let arg = node.arguments?.as(TokenSyntax.self)
else {
print("Not a token")
// TODO: Diagnose.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this comment be preserved? Here and all the case below

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generateWithLabeledExprListArguments and generateConsuming* will diagnose if the input is unexpected.

return nil
}
let value: Int? = Int(String(syntaxText: arg.rawText))
guard let value, value > 0 else {
// TODO: Diagnose.
return nil
self.generateWithLabeledExprListArguments(attribute: node) { args in
let value: Int? = self.generateConsumingAttrOption(args: &args, label: nil) { expr in
guard let intExpr = expr.as(IntegerLiteralExprSyntax.self) else {
return nil
}
return intExpr.representedLiteralValue
}
guard let value, value > 0 else {
// TODO: Diagnose.
return nil
}

return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
range: self.generateAttrSourceRange(node),
value: value
)
}
return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
range: self.generateAttrSourceRange(node),
value: value
)
}

/// E.g.:
Expand Down Expand Up @@ -557,25 +558,18 @@ extension ASTGenVisitor {
/// @_cdecl("c_function_name")
/// ```
func generateCDeclAttr(attribute node: AttributeSyntax) -> BridgedCDeclAttr? {
guard
// `@_cdecl` attribute has `.string(StringLiteralExprSyntax)` arguments.
let arg = node.arguments?.as(StringLiteralExprSyntax.self)
else {
// TODO: Diagnose.
return nil
}
guard
let name = self.generateStringLiteralTextIfNotInterpolated(expr: arg)
else {
// TODO: Diagnose.
return nil
self.generateWithLabeledExprListArguments(attribute: node) { args in
guard let name = self.generateConsumingSimpleStringLiteralAttrOption(args: &args) else {
return nil
}

return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
range: self.generateAttrSourceRange(node),
name: name
)
}
return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
range: self.generateAttrSourceRange(node),
name: name
)
}

struct GeneratedDerivativeOriginalDecl {
Expand Down Expand Up @@ -940,13 +934,21 @@ extension ASTGenVisitor {
}

// Name.
let name = self.generateConsumingSimpleStringLiteralAttrOption(args: &args) ?? ""
let name: BridgedStringRef?
if !args.isEmpty {
name = self.generateConsumingSimpleStringLiteralAttrOption(args: &args) ?? ""
guard name != nil else {
return nil
}
} else {
name = nil
}

return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
range: self.generateAttrSourceRange(node),
name: name,
name: name ?? BridgedStringRef(),
kind: kind
)
}
Expand Down Expand Up @@ -1605,27 +1607,21 @@ extension ASTGenVisitor {
}

func generatePrivateImportAttr(attribute node: AttributeSyntax) -> BridgedPrivateImportAttr? {
guard
// `@_private` has special argument list syntax
let args = node.arguments?.as(UnderscorePrivateAttributeArgumentsSyntax.self)
else {
// TODO: Diagnose
return nil
}
self.generateWithLabeledExprListArguments(attribute: node) { args in
let fileName = self.generateConsumingSimpleStringLiteralAttrOption(args: &args, label: "sourceFile")
guard let fileName else {
return nil
}

guard let fileName = self.generateStringLiteralTextIfNotInterpolated(expr: args.filename) else {
// TODO: Diagnose
return nil
return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
attrNameLoc: self.generateSourceLoc(node.attributeName),
lParenLoc: self.generateSourceLoc(node.leftParen),
fileName: fileName,
rParenLoc: self.generateSourceLoc(node.rightParen)
)
}

return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
attrNameLoc: self.generateSourceLoc(node.attributeName),
lParenLoc: self.generateSourceLoc(node.leftParen),
fileName: fileName,
rParenLoc: self.generateSourceLoc(node.rightParen)
)
}

/// E.g.:
Expand Down Expand Up @@ -1820,24 +1816,18 @@ extension ASTGenVisitor {
/// ```
/// @semantics("semantics_name")
func generateSemanticsAttr(attribute node: AttributeSyntax) -> BridgedSemanticsAttr? {
guard
let arg = node.arguments?.as(StringLiteralExprSyntax.self)
else {
// TODO: Diagnose.
return nil
}
guard
let value = self.generateStringLiteralTextIfNotInterpolated(expr: arg)
else {
// TODO: Diagnose.
return nil
self.generateWithLabeledExprListArguments(attribute: node) { args in
guard let value = self.generateConsumingSimpleStringLiteralAttrOption(args: &args) else {
return nil
}

return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
range: self.generateAttrSourceRange(node),
value: value
)
}
return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
range: self.generateAttrSourceRange(node),
value: value
)
}

/// E.g.:
Expand Down Expand Up @@ -2160,15 +2150,15 @@ extension ASTGenVisitor {
/// @_unavailableFromAsync(message: "use fooBar(_:) instead")
/// ```
func generateUnavailableFromAsyncAttr(attribute node: AttributeSyntax) -> BridgedUnavailableFromAsyncAttr? {

var message: BridgedStringRef? = nil
if node.arguments != nil {
// FIXME: Should be normal LabeledExprListSyntax arguments.

guard let args = node.arguments?.as(UnavailableFromAsyncAttributeArgumentsSyntax.self) else {
// TODO: Diagnose.
message = self.generateWithLabeledExprListArguments(attribute: node) { args in
self.generateConsumingSimpleStringLiteralAttrOption(args: &args, label: "message")
}
guard message != nil else {
return nil
}
message = self.generateStringLiteralTextIfNotInterpolated(expr: args.message)
}
return .createParsed(
self.ctx,
Expand Down Expand Up @@ -2309,14 +2299,13 @@ extension ASTGenVisitor {
_ valueGeneratorFunction: (TokenSyntax) -> R?
) -> R? {
return generateConsumingAttrOption(args: &args, label: nil) {
guard
let declRefExpr = $0.as(DeclReferenceExprSyntax.self),
declRefExpr.argumentNames == nil
else {
// TODO: Diagnose.
return nil
if let declRefExpr = $0.as(DeclReferenceExprSyntax.self), declRefExpr.argumentNames == nil {
return valueGeneratorFunction(declRefExpr.baseName)
} else if let discardExpr = $0.as(DiscardAssignmentExprSyntax.self) {
return valueGeneratorFunction(discardExpr.wildcard)
}
return valueGeneratorFunction(declRefExpr.baseName)
// TODO: Diagnose.
return nil
}
}

Expand All @@ -2341,19 +2330,14 @@ extension ASTGenVisitor {
_ valueGeneratorFunction: (TokenSyntax) -> Result?,
valueIfOmitted: Result? = nil
) -> Result? {
guard node.leftParen != nil, let arguments = node.arguments else {
guard node.arguments != nil else {
if let valueIfOmitted {
return valueIfOmitted
}
self.diagnose(.expectedArgumentsInAttribute(node))
return nil
}

if case .token(let tok) = arguments {
// Special case: was parsed as a token, not an an argument list
return valueGeneratorFunction(tok)
}

return self.generateWithLabeledExprListArguments(attribute: node) { args in
self.generateConsumingPlainIdentifierAttrOption(
args: &args,
Expand Down
129 changes: 74 additions & 55 deletions lib/ASTGen/Sources/ASTGen/TypeAttrs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,38 +142,49 @@ extension ASTGenVisitor {
nameLoc: self.generateSourceLoc(node.attributeName)
)
}


/// E.g.
/// ```
/// @convention(c)
/// @convention(c, cType: "int (*)(int)")
/// ```
func generateConventionTypeAttr(attribute node: AttributeSyntax) -> BridgedConventionTypeAttr? {
// FIXME: This doesn't need custom attribute arguments syntax.
// FIXME: Support 'witness_method' argument.
guard let args = node.arguments?.as(ConventionAttributeArgumentsSyntax.self) else {
// TODO: Diangose.
return nil
}

let cTypeName: BridgedStringRef?
let cTypeNameLoc: BridgedSourceLoc?
if let ctypeString = args.cTypeString {
cTypeName = self.generateStringLiteralTextIfNotInterpolated(expr: ctypeString)
cTypeNameLoc = cTypeName != nil ? self.generateSourceLoc(ctypeString) : nil
} else {
cTypeName = nil
cTypeNameLoc = nil
self.generateWithLabeledExprListArguments(attribute: node) { args in
let nameAndLoc: (name: _, loc: _)? = self.generateConsumingPlainIdentifierAttrOption(args: &args) {
(ctx.allocateCopy(string: $0.rawText.bridged), self.generateSourceLoc($0))
}
guard let nameAndLoc else {
return nil
}

let cTypeNameLoc: BridgedSourceLoc?
let cTypeName: BridgedStringRef?
if !args.isEmpty {
cTypeNameLoc = self.generateSourceLoc(args.first?.expression)
cTypeName = self.generateConsumingSimpleStringLiteralAttrOption(args: &args, label: "cType")
guard cTypeName != nil else {
return nil
}
} else {
cTypeNameLoc = nil
cTypeName = nil
}

// `@convention(witness_method: <protocol-name>)` is for SIL only.
let witnessMethodProtocol: BridgedDeclNameRef = BridgedDeclNameRef()

return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
nameLoc: self.generateSourceLoc(node.attributeName),
parensRange: self.generateAttrParensRange(attribute: node),
name: nameAndLoc.name,
nameLoc: nameAndLoc.loc,
witnessMethodProtocol: witnessMethodProtocol,
clangType: cTypeName ?? BridgedStringRef(),
clangTypeLoc: cTypeNameLoc ?? BridgedSourceLoc()
)
}

let witnessMethodProtocol: BridgedDeclNameRef = BridgedDeclNameRef()

return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
nameLoc: self.generateSourceLoc(node.attributeName),
parensRange: self.generateAttrParensRange(attribute: node),
name: ctx.allocateCopy(string: args.conventionLabel.rawText.bridged),
nameLoc: self.generateSourceLoc(args.conventionLabel),
witnessMethodProtocol: witnessMethodProtocol,
clangType: cTypeName ?? BridgedStringRef(),
clangTypeLoc: cTypeNameLoc ?? BridgedSourceLoc()
)
}

func generateDifferentiableTypeAttr(attribute node: AttributeSyntax) -> BridgedDifferentiableTypeAttr? {
Expand Down Expand Up @@ -284,35 +295,43 @@ extension ASTGenVisitor {
)
}

/// E.g.
/// ```
/// @_opaqueReturnTypeOf("$sMangledName", 4)
/// ```
func generateOpaqueReturnTypeOfTypeAttr(attribute node: AttributeSyntax) -> BridgedOpaqueReturnTypeOfTypeAttr? {
// FIXME: This doesn't need custom attribute arguments syntax.
guard let args = node.arguments?.as(OpaqueReturnTypeOfAttributeArgumentsSyntax.self) else {
// TODO: Diagnose
fatalError("expected arguments for @_opaqueReturnTypeOfType type attribute")
}
self.generateWithLabeledExprListArguments(attribute: node) { args in
let mangledLoc = self.generateSourceLoc(args.first?.expression)
let mangledName = self.generateConsumingSimpleStringLiteralAttrOption(args: &args)
guard let mangledName else {
return nil
}

let mangledLoc = self.generateSourceLoc(args.mangledName)
guard let mangled = self.generateStringLiteralTextIfNotInterpolated(expr: args.mangledName) else {
// TODO: Diagnose
fatalError("expected string literal for @_opaqueReturnTypeOfType type attribute")
}

let indexLoc = self.generateSourceLoc(args.ordinal)
let index = Int(args.ordinal.text, radix: 10)
guard let index else {
// TODO: Diagnose
fatalError("expected integer literal for @_opaqueReturnTypeOfType type attribute")
let indexLoc = self.generateSourceLoc(args.first?.expression)
let index: Int? = self.generateConsumingAttrOption(args: &args, label: nil) { expr in
guard let intExpr = expr.as(IntegerLiteralExprSyntax.self) else {
// TODO: Diagnostics.
fatalError("expected integer literal")
// return nil
}
return intExpr.representedLiteralValue
}
guard let index else {
return nil
}

return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
nameLoc: self.generateSourceLoc(node.attributeName),
parensRange: self.generateAttrParensRange(attribute: node),
mangled: mangledName,
mangledLoc: mangledLoc,
index: index,
indexLoc: indexLoc
)
}

return .createParsed(
self.ctx,
atLoc: self.generateSourceLoc(node.atSign),
nameLoc: self.generateSourceLoc(node.attributeName),
parensRange: self.generateAttrParensRange(attribute: node),
mangled: mangled,
mangledLoc: mangledLoc,
index: index, indexLoc: indexLoc
)
}

func generateAttrParensRange(attribute node: AttributeSyntax) -> BridgedSourceRange {
Expand Down