diff --git a/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift b/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift index 41ef4466231cb..7d80b663340f0 100644 --- a/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift +++ b/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift @@ -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. - 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.: @@ -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 { @@ -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 ) } @@ -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.: @@ -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.: @@ -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, @@ -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 } } @@ -2341,7 +2330,7 @@ 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 } @@ -2349,11 +2338,6 @@ extension ASTGenVisitor { 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, diff --git a/lib/ASTGen/Sources/ASTGen/TypeAttrs.swift b/lib/ASTGen/Sources/ASTGen/TypeAttrs.swift index 8a4e355f11e35..0aea4fe145ca4 100644 --- a/lib/ASTGen/Sources/ASTGen/TypeAttrs.swift +++ b/lib/ASTGen/Sources/ASTGen/TypeAttrs.swift @@ -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: )` 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? { @@ -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 {