//===--- DeclSyntax.h - Declaration Syntax Interface ------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // This file defines the interface for declaration-specific syntax nodes, // such as for structures, enumerations, type aliases, and constants. // //===----------------------------------------------------------------------===// #ifndef SWIFT_SYNTAX_DECLSYNTAX_H #define SWIFT_SYNTAX_DECLSYNTAX_H #include "swift/Syntax/References.h" #include "swift/Syntax/RawSyntax.h" #include "swift/Syntax/Syntax.h" #include "swift/Syntax/SyntaxCollection.h" #include "swift/Syntax/SyntaxData.h" #include "swift/Syntax/TokenSyntax.h" #include "swift/Syntax/TypeSyntax.h" #include "swift/Syntax/UnknownSyntax.h" #include "llvm/ADT/BitVector.h" namespace swift { namespace syntax { class ExprSyntax; class ExprSyntaxData; class CodeBlockStmtSyntax; class CodeBlockStmtSyntaxData; class TypeAttributesSyntax; class TypeAttributesSyntaxData; class DeclModifierListSyntax; class GenericWhereClauseSyntax; class GenericWhereClauseSyntaxData; class GenericParameterListSyntax; class GenericParameterListSyntaxData; #pragma mark declaration-modifier Data class DeclModifierSyntaxData final : public SyntaxData { friend struct SyntaxFactory; friend class SyntaxData; friend class Syntax; friend class DeclModifierSyntax; DeclModifierSyntaxData(const RC Raw, const SyntaxData *Parent = nullptr, const CursorIndex IndexInParent = 0); static RC make(const RC Raw, const SyntaxData *Parent = nullptr, const CursorIndex IndexInParent = 0); static RC makeBlank(); public: static bool classof(const SyntaxData *SD) { return SD->getKind() == SyntaxKind::DeclModifier; } }; #pragma mark declaration-modifier API /// declaration-modifier -> access-level-modifier /// | mutation-modifier /// | 'class' /// | 'convenience' /// | 'dynamic' /// | 'final' /// | 'infix' /// | 'lazy' /// | 'optional' /// | 'override' /// | 'postfix' /// | 'prefix' /// | 'required' /// | 'static' /// | 'unowned' /// | 'unowned(safe)' /// | 'unowned(unsafe)' /// | 'weak' /// access-level-modifier -> 'private' | 'private' '(' 'set' ')' /// | 'fileprivate' | 'fileprivate' '(' 'set' ')' /// | 'internal' | 'internal' '(' 'set' ')' /// | 'public' | 'public' '(' 'set' ')' /// | 'open' | 'open' '(' 'set' ')' /// mutation-modifier -> 'mutating' | 'nonmutating' class DeclModifierSyntax final : public Syntax { friend struct SyntaxFactory; friend class Syntax; friend class SyntaxData; friend class DeclModifierSyntaxData; enum class Cursor : CursorIndex { Name, LeftParen, Argument, RightParen }; DeclModifierSyntax(const RC Root, const DataType *Data) : Syntax(Root, Data) {} public: using DataType = DeclModifierSyntaxData; /// Return the name of the modifier. RC getName() const; /// Return a DeclModifierSyntax with the given name. DeclModifierSyntax withName(RC NewName) const; /// Return the left parenthesis '(' token as a part of the argument clause, /// if there is one. RC getLeftParenToken() const; /// Return a DeclModifierSyntax with the given left parenthesis '(' token. DeclModifierSyntax withLeftParenToken(RC NewLeftParen) const; /// Get the argument to the declaration modifier. /// /// This is either: /// - 'set' for the access modifiers such as 'private' or 'public', or /// - 'safe' / 'unsafe' for the 'unowned' modifier. RC getArgument() const; /// Return a DeclModifierSyntax with the given argument. DeclModifierSyntax withArgument(RC NewArgument) const; /// Return the right parenthesis ')' token as a part of the argument clause, /// if there is one. RC getRightParenToken() const; /// Return a DeclModifierSyntax with the given right parenthesis ')' token. DeclModifierSyntax withRightParenToken(RC NewRightParen) const; static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::DeclModifier; } }; #pragma mark declaration-modifiers Data using DeclModifierListSyntaxData = SyntaxCollectionData; #pragma mark declaration-modifiers API class DeclModifierListSyntax final : public SyntaxCollection { friend struct SyntaxFactory; friend class Syntax; friend class SyntaxData; friend class FunctionDeclSyntax; using DataType = DeclModifierListSyntaxData; DeclModifierListSyntax(const RC Root, const DataType *Data) : SyntaxCollection(Root, Data) {} public: static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::DeclModifierList; } }; #pragma mark declaration Data class DeclSyntaxData : public SyntaxData { protected: DeclSyntaxData(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); public: static bool classof(const SyntaxData *S) { return S->isDecl(); } }; #pragma mark declaration API class DeclSyntax : public Syntax { friend class Syntax; using DataType = DeclSyntaxData; protected: DeclSyntax(const RC Root, const DeclSyntaxData *Data); public: static bool classof(const SyntaxData *S) { return S->isDecl(); } }; #pragma mark - unknown-declaration Data class UnknownDeclSyntaxData : public UnknownSyntaxData { UnknownDeclSyntaxData(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); public: static RC make(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static bool classof(const SyntaxData *S) { return S->getKind() == SyntaxKind::UnknownDecl; } }; #pragma mark - unknown-declaration API class UnknownDeclSyntax : public UnknownSyntax { friend class SyntaxData; friend class UnknownStmtSyntaxData; friend class LegacyASTTransformer; using DataType = UnknownDeclSyntaxData; UnknownDeclSyntax(const RC Root, const UnknownDeclSyntaxData *Data); public: static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::UnknownDecl; } }; #pragma mark declaration-members Data class DeclMembersSyntaxData final : public SyntaxData { friend class SyntaxData; friend class DeclMembersSyntaxBuilder; friend struct SyntaxFactory; DeclMembersSyntaxData(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); public: static RC make(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC makeBlank(); static bool classof(const SyntaxData *S) { return S->getKind() == SyntaxKind::DeclMembers; } }; #pragma mark - #pragma mark declaration-members API class DeclMembersSyntax final : public Syntax { using DataType = DeclMembersSyntaxData; friend struct SyntaxFactory; friend class SyntaxData; friend class Syntax; friend class DeclMembersSyntaxBuilder; friend class StructDeclSyntax; DeclMembersSyntax(RC Root, const DeclMembersSyntaxData *Data); public: static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::DeclMembers; } }; #pragma mark - #pragma mark declaration-members Builder (TODO) class DeclMembersSyntaxBuilder final { RawSyntax::LayoutList MembersLayout; public: DeclMembersSyntaxBuilder &addMember(DeclSyntax Member); DeclMembersSyntax build() const; }; #pragma mark - #pragma mark struct-declaration Data class StructDeclSyntaxData final : public DeclSyntaxData { friend class SyntaxData; friend class StructDeclSyntax; friend class StructDeclSyntaxBuilder; friend struct SyntaxFactory; RC CachedWhereClause; RC CachedGenericParams; RC CachedMembers; StructDeclSyntaxData(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC make(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC makeBlank(); public: static bool classof(const SyntaxData *S) { return S->getKind() == SyntaxKind::StructDecl; } }; #pragma mark - struct-declaration API /// struct-declaration -> attributes? access-level-modifier? /// 'struct' struct-name /// generic-parameter-clause? type-inheritance-clause? /// generic-where-clause? /// '{' struct-members '}' /// struct-name -> identifier /// struct-members -> struct-member struct-members? /// struct-member -> declaration | compiler-control-statement class StructDeclSyntax final : public DeclSyntax { using DataType = StructDeclSyntaxData; friend struct SyntaxFactory; friend class Syntax; friend class SyntaxData; friend class StructDeclSyntaxData; friend class StructDeclSyntaxBuilder; enum class Cursor : CursorIndex { StructKeyword, Identifier, GenericParameterClause, GenericWhereClause, LeftBrace, Members, RightBrace, First = StructKeyword, Last = RightBrace, }; StructDeclSyntax(const RC Root, const StructDeclSyntaxData *Data); const StructDeclSyntaxData *getData() const { return cast(Data); } public: /// Return the 'struct' keyword attached to the declaration. RC getStructKeyword() const; /// Return a StructDeclSyntax with the given 'struct' keyword. StructDeclSyntax withStructKeyword(RC NewStructKeyword) const; /// Return the identifier of the struct. RC getIdentifier() const; /// Return a StructDeclSyntax with the given identifier. StructDeclSyntax withIdentifier(RC NewIdentifier) const; /// Return the generic parameter clause of the struct declaration. GenericParameterClauseSyntax getGenericParameterClause() const; /// Return a StructDeclSyntax with the given generic parameter clause. StructDeclSyntax withGenericParameterClause(GenericParameterClauseSyntax NewGenericParams) const; /// Return the where clause of the struct declaration. GenericWhereClauseSyntax getGenericWhereClause() const; /// Return a StructDeclSyntax with the given generic where clause. StructDeclSyntax withWhereClause(GenericWhereClauseSyntax NewWhereClause) const; /// Return the left brace '{' token of the struct declaration. RC getLeftBraceToken() const; /// Return a StructDeclSyntax with the given left brace '{' token. StructDeclSyntax withLeftBrace(RC NewLeftBrace) const; /// Return the members' syntax of the struct. DeclMembersSyntax getMembers() const; /// Return a StructDeclSyntax with the given new members. StructDeclSyntax withMembers(DeclMembersSyntax NewMembers) const; /// Return the right brace '}' token of the struct declaration. RC getRightBraceToken() const; /// Return a StructDeclSyntax with the given right brace '}' token. StructDeclSyntax withRightBrace(RC NewRightBrace) const; static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::StructDecl; } }; #pragma mark - struct-declaration Builder class StructDeclSyntaxBuilder final { RawSyntax::LayoutList StructLayout; public: StructDeclSyntaxBuilder(); StructDeclSyntaxBuilder &useStructKeyword(RC StructKeyword); StructDeclSyntaxBuilder &useIdentifier(RC Identifier); StructDeclSyntaxBuilder &useLeftBrace(RC LeftBrace); StructDeclSyntaxBuilder & useGenericParameterClause(GenericParameterClauseSyntax GenericParams); StructDeclSyntaxBuilder & useGenericWhereClause(GenericWhereClauseSyntax GenericWhereClause); StructDeclSyntaxBuilder &useMembers(DeclMembersSyntax Members); StructDeclSyntaxBuilder &useRightBrace(RC RightBrace); StructDeclSyntax build() const; }; #pragma mark - #pragma mark - type-alias Data class TypeAliasDeclSyntaxData final : public DeclSyntaxData { friend class SyntaxData; friend struct SyntaxFactory; friend class TypeAliasDeclSyntaxBuilder; TypeAliasDeclSyntaxData(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC make(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC makeBlank(); public: static bool classof(const SyntaxData *S) { return S->getKind() == SyntaxKind::TypeAliasDecl; } }; #pragma mark - #pragma mark - type-alias API class TypeAliasDeclSyntax final : public DeclSyntax { friend struct SyntaxFactory; friend class SyntaxData; friend class TypeAliasDeclSyntaxData; friend class TypeAliasDeclSyntaxBuilder; using DataType = TypeAliasDeclSyntaxData; enum Cursor : CursorIndex { TypeAliasKeyword, Identifier, GenericParameterClause, EqualToken, Type }; TypeAliasDeclSyntax(RC Root, const TypeAliasDeclSyntaxData *Data); public: /// Return the 'typealias' keyword for the declaration. RC getTypealiasKeyword() const { return cast(getRaw()->getChild(Cursor::TypeAliasKeyword)); } /// Return a TypeAliasDeclSyntax with the given 'typealias' keyword. TypeAliasDeclSyntax withTypeAliasKeyword(RC NewTypeAliasKeyword) const; /// Return the identifier for the declaration. RC getIdentifier() const; /// Return a TypeAliasDeclSyntax with the given identifier. TypeAliasDeclSyntax withIdentifier(RC NewIdentifier) const; /// Return the generic parameter clause of the declaration. GenericParameterClauseSyntax getGenericParameterClause() const; /// Return a TypeAliasDeclSyntax with the given generic parameter clause. TypeAliasDeclSyntax withGenericParameterClause( GenericParameterClauseSyntax NewGenericParams) const; /// Return the equal '=' token from the declaration. RC getEqualToken() const; /// Return a TypeAliasDeclSyntax with the given equal '=' token. TypeAliasDeclSyntax withEqualToken(RC NewEqualToken) const; /// Return the type syntax to which the type alias is assigned. TypeSyntax getTypeSyntax() const; /// Return a TypeAliasDeclSyntax with the given type assignment. TypeAliasDeclSyntax withTypeSyntax(TypeSyntax NewType) const; static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::TypeAliasDecl; } }; #pragma mark - type-alias Builder class TypeAliasDeclSyntaxBuilder final { RawSyntax::LayoutList TypeAliasLayout; public: TypeAliasDeclSyntaxBuilder(); TypeAliasDeclSyntaxBuilder & useTypeAliasKeyword(RC TypeAliasKeyword); TypeAliasDeclSyntaxBuilder &useIdentifier(RC Identifier); TypeAliasDeclSyntaxBuilder & useGenericParameterClause(GenericParameterClauseSyntax GenericParams); TypeAliasDeclSyntaxBuilder &useEqualToken(RC EqualToken); TypeAliasDeclSyntaxBuilder &useType(TypeSyntax ReferentType); TypeAliasDeclSyntax build() const; }; #pragma mark - function-parameter Data class FunctionParameterSyntaxData final : public SyntaxData { friend struct SyntaxFactory; friend class Syntax; friend class SyntaxData; friend class FunctionParameterSyntax; RC CachedTypeSyntax; RC CachedDefaultValue; FunctionParameterSyntaxData(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC make(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC makeBlank(); public: static bool classof(const SyntaxData *SD) { return SD->getKind() == SyntaxKind::FunctionParameter; } }; #pragma mark - function-parameter API /// parameter -> /// external-parameter-name? local-parameter-name ':' /// type '...'? '='? expression? ','? class FunctionParameterSyntax final : public Syntax { friend struct SyntaxFactory; friend class Syntax; friend class SyntaxData; friend class FunctionParameterSyntaxData; enum class Cursor : CursorIndex { ExternalName, LocalName, Colon, Type, Ellipsis, DefaultEqual, DefaultExpression, TrailingComma, }; public: using DataType = FunctionParameterSyntaxData; FunctionParameterSyntax(const RC Root, const DataType *Data) : Syntax(Root, Data) {} /// Get the external name of the parameter, if there is one. RC getExternalName() const; /// Return a FunctionParameterSyntax with the given external name. FunctionParameterSyntax withExternalName(RC NewExternalName) const; /// Return the local name of the parameter. RC getLocalName() const; /// Return a FunctionParameterSyntax with the given local name. FunctionParameterSyntax withLocalName(RC NewLocalName) const; /// Return the colon ':' token between the local name and type of the /// parameter. RC getColonToken() const; /// Return a FunctionParameterSyntax with the given colon token between /// the local name and type. FunctionParameterSyntax withColonToken(RC NewColonToken) const; /// Return the syntax for the type of this parameter. llvm::Optional getTypeSyntax() const; /// Return a FunctionParameterSyntax with the given parameter type syntax. FunctionParameterSyntax withTypeSyntax(llvm::Optional NewType) const; /// Return the equal '=' token in between the parameter type and the default /// value, if there is one. RC getEqualToken() const; /// Return a FunctionParameterSyntax with the given equal '=' token in /// between the parameter type and the default value. FunctionParameterSyntax withEqualToken(RC NewEqualToken) const; /// Return the expression for the default value of the parameter, if there /// is one. llvm::Optional getDefaultValue() const; /// Return a FunctionParameterSyntax with the given default value. To remove /// the default value, pass llvm::None. FunctionParameterSyntax withDefaultValue(llvm::Optional NewDefaultValue) const; /// Return the trailing comma on the parameter, if there is one. RC getTrailingComma() const; /// Return a FunctionParameterSyntax with the given trailing comma. FunctionParameterSyntax withTrailingComma(RC NewTrailingComma) const; static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::FunctionParameter; } }; #pragma mark - function-parameter-list API /// parameter-list -> parameteter | parameter ',' parameter-list class FunctionParameterListSyntax final : public SyntaxCollection { friend struct SyntaxFactory; friend class Syntax; friend class SyntaxData; friend class FunctionSignatureSyntax; using DataType = FunctionParameterListSyntaxData; FunctionParameterListSyntax(const RC Root, const DataType *Data) : SyntaxCollection(Root, Data) {} public: static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::FunctionParameterList; } }; #pragma mark - function-signature Data class FunctionSignatureSyntaxData final : public SyntaxData { friend struct SyntaxFactory; friend class SyntaxData; friend class FunctionSignatureSyntax; RC CachedParameterList; RC CachedReturnTypeAttributes; RC CachedReturnTypeSyntax; FunctionSignatureSyntaxData(const RC Raw, const SyntaxData *Parent = nullptr, const CursorIndex IndexInParent = 0); static RC make(RC Raw, const SyntaxData *Parent = nullptr, CursorIndex IndexInParent = 0); static RC makeBlank(); public: static bool classof(const SyntaxData *SD) { return SD->getKind() == SyntaxKind::FunctionSignature; } }; #pragma mark - function-signature API /// function-signature -> /// '(' parameter-list? ')' (throws | rethrows)? '->' attributes? type class FunctionSignatureSyntax final : public Syntax { friend struct SyntaxBuilder; friend class Syntax; friend class SyntaxData; friend class FunctionSignatureSyntaxData; enum class Cursor : CursorIndex { LeftParen, ParameterList, RightParen, ThrowsOrRethrows, Arrow, ReturnTypeAttributes, ReturnType, }; public: using DataType = FunctionSignatureSyntaxData; FunctionSignatureSyntax(const RC Root, const DataType *Data) : Syntax(Root, Data) {} /// Return the left parenthesis '(' token enclosing the parameter list. RC getLeftParenToken() const; /// Return a FunctionSignatureSyntax with the given left parenthesis '(' token /// enclosing the parameter list. FunctionSignatureSyntax withLeftParenToken(RC NewLeftParen) const; /// Return the parameter list for this signature. FunctionParameterListSyntax getParameterList() const; /// Return the parameter list for this signature. FunctionSignatureSyntax withParameterList(FunctionParameterListSyntax NewParameterList) const; /// Return the right parenthesis ')' token enclosing the parameter list. RC getRightParenToken() const; /// Return a FunctionSignatureSyntax with the given right parenthesis ')' token /// enclosing the parameter list. FunctionSignatureSyntax withRightParenToken(RC NewRightParen) const; /// Return the 'throws' token in this signature if it exists. RC getThrowsToken() const; /// Return a FunctionSignatureSyntax with the given 'throws' token. FunctionSignatureSyntax withThrowsToken(RC NewThrowsToken) const; /// Return the 'rethrows' token in this signature if it exists; RC getRethrowsToken() const; /// Return a FunctionSignatureSyntax with the given 'rethrows' token. FunctionSignatureSyntax withRethrowsToken(RC NewRethrowsToken) const; /// Return the arrow '->' token for the signature. RC getArrowToken() const; /// Return a FunctionSignatureSyntax with the given arrow token FunctionSignatureSyntax withArrowToken(RC NewArrowToken) const; /// Return the return type attributes for the signature. TypeAttributesSyntax getReturnTypeAttributes() const; /// Return a FunctionSignatureSyntax with the given return type attributes. FunctionSignatureSyntax withReturnTypeAttributes(TypeAttributesSyntax NewReturnTypeAttributes) const; /// Return the syntax for the return type of the signature. TypeSyntax getReturnTypeSyntax() const; /// Return a FunctionSignatureSyntax with the given return type. FunctionSignatureSyntax withReturnTypeSyntax(TypeSyntax NewReturnType) const; static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::FunctionSignature; } }; #pragma mark - function-declaration Data class FunctionDeclSyntaxData final : public SyntaxData { friend struct SyntaxFactory; friend class SyntaxData; friend class FunctionDeclSyntax; RC CachedAttributes; RC CachedModifiers; RC CachedGenericParams; RC CachedSignature; RC CachedGenericWhereClause; RC CachedBody; FunctionDeclSyntaxData(const RC Raw, const SyntaxData *Parent = nullptr, const CursorIndex IndexInParent = 0); static RC make(const RC Raw, const SyntaxData *Parent = nullptr, const CursorIndex IndexInParent = 0); static RC makeBlank(); public: static bool classof(const SyntaxData *SD) { return SD->getKind() == SyntaxKind::FunctionDecl; } }; #pragma mark - function-declaration API class FunctionDeclSyntax final : public Syntax { friend struct SyntaxFactory; friend class Syntax; friend class SyntaxData; friend class FunctionDeclSyntaxData; enum class Cursor : CursorIndex { Attributes, Modifiers, FuncKeyword, Identifier, GenericParameterClause, Signature, GenericWhereClause, Body }; using DataType = FunctionDeclSyntaxData; FunctionDeclSyntax(const RC Root, const DataType *Data) : Syntax(Root, Data) {} public: /// Get the attributes of this function declaration. TypeAttributesSyntax getAttributes() const; /// Return a FunctionDeclSyntax with the given attributes. FunctionDeclSyntax withAttributes(TypeAttributesSyntax NewAttributes) const; /// Get the modifiers of this function declaration. DeclModifierListSyntax getModifiers() const; /// Return a FunctionDeclSyntax with the given modifiers. FunctionDeclSyntax withModifiers(DeclModifierListSyntax NewModifiers) const; /// Return the 'func' keyword of tis function declaration. RC getFuncKeyword() const; /// Return a FunctionDeclSyntax with the given 'func' keyword. FunctionDeclSyntax withFuncKeyword(RC NewFuncKeyword) const; /// Return the identifier of the function declaration. RC getIdentifier() const; /// Return a FunctionDeclSyntax with the given identifier. FunctionDeclSyntax withIdentifier(RC NewIdentifier) const; /// Return the generic parameter clause of the function declaration, if /// there is one. Otherwise, return llvm::None. llvm::Optional getGenericParameterClause() const; /// Return a FunctionDeclSyntax with the given generic parameter clause. /// To remove the generic parameters, pass in llvm::None. FunctionDeclSyntax withGenericParameterClause( llvm::Optional NewGenericParams) const; /// Return the signature of the function declaration. FunctionSignatureSyntax getSignature() const; /// Return a FunctionDeclSyntax with the given function signature. FunctionDeclSyntax withSignature(FunctionSignatureSyntax NewSignature) const; /// Return the body of the function declaration, if there is one. /// /// As an example, function declarations in protocols have no body. llvm::Optional getBody() const; /// Return a FunctionDeclSyntax with the given body. To remove the body, /// pass in llvm::None. FunctionDeclSyntax withBody(llvm::Optional NewBody) const; static bool classof(const Syntax *S) { return S->getKind() == SyntaxKind::FunctionDecl; } }; } // end namespace syntax } // end namespace swift #endif // SWIFT_SYNTAX_DECLSYNTAX_H